Просмотр исходного кода

HUE-8687 [frontend] Move additional third party dependencies to the webpack bundle

Johan Ahlen 7 лет назад
Родитель
Сommit
5ed04bd
66 измененных файлов с 1364 добавлено и 13599 удалено
  1. 0 3
      apps/beeswax/src/beeswax/templates/create_database.mako
  2. 0 3
      apps/beeswax/src/beeswax/templates/create_table_manually.mako
  3. 0 4
      apps/beeswax/src/beeswax/templates/execute.mako
  4. 0 3
      apps/beeswax/src/beeswax/templates/import_wizard_choose_delimiter.mako
  5. 0 3
      apps/beeswax/src/beeswax/templates/import_wizard_choose_file.mako
  6. 0 3
      apps/beeswax/src/beeswax/templates/import_wizard_define_columns.mako
  7. 0 1
      apps/filebrowser/src/filebrowser/templates/listdir_components.mako
  8. 0 2
      apps/jobbrowser/src/jobbrowser/templates/job_browser.mako
  9. 0 3
      apps/metastore/src/metastore/templates/metastore.mako
  10. 0 1
      apps/oozie/src/oozie/templates/editor/edit_workflow.mako
  11. 0 1
      apps/oozie/src/oozie/templates/editor2/common_workflow.mako
  12. 0 2
      apps/rdbms/src/rdbms/templates/execute.mako
  13. 0 1
      apps/security/src/security/templates/hive.mako
  14. 0 1
      apps/security/src/security/templates/sentry.mako
  15. 0 4
      apps/useradmin/src/useradmin/templates/list_configurations.mako
  16. 8 9
      desktop/core/src/desktop/js/hue.js
  17. 5 1
      desktop/core/src/desktop/js/jquery/jquery.all.js
  18. 774 0
      desktop/core/src/desktop/js/jquery/plugins/jquery.huedatatable.js
  19. 5 0
      desktop/core/src/desktop/js/jquery/plugins/jquery.selectize.js
  20. 7 8
      desktop/core/src/desktop/js/ko/bindings/ko.impalaDagre.js
  21. 12 0
      desktop/core/src/desktop/js/ko/ko.all.js
  22. 116 0
      desktop/core/src/desktop/js/utils/customIntervals.js
  23. 303 0
      desktop/core/src/desktop/js/utils/json.bigDataParse.js
  24. 0 5
      desktop/core/src/desktop/static/desktop/ext/js/bootstrap.min.js
  25. 0 1311
      desktop/core/src/desktop/static/desktop/ext/js/fileuploader.js
  26. 0 5
      desktop/core/src/desktop/static/desktop/ext/js/jquery/plugins/jquery-ui-1.10.4.custom.min.js
  27. 0 47
      desktop/core/src/desktop/static/desktop/ext/js/jquery/plugins/jquery.cookie.js
  28. 0 151
      desktop/core/src/desktop/static/desktop/ext/js/jquery/plugins/jquery.dataTables.1.8.2.min.js
  29. 0 1277
      desktop/core/src/desktop/static/desktop/ext/js/jquery/plugins/jquery.form.js
  30. 0 25
      desktop/core/src/desktop/static/desktop/ext/js/jquery/plugins/jquery.total-storage.min.js
  31. 0 5
      desktop/core/src/desktop/static/desktop/ext/js/jquery/plugins/jquery.ui.position.min.js
  32. 0 1
      desktop/core/src/desktop/static/desktop/ext/js/knockout-sortable.min.js
  33. 0 9
      desktop/core/src/desktop/static/desktop/ext/js/knockout.validation.min.js
  34. 0 1123
      desktop/core/src/desktop/static/desktop/ext/js/page.js
  35. 0 74
      desktop/core/src/desktop/static/desktop/ext/js/selectize-plugin-clear.js
  36. 0 1
      desktop/core/src/desktop/static/desktop/ext/js/selectize.min.js
  37. 0 0
      desktop/core/src/desktop/static/desktop/js/bundles/hue-bundle-5a1bf7f66484544c5faf.js
  38. 0 0
      desktop/core/src/desktop/static/desktop/js/bundles/hue-bundle-5a1bf7f66484544c5faf.js.map
  39. 0 0
      desktop/core/src/desktop/static/desktop/js/bundles/hue-bundle-c56027ed5fcc7f4abc0b.js.map
  40. 1 1
      desktop/core/src/desktop/static/desktop/js/bundles/sqlSyntaxWebWorker-bundle-5a1bf7f66484544c5faf.js
  41. 0 0
      desktop/core/src/desktop/static/desktop/js/bundles/sqlSyntaxWebWorker-bundle-5a1bf7f66484544c5faf.js.map
  42. 0 321
      desktop/core/src/desktop/static/desktop/js/hue.json.js
  43. 0 765
      desktop/core/src/desktop/static/desktop/js/hue.utils.js
  44. 0 106
      desktop/core/src/desktop/static/desktop/js/hue4.utils.js
  45. 0 7699
      desktop/core/src/desktop/static/desktop/js/ko.hue-bindings.js
  46. 0 219
      desktop/core/src/desktop/static/desktop/js/ko.selectize.js
  47. 0 11
      desktop/core/src/desktop/static/desktop/js/ko.switch-case.js
  48. 0 299
      desktop/core/src/desktop/static/desktop/js/sqlUtils.js
  49. 0 3
      desktop/core/src/desktop/templates/assist_m.mako
  50. 0 2
      desktop/core/src/desktop/templates/common_dashboard.mako
  51. 4 28
      desktop/core/src/desktop/templates/common_header.mako
  52. 5 7
      desktop/core/src/desktop/templates/common_header_m.mako
  53. 0 3
      desktop/core/src/desktop/templates/common_home.mako
  54. 0 3
      desktop/core/src/desktop/templates/common_jasmine.mako
  55. 0 8
      desktop/core/src/desktop/templates/hue.mako
  56. 0 5
      desktop/libs/dashboard/src/dashboard/templates/common_search.mako
  57. 0 2
      desktop/libs/indexer/src/indexer/templates/collections.mako
  58. 0 7
      desktop/libs/indexer/src/indexer/templates/importer.mako
  59. 0 4
      desktop/libs/indexer/src/indexer/templates/indexer.mako
  60. 0 2
      desktop/libs/indexer/src/indexer/templates/indexes.mako
  61. 0 2
      desktop/libs/indexer/src/indexer/templates/topics.mako
  62. 0 9
      desktop/libs/notebook/src/notebook/templates/editor_components.mako
  63. 0 5
      desktop/libs/notebook/src/notebook/templates/editor_m.mako
  64. 122 0
      package-lock.json
  65. 1 0
      package.json
  66. 1 1
      webpack-stats.json

+ 0 - 3
apps/beeswax/src/beeswax/templates/create_database.mako

@@ -29,11 +29,8 @@ ${ commonheader(_("Create database"), 'metastore', user, request) | n,unicode }
 
 ${layout.metastore_menubar()}
 
-<script src="${ static('desktop/ext/js/jquery/plugins/jquery-ui-1.10.4.custom.min.js') }"></script>
 <script src="${ static('desktop/js/hue.routie.js') }" type="text/javascript" charset="utf-8"></script>
-<script src="${ static('desktop/ext/js/selectize.min.js') }"></script>
 <script src="${ static('metastore/js/metastore.ko.js') }"></script>
-<script src="${ static('desktop/ext/js/knockout-sortable.min.js') }"></script>
 
 ${ assist.assistJSModels() }
 

+ 0 - 3
apps/beeswax/src/beeswax/templates/create_table_manually.mako

@@ -28,10 +28,7 @@ ${ commonheader(_("Create table manually"), 'metastore', user, request) | n,unic
 <span class="notebook">
 ${ layout.metastore_menubar() }
 
-<script src="${ static('desktop/ext/js/jquery/plugins/jquery-ui-1.10.4.custom.min.js') }"></script>
-<script src="${ static('desktop/ext/js/selectize.min.js') }"></script>
 <script src="${ static('metastore/js/metastore.ko.js') }"></script>
-<script src="${ static('desktop/ext/js/knockout-sortable.min.js') }"></script>
 
 ${ assist.assistJSModels() }
 

+ 0 - 4
apps/beeswax/src/beeswax/templates/execute.mako

@@ -793,12 +793,9 @@ ${ commonshare() | n,unicode }
   var SqlAutocompleter2 = {};
 </script>
 
-<script src="${ static('desktop/js/hue.json.js') }" type="text/javascript" charset="utf-8"></script>
-<script src="${ static('desktop/ext/js/jquery/plugins/jquery-ui-1.10.4.custom.min.js') }" type="text/javascript" charset="utf-8"></script>
 <script src="${ static('desktop/js/hue.routie.js') }" type="text/javascript" charset="utf-8"></script>
 <script src="${ static('desktop/js/sqlAutocompleter2.js') }" type="text/javascript" charset="utf-8"></script>
 <script src="${ static('desktop/js/hdfsAutocompleter.js') }" type="text/javascript" charset="utf-8"></script>
-<script src="${ static('desktop/js/sqlFunctions.js') }" type="text/javascript" charset="utf-8"></script>
 
 ${ assist.assistJSModels() }
 
@@ -809,7 +806,6 @@ ${ assist.assistJSModels() }
 <!-- For query builder -->
 <link rel="stylesheet" href="${ static('desktop/ext/css/jquery.contextMenu.min.css') }">
 <script src="${ static('desktop/ext/js/jquery/plugins/jquery.contextMenu.min.js') }"></script>
-<script src="${ static('desktop/ext/js/jquery/plugins/jquery.ui.position.min.js') }"></script>
 <script src="${ static('desktop/js/queryBuilder.js') }"></script>
 <script>
   // query-builder-menu is the class to use

+ 0 - 3
apps/beeswax/src/beeswax/templates/import_wizard_choose_delimiter.mako

@@ -28,10 +28,7 @@ ${ commonheader(_('Create table from file'), 'metastore', user, request) | n,uni
 <span class="notebook">
 ${ layout.metastore_menubar() }
 
-<script src="${ static('desktop/ext/js/jquery/plugins/jquery-ui-1.10.4.custom.min.js') }"></script>
-<script src="${ static('desktop/ext/js/selectize.min.js') }"></script>
 <script src="${ static('metastore/js/metastore.ko.js') }"></script>
-<script src="${ static('desktop/ext/js/knockout-sortable.min.js') }"></script>
 
 ${ assist.assistJSModels() }
 

+ 0 - 3
apps/beeswax/src/beeswax/templates/import_wizard_choose_file.mako

@@ -27,10 +27,7 @@ ${ commonheader(_('Create table from file'), 'metastore', user, request) | n,uni
 <span class="notebook">
 ${ layout.metastore_menubar() }
 
-<script src="${ static('desktop/ext/js/jquery/plugins/jquery-ui-1.10.4.custom.min.js') }"></script>
-<script src="${ static('desktop/ext/js/selectize.min.js') }"></script>
 <script src="${ static('metastore/js/metastore.ko.js') }"></script>
-<script src="${ static('desktop/ext/js/knockout-sortable.min.js') }"></script>
 
 ${ assist.assistJSModels() }
 

+ 0 - 3
apps/beeswax/src/beeswax/templates/import_wizard_define_columns.mako

@@ -28,10 +28,7 @@ ${ commonheader(_('Create table from file'), 'metastore', user, request) | n,uni
 <span class="notebook">
 ${ layout.metastore_menubar() }
 
-<script src="${ static('desktop/ext/js/jquery/plugins/jquery-ui-1.10.4.custom.min.js') }"></script>
-<script src="${ static('desktop/ext/js/selectize.min.js') }"></script>
 <script src="${ static('metastore/js/metastore.ko.js') }"></script>
-<script src="${ static('desktop/ext/js/knockout-sortable.min.js') }"></script>
 
 ${ assist.assistJSModels() }
 

+ 0 - 1
apps/filebrowser/src/filebrowser/templates/listdir_components.mako

@@ -669,7 +669,6 @@ from filebrowser.conf import ENABLE_EXTRACT_UPLOADED_ARCHIVE
     </tr>
   </script>
 
-  <script src="${ static('desktop/ext/js/jquery/plugins/jquery-ui-1.10.4.custom.min.js') }" type="text/javascript" charset="utf-8"></script>
   <script src="${ static('desktop/ext/js/datatables-paging-0.1.js') }" type="text/javascript" charset="utf-8"></script>
 
 

+ 0 - 2
apps/jobbrowser/src/jobbrowser/templates/job_browser.mako

@@ -52,8 +52,6 @@ ${ commonheader("Job Browser", "jobbrowser", user, request) | n,unicode }
 <link rel="stylesheet" href="${ static('jobbrowser/css/jobbrowser-embeddable.css') }">
 
 <script src="${ static('oozie/js/dashboard-utils.js') }" type="text/javascript" charset="utf-8"></script>
-<script src="${ static('desktop/ext/js/jquery/plugins/jquery-ui-1.10.4.custom.min.js') }"></script>
-<script src="${ static('desktop/ext/js/knockout-sortable.min.js') }"></script>
 <script src="${ static('desktop/ext/js/d3.v5.js') }"></script>
 
 % if ENABLE_QUERY_BROWSER.get():

+ 0 - 3
apps/metastore/src/metastore/templates/metastore.mako

@@ -41,10 +41,7 @@ else:
 % if not is_embeddable:
 ${ commonheader(_("Metastore"), app_name, user, request) | n,unicode }
 
-<script src="${ static('desktop/ext/js/jquery/plugins/jquery-ui-1.10.4.custom.min.js') }"></script>
 <script src="${ static('desktop/ext/js/jquery/plugins/jquery.mousewheel.min.js') }"></script>
-<script src="${ static('desktop/ext/js/selectize.min.js') }"></script>
-<script src="${ static('desktop/ext/js/knockout-sortable.min.js') }"></script>
 <script src="${ static('desktop/ext/js/bootstrap-editable.min.js') }"></script>
 
 ${ assist.assistJSModels() }

+ 0 - 1
apps/oozie/src/oozie/templates/editor/edit_workflow.mako

@@ -442,7 +442,6 @@ ${ layout.menubar(section='workflows') }
 <script src="${ static('desktop/ext/js/codemirror-xml.js') }"></script>
 <script src="${ static('desktop/ext/js/codemirror-closetag.js') }"></script>
 
-<script src="${ static('desktop/ext/js/jquery/plugins/jquery-ui-1.10.4.custom.min.js') }" type="text/javascript" charset="utf-8"></script>
 <script src="${ static('desktop/js/hue.routie.js') }" type="text/javascript" charset="utf-8"></script>
 <script src="${ static('desktop/ext/js/datatables-paging-0.1.js') }" type="text/javascript" charset="utf-8"></script>
 

+ 0 - 1
apps/oozie/src/oozie/templates/editor2/common_workflow.mako

@@ -30,7 +30,6 @@
 
 
 <%def name="render()">
-<script src="${ static('desktop/ext/js/selectize.min.js') }"></script>
 
 <script type="text/html" id="doc-search-autocomp-item">
   <a>

+ 0 - 2
apps/rdbms/src/rdbms/templates/execute.mako

@@ -357,8 +357,6 @@ ${ commonshare() | n,unicode }
 
 </style>
 
-<script src="${ static('desktop/js/hue.json.js') }"></script>
-<script src="${ static('desktop/ext/js/jquery/plugins/jquery-ui-1.10.4.custom.min.js') }" type="text/javascript" charset="utf-8"></script>
 <script src="${ static('rdbms/js/rdbms.vm.js') }"></script>
 <script src="${ static('desktop/js/share.vm.js') }"></script>
 <script src="${ static('desktop/ext/js/codemirror-3.11.js') }"></script>

+ 0 - 1
apps/security/src/security/templates/hive.mako

@@ -551,7 +551,6 @@ ${ tree.import_templates(itemClick='$root.assist.setPath', iconClick='$root.assi
 
 
 <script src="${ static('security/js/hive.ko.js') }" type="text/javascript" charset="utf-8"></script>
-<script src="${ static('desktop/js/jquery.filechooser.js') }" type="text/javascript" charset="utf-8"></script>
 
 <script type="text/javascript">
   (function () {

+ 0 - 1
apps/security/src/security/templates/sentry.mako

@@ -606,7 +606,6 @@ ${ tree.import_templates(itemClick='$root.assist.setPath', iconClick='$root.assi
 
 
 <script src="${ static('security/js/sentry.ko.js') }" type="text/javascript" charset="utf-8"></script>
-<script src="${ static('desktop/js/jquery.filechooser.js') }" type="text/javascript" charset="utf-8"></script>
 
 
 <script type="text/javascript">

+ 0 - 4
apps/useradmin/src/useradmin/templates/list_configurations.mako

@@ -29,11 +29,7 @@ ${commonheader(_('Configurations'), "useradmin", user, request) | n,unicode}
 %endif
 ${layout.menubar(section='configurations')}
 
-<script src="${ static('desktop/ext/js/jquery/plugins/jquery-ui-1.10.4.custom.min.js') }"></script>
-<script src="${ static('desktop/ext/js/selectize.min.js') }"></script>
 <script src="${ static('metastore/js/metastore.ko.js') }"></script>
-<script src="${ static('desktop/ext/js/knockout-sortable.min.js') }"></script>
-<script src="${ static('desktop/js/ko.selectize.js') }"></script>
 
 <script id="app-list" type="text/html">
   <div class="card card-small">

+ 8 - 9
desktop/core/src/desktop/js/hue.js

@@ -24,28 +24,25 @@ import page from 'page';
 import localforage from 'localforage';
 import sprintf from 'sprintf-js';
 
-import ko from 'knockout';
 import 'ko/ko.all';
-import komapping from 'knockout.mapping';
-import 'ext/ko.editable.custom';
-import 'ext/ko.selectize.custom';
-import 'knockout-switch-case';
-import 'knockout-sortable';
-import 'knockout.validation';
 
 import apiHelper from 'api/apiHelper';
 import CancellablePromise from 'api/cancellablePromise';
 import contextCatalog from 'catalog/contextCatalog';
+import 'utils/customIntervals';
 import dataCatalog from 'catalog/dataCatalog';
 import hueAnalytics from 'utils/hueAnalytics';
 import hueDebug from 'utils/hueDebug';
 import hueDrop from 'utils/hueDrop';
 import huePubSub from 'utils/huePubSub';
 import hueUtils from 'utils/hueUtils';
+import 'utils/json.bigDataParse';
 import MultiLineEllipsisHandler from 'utils/multiLineEllipsisHandler';
 
 import AceLocationHandler from 'sql/aceLocationHandler';
+import SqlParseSupport from 'sql/parse/sqlParseSupport';
 import sqlUtils from 'sql/sqlUtils';
+import { PigFunctions, SqlSetOptions, SqlFunctions } from 'sql/sqlFunctions';
 import sqlWorkerHandler from 'sql/sqlWorkerHandler';
 
 import 'assist/assistViewModel';
@@ -64,12 +61,14 @@ window.hueAnalytics = hueAnalytics;
 window.hueDebug = hueDebug;
 window.huePubSub = huePubSub;
 window.hueDrop = hueDrop;
-window.ko = ko;
-window.ko.mapping = komapping;
 window.localforage = localforage;
 window.MultiLineEllipsisHandler = MultiLineEllipsisHandler;
 window.page = page;
 window.sprintf = sprintf;
+window.PigFunctions = PigFunctions;
+window.SqlParseSupport = SqlParseSupport;
+window.SqlSetOptions = SqlSetOptions;
+window.SqlFunctions = SqlFunctions;
 window.sqlUtils = sqlUtils;
 window.sqlWorkerHandler = sqlWorkerHandler;
 window.qq = qq;

+ 5 - 1
desktop/core/src/desktop/js/jquery/jquery.all.js

@@ -19,7 +19,9 @@ import 'jquery/jquery.migration';
 
 import 'jquery.cookie';
 import 'jquery-form';
-import 'selectize';
+import 'jquery/plugins/jquery.selectize';
+import 'selectize-plugin-clear';
+
 import 'jquery-ui/ui/widgets/autocomplete';
 import 'jquery-ui/ui/widgets/mouse';
 import 'jquery-ui/ui/widgets/draggable';
@@ -36,9 +38,11 @@ import 'jquery/plugins/jquery.filechooser';
 import 'jquery/plugins/jquery.hdfs.autocomplete';
 import 'jquery/plugins/jquery.hiveautocomplete';
 import 'jquery/plugins/jquery.horizontalscrollbar';
+import 'jquery/plugins/jquery.huedatatable';
 import 'jquery/plugins/jquery.notify';
 import 'jquery/plugins/jquery.rowselector';
 import 'jquery/plugins/jquery.scrollleft';
+import 'jquery/plugins/jquery.scrollup';
 import 'jquery/plugins/jquery.selector';
 import 'jquery/plugins/jquery.tableextender';
 import 'jquery/plugins/jquery.tableextender2';

+ 774 - 0
desktop/core/src/desktop/js/jquery/plugins/jquery.huedatatable.js

@@ -0,0 +1,774 @@
+// Licensed to Cloudera, Inc. under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  Cloudera, Inc. 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.
+
+import $ from 'jquery';
+
+import huePubSub from 'utils/huePubSub';
+import hueUtils from 'utils/hueUtils';
+
+/*
+ * Extension to datatable to programmatically switch off datatable in case of huge tables
+ *
+ */
+
+$.fn.hueDataTable = function(oInit) {
+  const self = this;
+  self.$table = null;
+
+  self.fnSetColumnVis = function(index, visible) {
+    const aoColumns = self.$table.data('aoColumns');
+    const change = aoColumns[index].bVisible !== visible;
+    aoColumns[index].bVisible = visible;
+    if (!change) {
+      return;
+    }
+    if (!visible) {
+      self.$table
+        .find('tr')
+        .find('td:eq(' + index + '),th:eq(' + index + ')')
+        .hide();
+    } else {
+      self.$table
+        .find('tr')
+        .find('td:eq(' + index + '),th:eq(' + index + ')')
+        .show();
+    }
+    if (self.$table.data('plugin_jHueTableExtender')) {
+      self.$table.data('plugin_jHueTableExtender').drawLockedRows(true);
+    } else if (self.$table.data('plugin_jHueTableExtender2')) {
+      self.$table.data('plugin_jHueTableExtender2').redraw();
+    }
+  };
+
+  self.fnToggleAllCols = function(visible) {
+    const aoColumns = self.$table.data('aoColumns');
+    aoColumns.forEach((col, idx) => {
+      if (idx > 0) {
+        col.bVisible = visible;
+      }
+    });
+    if (!visible) {
+      self.$table.find('th, td').hide();
+      self.$table
+        .find('tr')
+        .find('td:eq(0),th:eq(0)')
+        .show();
+    } else {
+      self.$table.find('th, td').show();
+    }
+    if (self.$table.data('plugin_jHueTableExtender')) {
+      self.$table.data('plugin_jHueTableExtender').drawLockedRows(true);
+    } else if (self.$table.data('plugin_jHueTableExtender2')) {
+      self.$table.data('plugin_jHueTableExtender2').redraw();
+    }
+  };
+
+  self.fnSortColumn = function(obj, way) {
+    const data = self.$table.data('data');
+
+    let idx = obj.originalIndex;
+    if (way === 0) {
+      idx = 0;
+    }
+
+    let sortType = 'alpha';
+    if (obj.cssClass) {
+      if (obj.cssClass === 'sort-numeric') {
+        sortType = 'numeric';
+      }
+      if (obj.cssClass === 'sort-date') {
+        sortType = 'date';
+      }
+    }
+
+    if (way === -1 || way === 0) {
+      data.sort((a, b) => {
+        if (sortType === 'date') {
+          if (a[idx] === 'NULL') {
+            return -1;
+          }
+          if (b[idx] === 'NULL') {
+            return 1;
+          }
+          if (
+            moment(a[idx].replace(/\&nbsp;/, ' ')).valueOf() >
+            moment(b[idx].replace(/\&nbsp;/, ' ')).valueOf()
+          ) {
+            return 1;
+          }
+          if (
+            moment(a[idx].replace(/\&nbsp;/, ' ')).valueOf() <
+            moment(b[idx].replace(/\&nbsp;/, ' ')).valueOf()
+          ) {
+            return -1;
+          }
+          return 0;
+        } else if (sortType === 'numeric') {
+          if (a[idx] === 'NULL') {
+            return -1;
+          }
+          if (b[idx] === 'NULL') {
+            return 1;
+          }
+          if (a[idx] * 1 > b[idx] * 1) {
+            return 1;
+          }
+          if (a[idx] * 1 < b[idx] * 1) {
+            return -1;
+          }
+          return 0;
+        } else {
+          if (a[idx] > b[idx]) {
+            return 1;
+          }
+          if (a[idx] < b[idx]) {
+            return -1;
+          }
+          return 0;
+        }
+      });
+    } else {
+      data.sort((a, b) => {
+        if (sortType === 'date') {
+          if (a[idx] === 'NULL') {
+            return 1;
+          }
+          if (b[idx] === 'NULL') {
+            return -1;
+          }
+          if (
+            moment(a[idx].replace(/\&nbsp;/, ' ')).valueOf() >
+            moment(b[idx].replace(/\&nbsp;/, ' ')).valueOf()
+          ) {
+            return -1;
+          }
+          if (
+            moment(a[idx].replace(/\&nbsp;/, ' ')).valueOf() <
+            moment(b[idx].replace(/\&nbsp;/, ' ')).valueOf()
+          ) {
+            return 1;
+          }
+          return 0;
+        } else if (sortType === 'numeric') {
+          if (a[idx] === 'NULL') {
+            return 1;
+          }
+          if (b[idx] === 'NULL') {
+            return -1;
+          }
+          if (a[idx] * 1 > b[idx] * 1) {
+            return -1;
+          }
+          if (a[idx] * 1 < b[idx] * 1) {
+            return 1;
+          }
+          return 0;
+        } else {
+          if (a[idx] > b[idx]) {
+            return -1;
+          }
+          if (a[idx] < b[idx]) {
+            return 1;
+          }
+          return 0;
+        }
+      });
+    }
+
+    self.fnDraw(true);
+  };
+
+  self.fnShowSearch = function() {
+    if ($('.hue-datatable-search').length == 0) {
+      const search = $('<div>')
+        .css({
+          position: 'fixed',
+          bottom: '20px',
+          opacity: 0.85
+        })
+        .addClass('hueAnchor hue-datatable-search')
+        .appendTo(HUE_CONTAINER);
+      search.html(
+        '<input type="text"> <i class="fa fa-chevron-up pointer muted"></i> <i class="fa fa-chevron-down pointer muted"></i> &nbsp; <span></span> &nbsp; <i class="fa fa-times pointer inactive-action"></i>'
+      );
+
+      search.find('.fa-times').on('click', () => {
+        search.hide();
+        const $t = self.$table;
+        if ($t.data('scrollToRow') != null) {
+          $t.data('scrollToCol', null);
+          $t.data('scrollToRow', null);
+          $t.find('.columnSelected').removeClass('columnSelected');
+        }
+      });
+
+      search.find('.fa-chevron-down').on('click', () => {
+        if (!self.isScrolling) {
+          self.fnScrollToNextResult();
+        }
+      });
+
+      search.find('.fa-chevron-up').on('click', () => {
+        if (!self.isScrolling) {
+          self.fnScrollToPreviousResult();
+        }
+      });
+
+      search.find('input').jHueDelayedInput(
+        () => {
+          self.fnSearch(search.find('input').val());
+        },
+        600,
+        true
+      );
+
+      search.find('input').keydown(e => {
+        if ([13, 37, 38, 39, 40].indexOf(e.keyCode) > -1) {
+          e.preventDefault();
+          e.stopPropagation();
+          e.stopImmediatePropagation();
+          if ([13, 39, 40].indexOf(e.keyCode) > -1) {
+            search.find('.fa-chevron-down').trigger('click');
+          } else {
+            search.find('.fa-chevron-up').trigger('click');
+          }
+        }
+      });
+
+      search.find('input').focus();
+
+      huePubSub.subscribe('hue.datatable.search.hide', () => {
+        $('.hue-datatable-search').hide();
+      });
+    } else {
+      $('.hue-datatable-search').show();
+      $('.hue-datatable-search')
+        .find('input')
+        .focus();
+    }
+    let right = -30;
+    if (IS_HUE_4) {
+      const adjustRight =
+        $(window).width() - ($('.page-content').width() + $('.page-content').offset().left);
+      if (adjustRight > 0) {
+        right = adjustRight;
+      }
+    }
+    $('.hueAnchorScroller:visible').each(function() {
+      const visibleRight =
+        $(this)
+          .css('right')
+          .replace(/px/gi, '') * 1;
+      if (!isNaN(visibleRight) && visibleRight > right) {
+        right = visibleRight;
+      }
+    });
+    $('.hue-datatable-search').css('right', right + 50 + 'px');
+  };
+
+  self.fnSearch = function(what, avoidScroll) {
+    const $t = self.$table;
+    if ($t) {
+      if (typeof avoidScroll === 'undefined' || !avoidScroll) {
+        $t.find('.columnSelected').removeClass('columnSelected');
+        $t.data('scrollToCol', null);
+        $t.data('scrollToRow', null);
+      }
+
+      if (what !== '') {
+        $('.hue-datatable-search')
+          .find('span')
+          .text('');
+        $('.hue-datatable-search')
+          .find('.fa-chevron-down')
+          .addClass('muted')
+          .removeClass('inactive-action');
+        $('.hue-datatable-search')
+          .find('.fa-chevron-up')
+          .addClass('muted')
+          .removeClass('inactive-action');
+        const coords = [];
+        $t.data('searchCoords', []);
+        $t.data('searchCoordHighlighted', 0);
+        const data = self.$table.data('data');
+        data.forEach((row, rowIdx) => {
+          row.forEach((fld, fldIdx) => {
+            if (
+              (fld + '')
+                .replace(/\&nbsp;/, ' ')
+                .toLowerCase()
+                .indexOf(what.toLowerCase()) > -1
+            ) {
+              coords.push({
+                row: rowIdx,
+                col: fldIdx
+              });
+            }
+          });
+        });
+        $t.data('searchCoords', coords);
+        if (coords.length > 0) {
+          if (
+            $('.hue-datatable-search')
+              .find('input')
+              .val() !== ''
+          ) {
+            $('.hue-datatable-search')
+              .find('.fa-chevron-down')
+              .removeClass('muted')
+              .addClass('inactive-action');
+            $('.hue-datatable-search')
+              .find('.fa-chevron-up')
+              .removeClass('muted')
+              .addClass('inactive-action');
+          }
+          if (typeof avoidScroll === 'undefined' || !avoidScroll) {
+            self.fnScrollTo(coords[0].row, coords[0].col);
+          } else {
+            $('.hue-datatable-search')
+              .find('span')
+              .text(
+                $t.data('searchCoordHighlighted') +
+                  1 +
+                  ' ' +
+                  $t.data('oInit')['i18n'].OF +
+                  ' ' +
+                  $t.data('searchCoords').length
+              );
+          }
+        } else {
+          $('.hue-datatable-search')
+            .find('span')
+            .text($t.data('oInit')['i18n'].NO_RESULTS);
+        }
+      }
+    }
+  };
+
+  self.fnScrollToPreviousResult = function() {
+    const $t = self.$table;
+    if ($t && $t.data('searchCoords') && $t.data('searchCoords').length > 0) {
+      let high = $t.data('searchCoordHighlighted');
+      high = high == 0 ? $t.data('searchCoords').length - 1 : high - 1;
+      $t.data('searchCoordHighlighted', high);
+      self.fnScrollTo($t.data('searchCoords')[high].row, $t.data('searchCoords')[high].col);
+    }
+  };
+
+  self.fnScrollToNextResult = function() {
+    const $t = self.$table;
+    if ($t && $t.data('searchCoords') && $t.data('searchCoords').length > 0) {
+      let high = $t.data('searchCoordHighlighted');
+      high = high == $t.data('searchCoords').length - 1 ? 0 : high + 1;
+      $t.data('searchCoordHighlighted', high);
+      self.fnScrollTo($t.data('searchCoords')[high].row, $t.data('searchCoords')[high].col);
+    }
+  };
+
+  self.isScrolling = false;
+  self.fnScrollTo = function(row, col) {
+    const $t = self.$table;
+    if ($t) {
+      self.isScrolling = true;
+      $('.hue-datatable-search')
+        .find('span')
+        .text(
+          $t.data('searchCoordHighlighted') +
+            1 +
+            ' ' +
+            $t.data('oInit')['i18n'].OF +
+            ' ' +
+            $t.data('searchCoords').length
+        );
+      const colSel = $t.find('tr th:nth-child(' + (col + 1) + ')');
+      $t.parent().animate(
+        {
+          scrollLeft:
+            colSel.position().left + $t.parent().scrollLeft() - $t.parent().offset().left - 30
+        },
+        300,
+        () => {
+          self.isScrolling = false;
+        }
+      );
+      $t.parents($t.data('oInit')['scrollable']).animate(
+        {
+          scrollTop:
+            $t
+              .find('tbody tr')
+              .find('td:eq(0)')
+              .filter(function() {
+                return $(this).text() - 1 == row;
+              })
+              .position().top + 73
+        },
+        100,
+        () => {
+          $t.data('scrollToCol', col);
+          $t.data('scrollToRow', row);
+          $t.data('scrollAnimate', true);
+          $t.parent().trigger('scroll');
+        }
+      );
+    }
+  };
+
+  self.isDrawing = false;
+
+  self.fnDraw = function(force) {
+    const aoColumns = self.$table.data('aoColumns');
+    if (!self.isDrawing && aoColumns) {
+      const $t = self.$table;
+      if ($t) {
+        self.isDrawing = true;
+        const data = self.$table.data('data');
+        const appendable = $t.children('tbody').length > 0 ? $t.children('tbody') : $t;
+        let startCol = -1;
+        let endCol = -1;
+        $t.find('thead>tr th').each(function(i) {
+          if ($(this).position().left > 0 && startCol == -1) {
+            startCol = i;
+          }
+          if ($(this).position().left < $t.parent().width() + $t.parent().position().left) {
+            endCol = i;
+          }
+        });
+        startCol = Math.max(1, startCol - 1);
+        endCol = Math.min(aoColumns.length, endCol + 3); // avoid loading just after the col
+        // for tables under the 30 columns, display them all at once
+        if (aoColumns.length <= 30) {
+          endCol = aoColumns.length;
+        }
+
+        const rowHeight = 32;
+        const invisibleOffset = $t.data('oInit')['forceInvisible']
+          ? $t.data('oInit')['forceInvisible']
+          : aoColumns.length < 100
+          ? 10
+          : 1;
+        const scrollable = $t.parents($t.data('oInit')['scrollable']);
+        let visibleRows = Math.ceil(
+          (scrollable.height() - Math.max($t.offset().top, 0)) / rowHeight
+        );
+        if ($t.data('oInit')['contained']) {
+          visibleRows = Math.ceil(scrollable.height() / rowHeight);
+        }
+        visibleRows += invisibleOffset;
+        visibleRows = Math.max(visibleRows, 11);
+
+        let startRow =
+          $t.offset().top - 73 < 0
+            ? Math.max(Math.floor(Math.abs($t.offset().top - 73) / rowHeight) - invisibleOffset, 0)
+            : 0;
+        if ($t.data('oInit')['contained']) {
+          startRow = Math.max(
+            0,
+            Math.floor(Math.abs($t.position().top) / rowHeight) - invisibleOffset
+          );
+        }
+        const endRow = startRow + visibleRows + invisibleOffset;
+
+        if (
+          endRow != $t.data('endRow') ||
+          (endRow == $t.data('endRow') && endCol > $t.data('endCol')) ||
+          force
+        ) {
+          $t.data('endCol', endCol);
+          $t.data('endRow', endRow);
+
+          if ($t.data('fnDraws') === 0) {
+            let html = '';
+            for (let i = 0; i < data.length; i++) {
+              html +=
+                '<tr class="ht-visible-row ht-visible-row-' +
+                i +
+                '"><td>' +
+                hueUtils.deXSS(data[i][0]) +
+                '</td><td colspan="' +
+                (aoColumns.length - 1) +
+                '" class="stripe"></td></tr>';
+            }
+            appendable.html(html);
+            if ($t.data('plugin_jHueTableExtender')) {
+              $t.data('plugin_jHueTableExtender').drawFirstColumn();
+            }
+            if ($t.data('plugin_jHueTableExtender2')) {
+              $t.data('plugin_jHueTableExtender2').drawFirstColumn(true);
+            }
+          } else if (force) {
+            let html = '';
+            for (let i = $t.find('.ht-visible-row').length; i < data.length; i++) {
+              html +=
+                '<tr class="ht-visible-row ht-visible-row-' +
+                i +
+                '"><td>' +
+                hueUtils.deXSS(data[i][0]) +
+                '</td><td colspan="' +
+                (aoColumns.length - 1) +
+                '" class="stripe"></td></tr>';
+            }
+            appendable.html(appendable.html() + html);
+          }
+
+          for (let i = 0; i < data.length; i++) {
+            let html = '';
+            if (i >= startRow && i <= endRow) {
+              const row = data[i];
+              if (row) {
+                for (let j = 0; j < endCol; j++) {
+                  html +=
+                    '<td ' +
+                    (!aoColumns[j].bVisible ? 'style="display: none"' : '') +
+                    '>' +
+                    hueUtils.deXSS(row[j]) +
+                    '</td>';
+                }
+
+                if (endCol < aoColumns.length) {
+                  html += '<td colspan="' + (aoColumns.length - endCol) + '" class="stripe"></td>';
+                }
+              }
+            } else {
+              html =
+                '<td>' +
+                hueUtils.deXSS(data[i][0]) +
+                '</td><td colspan="' +
+                (aoColumns.length - 1) +
+                '" class="stripe"></td>';
+            }
+            appendable
+              .children()
+              .eq(i)
+              .html(html);
+          }
+
+          if (force) {
+            if ($t.data('plugin_jHueTableExtender')) {
+              $t.data('plugin_jHueTableExtender').drawFirstColumn();
+            }
+            if ($t.data('plugin_jHueTableExtender2')) {
+              $t.data('plugin_jHueTableExtender2').drawFirstColumn(true);
+            }
+          }
+        }
+        if ($t.data('scrollToCol')) {
+          $t.find('.columnSelected').removeClass('columnSelected');
+          let colSel = $t.find('tr th:nth-child(' + ($t.data('scrollToCol') + 1) + ')');
+          if ($t.find('tr td:nth-child(' + ($t.data('scrollToCol') + 1) + ')').length > 0) {
+            colSel = $t.find('tr td:nth-child(' + ($t.data('scrollToCol') + 1) + ')');
+          }
+          if ($t.data('scrollAnimate')) {
+            if ($t.data('scrollAnimateDirect')) {
+              $t.parent().scrollLeft(
+                colSel.position().left +
+                  $t.parent().scrollLeft() -
+                  ($t.data('scrollInPopover') ? 0 : $t.parent().offset().left) -
+                  30
+              );
+              $t.parent().trigger('scroll');
+            } else {
+              $t.parent().animate(
+                {
+                  scrollLeft:
+                    colSel.position().left +
+                    $t.parent().scrollLeft() -
+                    ($t.data('scrollInPopover') ? 0 : $t.parent().offset().left) -
+                    30
+                },
+                300,
+                () => {
+                  $t.parent().trigger('scroll');
+                }
+              );
+            }
+            if (
+              $t.data('scrollLastColPosLeft') == null ||
+              $t.data('scrollLastColPosLeft') != colSel.position().left
+            ) {
+              $t.data('scrollLastColPosLeft', colSel.position().left);
+              $t.data('scrollLastParentLeft', $t.parent().scrollLeft());
+            } else {
+              $t.data('scrollAnimate', null);
+              $t.data('scrollAnimateDirect', null);
+              $t.data('scrollLastColPosLeft', null);
+              $t.data('scrollLastParentLeft', null);
+            }
+          }
+          if ($t.data('scrollToRow') == null) {
+            colSel.addClass('columnSelected');
+          } else {
+            $t.find(
+              'tr:nth-child(' +
+                ($t.data('scrollToRow') + 1) +
+                ') td:nth-child(' +
+                ($t.data('scrollToCol') + 1) +
+                ')'
+            ).addClass('columnSelected');
+          }
+
+          if ($t.data('plugin_jHueTableExtender')) {
+            $t.data('plugin_jHueTableExtender').drawHeader(typeof force === 'undefined');
+            $t.data('plugin_jHueTableExtender').drawLockedRows();
+          }
+          if ($t.data('plugin_jHueTableExtender2')) {
+            $t.data('plugin_jHueTableExtender2').drawLockedRows();
+          }
+        }
+        $t.data('fnDraws', $t.data('fnDraws') + 1);
+        if ($t.data('oInit')['fnDrawCallback']) {
+          $t.data('oInit')['fnDrawCallback']();
+        }
+
+        $t.trigger('headerpadding');
+
+        self.isDrawing = false;
+      }
+    }
+  };
+
+  self.fnAddData = function(mData, bRedraw) {
+    const $t = self.$table;
+
+    if ($t) {
+      const aoColumns = $t.data('aoColumns') || [];
+      $t.data('data', $t.data('data').concat(mData));
+
+      if (mData.length === 0) {
+        return;
+      }
+
+      if (aoColumns.length === 0) {
+        mData[0].forEach(() => {
+          aoColumns.push({
+            bVisible: true
+          });
+        });
+      }
+      self.fnDraw(true);
+
+      if ($('.hue-datatable-search').is(':visible')) {
+        self.fnSearch(
+          $('.hue-datatable-search')
+            .find('input')
+            .val(),
+          true
+        );
+      }
+    }
+  };
+
+  self.fnSettings = function() {
+    const aoColumns = self.$table.data('aoColumns');
+    return {
+      aoColumns: aoColumns
+    };
+  };
+
+  self.fnClearTable = function(bRedraw) {
+    const $t = self.$table;
+    if ($t) {
+      if ($t.children('tbody').length > 0) {
+        $t.children('tbody').empty();
+      } else {
+        $t.children('tr').remove();
+      }
+      $t.data('data', []);
+      $t.data('aoRows', []);
+      $t.data('aoColumns', []);
+      $t.data('fnDraws', 0);
+    }
+  };
+
+  self.fnDestroy = function() {
+    self.fnClearTable();
+    self.$table.unwrap();
+    self.$table.data('isScrollAttached', null);
+    self.$table.removeClass('table-huedatatable');
+    if (self.$table.data('oInit')) {
+      self.$table
+        .parents(self.$table.data('oInit')['scrollable'])
+        .off(
+          'scroll',
+          self.$table.parents(self.$table.data('oInit')['scrollable']).data('scrollFnDt')
+        );
+    }
+  };
+
+  return self.each(function() {
+    self.$table = $(this);
+    const parent = self.$table.parent();
+    if (parent.hasClass('dataTables_wrapper')) {
+      return;
+    }
+    $('.hue-datatable-search').remove();
+    self.$table.data('data', []);
+    self.$table.data('aoRows', []);
+    self.$table.data('aoColumns', []);
+    self.$table.data('fnDraws', 0);
+    self.$table.wrap('<div class="dataTables_wrapper"></div>');
+
+    self.$table.unbind('sort');
+    self.$table.bind('sort', (e, obj) => {
+      self.$table
+        .find('thead tr th:not(:eq(' + obj.originalIndex + '))')
+        .removeClass('sorting_desc')
+        .removeClass('sorting_asc');
+      self.$table.data('scrollAnimate', true);
+      self.$table.data('scrollAnimateDirect', true);
+      const $cell = self.$table.find('thead tr th:eq(' + obj.originalIndex + ')');
+      if ($cell.hasClass('sorting_desc')) {
+        $cell.removeClass('sorting_desc');
+        self.fnSortColumn(obj, 0);
+      } else if ($cell.hasClass('sorting_asc')) {
+        $cell.removeClass('sorting_asc').addClass('sorting_desc');
+        self.fnSortColumn(obj, 1);
+      } else {
+        $cell.addClass('sorting_asc');
+        self.fnSortColumn(obj, -1);
+      }
+      if (self.$table.data('plugin_jHueTableExtender2')) {
+        self.$table.data('plugin_jHueTableExtender2').drawHeader();
+        self.$table.data('plugin_jHueTableExtender2').drawLockedRows();
+      }
+    });
+
+    if (typeof oInit !== 'undefined') {
+      self.$table.data('oInit', oInit);
+      let drawTimeout = -1;
+      if (self.$table.data('oInit')['scrollable'] && !self.$table.data('isScrollAttached')) {
+        self.$table.data('isScrollAttached', true);
+        const scrollFn = function() {
+          window.clearTimeout(drawTimeout);
+          drawTimeout = window.setTimeout(
+            self.fnDraw,
+            Math.max(
+              100,
+              Math.min(
+                self.$table.data('aoColumns') ? self.$table.data('aoColumns').length : 500,
+                500
+              )
+            )
+          );
+        };
+        window.setTimeout(() => {
+          self.$table.parents(oInit['scrollable']).data('scrollFnDt', scrollFn);
+          self.$table.parents(oInit['scrollable']).on('scroll', scrollFn);
+        }, 1000);
+      }
+    }
+    self.$table.addClass('table-huedatatable');
+  });
+};

+ 5 - 0
desktop/core/src/desktop/js/jquery/plugins/jquery.selectize.js

@@ -0,0 +1,5 @@
+/*! selectize clear button plugin by Alexey Petushkov | https://github.com/mentatxx/selectize-plugin-clear | Apache License (v2) */
+
+import Selectize from 'selectize';
+
+window.Selectize = Selectize;

+ 7 - 8
desktop/core/src/desktop/js/ko/bindings/ko.impalaDagre.js

@@ -23,15 +23,14 @@ import huePubSub from 'utils/huePubSub';
 
 ko.bindingHandlers.impalaDagre = (function() {
   return {
-    init: function(element) {
+    init: function(element, valueAccessor, allBindingsAccessor) {
       const id = $(element).attr('id');
-      const self = this;
-      self._impalaDagre = impalaDagre(id);
+      element._impalaDagre = impalaDagre(id);
       const clickSubscription = huePubSub.subscribe('impala.node.moveto', value => {
-        self._impalaDagre.moveTo(value);
+        element._impalaDagre.moveTo(value);
       });
       const selectSubscription = huePubSub.subscribe('impala.node.select', value => {
-        self._impalaDagre.select(value);
+        element._impalaDagre.select(value);
       });
       ko.utils.domNodeDisposal.addDisposeCallback(element, () => {
         clickSubscription.remove();
@@ -40,9 +39,9 @@ ko.bindingHandlers.impalaDagre = (function() {
     },
     update: function(element, valueAccessor) {
       const props = ko.unwrap(valueAccessor());
-      this._impalaDagre.metrics(props.metrics);
-      this._impalaDagre.height(props.height);
-      this._impalaDagre.update(props.value);
+      element._impalaDagre.metrics(props.metrics);
+      element._impalaDagre.height(props.height);
+      element._impalaDagre.update(props.value);
     }
   };
 })();

+ 12 - 0
desktop/core/src/desktop/js/ko/ko.all.js

@@ -14,6 +14,15 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
+import ko from 'knockout';
+import komapping from 'knockout.mapping';
+import 'knockout-switch-case';
+import 'knockout-sortable';
+import 'knockout.validation';
+
+import 'ext/ko.editable.custom';
+import 'ext/ko.selectize.custom';
+
 import 'ko/bindings/ko.aceEditor';
 import 'ko/bindings/ko.aceResizer';
 import 'ko/bindings/ko.appAwareTemplateContextMenu';
@@ -111,3 +120,6 @@ import 'ko/extenders/ko.toJson';
 
 import 'ko/observables/ko.observableArrayDefault';
 import 'ko/observables/ko.observableDefault';
+
+window.ko = ko;
+window.ko.mapping = komapping;

+ 116 - 0
desktop/core/src/desktop/js/utils/customIntervals.js

@@ -0,0 +1,116 @@
+// Licensed to Cloudera, Inc. under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  Cloudera, Inc. 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.
+
+const originalSetInterval = window.setInterval;
+const originalClearInterval = window.clearInterval;
+let hueIntervals = [];
+
+/**
+ * @param {string} [app] - context for the intervals
+ */
+window.getIntervals = function(app) {
+  if (app) {
+    return hueIntervals.filter(obj => {
+      return obj.app === app;
+    });
+  }
+  return hueIntervals;
+};
+
+/**
+ * @param {Function} fn - the function to be called at intervals
+ * @param {Number} timeout - timeout in milliseconds
+ * @param {string} [app] - context for the interval
+ */
+window.setInterval = function(fn, timeout, app) {
+  const id = originalSetInterval(fn, timeout);
+  hueIntervals.push({
+    fn: fn,
+    timeout: timeout,
+    app: app,
+    id: id,
+    originalId: id,
+    status: 'running'
+  });
+  return id;
+};
+
+/**
+ * @param {Number} id - the original interval id generated by window.setInterval
+ */
+
+window.clearInterval = function(id) {
+  const foundIntervals = hueIntervals.filter(obj => {
+    return obj.originalId === id;
+  });
+  if (foundIntervals && foundIntervals.length > 0) {
+    originalClearInterval(foundIntervals[0].id);
+  } else {
+    originalClearInterval(id);
+  }
+  hueIntervals = hueIntervals.filter(obj => {
+    return obj.originalId !== id;
+  });
+};
+
+/**
+ * @param {string} app - context for the intervals to be suspended
+ */
+window.pauseAppIntervals = function(app) {
+  hueIntervals.forEach(interval => {
+    if (
+      typeof interval.app !== 'undefined' &&
+      interval.app !== null &&
+      (interval.app === app || (interval.app.split('-') && interval.app.split('-')[0] === app))
+    ) {
+      interval.status = 'paused';
+      originalClearInterval(interval.id);
+    }
+  });
+};
+
+/**
+ * @param {string} app - context for the intervals to be restarted
+ */
+window.resumeAppIntervals = function(app) {
+  hueIntervals.forEach(interval => {
+    if (
+      typeof interval.app !== 'undefined' &&
+      interval.app !== null &&
+      (interval.app === app || interval.app.split('-')[0] === app) &&
+      interval.status === 'paused'
+    ) {
+      interval.status = 'running';
+      interval.id = originalSetInterval(interval.fn, interval.timeout);
+    }
+  });
+};
+
+/**
+ * @param {string} app - context for the intervals to be cleared
+ */
+window.clearAppIntervals = function(app) {
+  hueIntervals.forEach(interval => {
+    if (
+      interval.app === app ||
+      (typeof interval.app !== 'undefined' &&
+        interval.app !== null &&
+        interval.app.split('-')[0] === app)
+    ) {
+      window.clearInterval(interval.originalId);
+    }
+  });
+};

+ 303 - 0
desktop/core/src/desktop/js/utils/json.bigDataParse.js

@@ -0,0 +1,303 @@
+// Licensed to Cloudera, Inc. under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  Cloudera, Inc. 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.
+
+// Based on json_parse by Douglas Crockford
+// https://github.com/douglascrockford/JSON-js/blob/master/json_parse.js
+
+JSON.bigdataParse = (function() {
+  'use strict';
+
+  // This is a function that can parse a JSON text, producing a JavaScript
+  // data structure. It is a simple, recursive descent parser. It does not use
+  // eval or regular expressions, so it can be used as a model for implementing
+  // a JSON parser in other languages.
+
+  // We are defining the function inside of another function to avoid creating
+  // global variables.
+
+  let at; // The index of the current character
+  let ch; // The current character
+  const escapee = {
+    '"': '"',
+    '\\': '\\',
+    '/': '/',
+    b: '\b',
+    f: '\f',
+    n: '\n',
+    r: '\r',
+    t: '\t'
+  };
+  let text;
+  const error = function(m) {
+    // Call error when something is wrong.
+
+    throw {
+      name: 'SyntaxError',
+      message: m,
+      at: at,
+      text: text
+    };
+  };
+  const next = function(c) {
+    // If a c parameter is provided, verify that it matches the current character.
+
+    if (c && c !== ch) {
+      error("Expected '" + c + "' instead of '" + ch + "'");
+    }
+
+    // Get the next character. When there are no more characters,
+    // return the empty string.
+    try {
+      ch = text.charAt(at);
+      at += 1;
+      return ch;
+    } catch (e) {
+      return '';
+    }
+  };
+  const number = function() {
+    // Parse a number value.
+
+    let string = '';
+
+    if (ch === '-') {
+      string = '-';
+      next('-');
+    }
+    while (ch >= '0' && ch <= '9') {
+      string += ch;
+      next();
+    }
+    if (ch === '.') {
+      string += '.';
+      while (next() && ch >= '0' && ch <= '9') {
+        string += ch;
+      }
+    }
+    if (ch === 'e' || ch === 'E') {
+      string += ch;
+      next();
+      if (ch === '-' || ch === '+') {
+        string += ch;
+        next();
+      }
+      while (ch >= '0' && ch <= '9') {
+        string += ch;
+        next();
+      }
+    }
+    const numberInt = +string;
+    if (!isFinite(number)) {
+      error('Bad number');
+    } else {
+      //if (number > 9007199254740992 || number < -9007199254740992)
+      // Bignumber has stricter check: everything with length > 15 digits disallowed
+      if (string.length > 15) {
+        return string;
+      }
+      return numberInt;
+    }
+  };
+  const string = function() {
+    // Parse a string value.
+
+    let hex,
+      i,
+      string = '',
+      uffff;
+
+    // When parsing for string values, we must look for " and \ characters.
+
+    if (ch === '"') {
+      while (next()) {
+        if (ch === '"') {
+          next();
+          return string;
+        }
+        if (ch === '\\') {
+          next();
+          if (ch === 'u') {
+            uffff = 0;
+            for (i = 0; i < 4; i += 1) {
+              hex = parseInt(next(), 16);
+              if (!isFinite(hex)) {
+                break;
+              }
+              uffff = uffff * 16 + hex;
+            }
+            string += String.fromCharCode(uffff);
+          } else if (typeof escapee[ch] === 'string') {
+            string += escapee[ch];
+          } else {
+            break;
+          }
+        } else {
+          string += ch;
+        }
+      }
+    }
+    error('Bad string');
+  };
+  const white = function() {
+    // Skip whitespace.
+
+    while (ch && ch <= ' ') {
+      next();
+    }
+  };
+  const value = function() {
+    // Parse a JSON value. It could be an object, an array, a string, a number,
+    // or a word.
+
+    white();
+    switch (ch) {
+      case '{':
+        return object();
+      case '[':
+        return array();
+      case '"':
+        return string();
+      case '-':
+        return number();
+      default:
+        return ch >= '0' && ch <= '9' ? number() : word();
+    }
+  };
+  const word = function() {
+    // true, false, or null.
+
+    switch (ch) {
+      case 't':
+        next('t');
+        next('r');
+        next('u');
+        next('e');
+        return true;
+      case 'f':
+        next('f');
+        next('a');
+        next('l');
+        next('s');
+        next('e');
+        return false;
+      case 'n':
+        next('n');
+        next('u');
+        next('l');
+        next('l');
+        return null;
+    }
+    error("Unexpected '" + ch + "'");
+  };
+  const array = function() {
+    // Parse an array value.
+
+    const array = [];
+
+    if (ch === '[') {
+      next('[');
+      white();
+      if (ch === ']') {
+        next(']');
+        return array; // empty array
+      }
+      while (ch) {
+        array.push(value());
+        white();
+        if (ch === ']') {
+          next(']');
+          return array;
+        }
+        next(',');
+        white();
+      }
+    }
+    error('Bad array');
+  };
+  const object = function() {
+    // Parse an object value.
+
+    let key;
+    const object = {};
+
+    if (ch === '{') {
+      next('{');
+      white();
+      if (ch === '}') {
+        next('}');
+        return object; // empty object
+      }
+      while (ch) {
+        key = string();
+        white();
+        next(':');
+        if (Object.hasOwnProperty.call(object, key)) {
+          error('Duplicate key "' + key + '"');
+        }
+        object[key] = value();
+        white();
+        if (ch === '}') {
+          next('}');
+          return object;
+        }
+        next(',');
+        white();
+      }
+    }
+    error('Bad object');
+  };
+
+  // Return the json_parse function. It will have access to all of the above
+  // functions and variables.
+
+  return function(source, reviver) {
+    text = source;
+    at = 0;
+    ch = ' ';
+    const res = value();
+    white();
+    if (ch) {
+      error('Syntax error');
+    }
+
+    // If there is a reviver function, we recursively walk the new structure,
+    // passing each name/value pair to the reviver function for possible
+    // transformation, starting with a temporary root object that holds the result
+    // in an empty key. If there is not a reviver function, we simply return the
+    // result.
+
+    return typeof reviver === 'function'
+      ? (function walk(holder, key) {
+          let k;
+          let v;
+          const val = holder[key];
+          if (val && typeof val === 'object') {
+            for (k in val) {
+              if (Object.prototype.hasOwnProperty.call(val, k)) {
+                v = walk(val, k);
+                if (v !== undefined) {
+                  val[k] = v;
+                } else {
+                  delete val[k];
+                }
+              }
+            }
+          }
+          return reviver.call(holder, key, val);
+        })({ '': res }, '')
+      : res;
+  };
+})();

Разница между файлами не показана из-за своего большого размера
+ 0 - 5
desktop/core/src/desktop/static/desktop/ext/js/bootstrap.min.js


+ 0 - 1311
desktop/core/src/desktop/static/desktop/ext/js/fileuploader.js

@@ -1,1311 +0,0 @@
-/*
- Multiple file upload component with progress-bar, drag-and-drop.
- http://github.com/valums/file-uploader
-
- Copyright (C) 2011 by Andris Valums
-
- Permission is hereby granted, free of charge, to any person obtaining a copy
- of this software and associated documentation files (the "Software"), to deal
- in the Software without restriction, including without limitation the rights
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- copies of the Software, and to permit persons to whom the Software is
- furnished to do so, subject to the following conditions:
-
- The above copyright notice and this permission notice shall be included in
- all copies or substantial portions of the Software.
-
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- THE SOFTWARE.
- */
-
-//
-// Helper functions
-//
-
-var qq = qq || {};
-
-/**
- * Adds all missing properties from second obj to first obj
- */
-qq.extend = function(first, second){
-    for (var prop in second){
-        first[prop] = second[prop];
-    }
-};
-
-/**
- * Searches for a given element in the array, returns -1 if it is not present.
- * @param {Number} [from] The index at which to begin the search
- */
-qq.indexOf = function(arr, elt, from){
-    if (arr.indexOf) return arr.indexOf(elt, from);
-
-    from = from || 0;
-    var len = arr.length;
-
-    if (from < 0) from += len;
-
-    for (; from < len; from++){
-        if (from in arr && arr[from] === elt){
-            return from;
-        }
-    }
-    return -1;
-};
-
-qq.getUniqueId = (function(){
-    var id = 0;
-    return function(){ return id++; };
-})();
-
-//
-// Events
-
-qq.attach = function(element, type, fn){
-    if (element.addEventListener){
-        element.addEventListener(type, fn, false);
-    } else if (element.attachEvent){
-        element.attachEvent('on' + type, fn);
-    }
-};
-qq.detach = function(element, type, fn){
-    if (element.removeEventListener){
-        element.removeEventListener(type, fn, false);
-    } else if (element.attachEvent){
-        element.detachEvent('on' + type, fn);
-    }
-};
-
-qq.preventDefault = function(e){
-    if (e.preventDefault){
-        e.preventDefault();
-    } else{
-        e.returnValue = false;
-    }
-};
-
-//
-// Node manipulations
-
-/**
- * Insert node a before node b.
- */
-qq.insertBefore = function(a, b){
-    b.parentNode.insertBefore(a, b);
-};
-qq.remove = function(element){
-    element.parentNode.removeChild(element);
-};
-
-qq.contains = function(parent, descendant){
-    // compareposition returns false in this case
-    if (parent == descendant) return true;
-
-    if (parent.contains){
-        return parent.contains(descendant);
-    } else {
-        return !!(descendant.compareDocumentPosition(parent) & 8);
-    }
-};
-
-/**
- * Creates and returns element from html string
- * Uses innerHTML to create an element
- */
-qq.toElement = (function(){
-    var div = document.createElement('div');
-    return function(html){
-        div.innerHTML = html;
-        var element = div.firstChild;
-        div.removeChild(element);
-        return element;
-    };
-})();
-
-//
-// Node properties and attributes
-
-/**
- * Sets styles for an element.
- * Fixes opacity in IE6-8.
- */
-qq.css = function(element, styles){
-    if (styles.opacity != null){
-        if (typeof element.style.opacity != 'string' && typeof(element.filters) != 'undefined'){
-            styles.filter = 'alpha(opacity=' + Math.round(100 * styles.opacity) + ')';
-        }
-    }
-    qq.extend(element.style, styles);
-};
-qq.hasClass = function(element, name){
-    var re = new RegExp('(^| )' + name + '( |$)');
-    return re.test(element.className);
-};
-qq.addClass = function(element, name){
-    if (!qq.hasClass(element, name)){
-        element.className += ' ' + name;
-    }
-};
-qq.removeClass = function(element, name){
-    var re = new RegExp('(^| )' + name + '( |$)');
-    element.className = element.className.replace(re, ' ').replace(/^\s+|\s+$/g, "");
-};
-qq.setText = function(element, text){
-    element.innerText = text;
-    element.textContent = text;
-};
-
-//
-// Selecting elements
-
-qq.children = function(element){
-    var children = [],
-    child = element.firstChild;
-
-    while (child){
-        if (child.nodeType == 1){
-            children.push(child);
-        }
-        child = child.nextSibling;
-    }
-
-    return children;
-};
-
-qq.getByClass = function(element, className){
-    if (element.querySelectorAll){
-        return element.querySelectorAll('.' + className);
-    }
-
-    var result = [];
-    var candidates = element.getElementsByTagName("*");
-    var len = candidates.length;
-
-    for (var i = 0; i < len; i++){
-        if (qq.hasClass(candidates[i], className)){
-            result.push(candidates[i]);
-        }
-    }
-    return result;
-};
-
-/**
- * obj2url() takes a json-object as argument and generates
- * a querystring. pretty much like jQuery.param()
- *
- * how to use:
- *
- *    `qq.obj2url({a:'b',c:'d'},'http://any.url/upload?otherParam=value');`
- *
- * will result in:
- *
- *    `http://any.url/upload?otherParam=value&a=b&c=d`
- *
- * @param  Object JSON-Object
- * @param  String current querystring-part
- * @return String encoded querystring
- */
-qq.obj2url = function(obj, temp, prefixDone){
-    var uristrings = [],
-        prefix = '&',
-        add = function(nextObj, i){
-            var nextTemp = temp
-                ? (/\[\]$/.test(temp)) // prevent double-encoding
-                   ? temp
-                   : temp+'['+i+']'
-                : i;
-            if ((nextTemp != 'undefined') && (i != 'undefined')) {
-                uristrings.push(
-                    (typeof nextObj === 'object')
-                        ? qq.obj2url(nextObj, nextTemp, true)
-                        : (Object.prototype.toString.call(nextObj) === '[object Function]')
-                            ? encodeURIComponent(nextTemp) + '=' + encodeURIComponent(nextObj())
-                            : encodeURIComponent(nextTemp) + '=' + encodeURIComponent(nextObj)
-                );
-            }
-        };
-
-    if (!prefixDone && temp) {
-      prefix = (/\?/.test(temp)) ? (/\?$/.test(temp)) ? '' : '&' : '?';
-      uristrings.push(temp);
-      uristrings.push(qq.obj2url(obj));
-    } else if ((Object.prototype.toString.call(obj) === '[object Array]') && (typeof obj != 'undefined') ) {
-        // we wont use a for-in-loop on an array (performance)
-        for (var i = 0, len = obj.length; i < len; ++i){
-            add(obj[i], i);
-        }
-    } else if ((typeof obj != 'undefined') && (obj !== null) && (typeof obj === "object")){
-        // for anything else but a scalar, we will use for-in-loop
-        for (var i in obj){
-            add(obj[i], i);
-        }
-    } else {
-        uristrings.push(encodeURIComponent(temp) + '=' + encodeURIComponent(obj));
-    }
-
-    return uristrings.join(prefix)
-                     .replace(/^&/, '')
-                     .replace(/%20/g, '+');
-};
-
-//
-//
-// Uploader Classes
-//
-//
-
-var qq = qq || {};
-
-
-
-/**
- * Creates upload button, validates upload, but doesn't create file list or dd.
- */
-qq.FileUploaderBasic = function(o){
-    this._options = {
-        // set to true to see the server response
-        debug: false,
-        action: '/server/upload',
-        dest: '/',
-        fileFieldLabel: 'hdfs_file',
-        params: {},
-        button: null,
-        multiple: true,
-        maxConnections: 3,
-        // validation
-        allowedExtensions: [],
-        sizeLimit: 0,
-        minSizeLimit: 0,
-        // events
-        // return false to cancel submit
-        onSubmit: function(id, fileName){},
-        onProgress: function(id, fileName, loaded, total){},
-        onComplete: function(id, fileName, responseJSON){},
-        onCancel: function(id, fileName){},
-        // messages
-        messages: {
-            typeError: "{file} has invalid extension. Only {extensions} are allowed.",
-            sizeError: "{file} is too large, maximum file size is {sizeLimit}.",
-            minSizeError: "{file} is too small, minimum file size is {minSizeLimit}.",
-            emptyError: "{file} is empty, please select files again without it.",
-            onLeave: "The files are being uploaded, if you leave now the upload will be cancelled."
-        },
-        showMessage: function(message){
-            alert(message);
-        }
-    };
-    qq.extend(this._options, o);
-
-    // number of files being uploaded
-    this._filesInProgress = 0;
-    this._handler = this._createUploadHandler();
-
-    if (this._options.button){
-        this._button = this._createUploadButton(this._options.button);
-    }
-
-    this._preventLeaveInProgress();
-};
-
-qq.FileUploaderBasic.prototype = {
-    setParams: function(params){
-        this._options.params = params;
-    },
-    getInProgress: function(){
-        return this._filesInProgress;
-    },
-    _createUploadButton: function(element){
-        var self = this;
-
-        return new qq.UploadButton({
-            element: element,
-            multiple: this._options.multiple && qq.UploadHandlerXhr.isSupported(),
-            onChange: function(input){
-                self._onInputChange(input);
-            }
-        });
-    },
-    _createUploadHandler: function(){
-        var self = this,
-            handlerClass;
-
-        if(qq.UploadHandlerXhr.isSupported()){
-            handlerClass = 'UploadHandlerXhr';
-        } else {
-            handlerClass = 'UploadHandlerForm';
-        }
-
-        var handler = new qq[handlerClass]({
-            debug: this._options.debug,
-            action: this._options.action,
-            dest: '/',
-            fileFieldLabel:'hdfs_file',
-            maxConnections: this._options.maxConnections,
-            onProgress: function(id, fileName, loaded, total){
-                self._onProgress(id, fileName, loaded, total);
-                self._options.onProgress(id, fileName, loaded, total);
-            },
-            onComplete: function(id, fileName, result){
-                self._onComplete(id, fileName, result);
-                self._options.onComplete(id, fileName, result);
-            },
-            onCancel: function(id, fileName){
-                self._onCancel(id, fileName);
-                self._options.onCancel(id, fileName);
-            }
-        });
-
-        return handler;
-    },
-    _preventLeaveInProgress: function(){
-        var self = this;
-
-        qq.attach(window, 'beforeunload', function(e){
-            if (!self._filesInProgress){return;}
-
-            var e = e || window.event;
-            // for ie, ff
-            e.returnValue = self._options.messages.onLeave;
-            // for webkit
-            return self._options.messages.onLeave;
-        });
-    },
-    _onSubmit: function(id, fileName){
-        this._filesInProgress++;
-    },
-    _onProgress: function(id, fileName, loaded, total){
-    },
-    _onComplete: function(id, fileName, result){
-        this._filesInProgress--;
-        if (result.error){
-            this._options.showMessage(result.error);
-        }
-    },
-    _onCancel: function(id, fileName){
-        this._filesInProgress--;
-    },
-    _onInputChange: function(input){
-        if (this._handler instanceof qq.UploadHandlerXhr){
-            this._uploadFileList(input.files);
-        } else {
-            if (this._validateFile(input)){
-                this._uploadFile(input);
-            }
-        }
-        this._button.reset();
-    },
-    _uploadFileList: function(files){
-        for (var i=0; i<files.length; i++){
-            if ( !this._validateFile(files[i])){
-                return;
-            }
-        }
-
-        for (var i=0; i<files.length; i++){
-            this._uploadFile(files[i]);
-        }
-    },
-    _uploadFile: function(fileContainer){
-        var id = this._handler.add(fileContainer);
-        var fileName = this._handler.getName(id);
-
-        if (this._options.onSubmit(id, fileName) !== false){
-            this._onSubmit(id, fileName);
-            this._handler.upload(id, this._options.params);
-        }
-    },
-    _validateFile: function(file){
-        var name, size;
-
-        if (file.value){
-            // it is a file input
-            // get input value and remove path to normalize
-            name = file.value.replace(/.*(\/|\\)/, "");
-        } else {
-            // fix missing properties in Safari
-            name = file.fileName != null ? file.fileName : file.name;
-            size = file.fileSize != null ? file.fileSize : file.size;
-        }
-
-        if (! this._isAllowedExtension(name)){
-            this._error('typeError', name);
-            return false;
-
-        } else if (size === 0){
-            this._error('emptyError', name);
-            return false;
-
-        } else if (size && this._options.sizeLimit && size > this._options.sizeLimit){
-            this._error('sizeError', name);
-            return false;
-
-        } else if (size && size < this._options.minSizeLimit){
-            this._error('minSizeError', name);
-            return false;
-        }
-
-        return true;
-    },
-    _error: function(code, fileName){
-        var message = this._options.messages[code];
-        function r(name, replacement){ message = message.replace(name, replacement); }
-
-        r('{file}', this._formatFileName(fileName));
-        r('{extensions}', this._options.allowedExtensions.join(', '));
-        r('{sizeLimit}', this._formatSize(this._options.sizeLimit));
-        r('{minSizeLimit}', this._formatSize(this._options.minSizeLimit));
-
-        this._options.showMessage(message);
-    },
-    _formatFileName: function(name){
-        if (name.length > 33){
-            name = name.slice(0, 19) + '...' + name.slice(-13);
-        }
-        return name;
-    },
-    _isAllowedExtension: function(fileName){
-        var ext = (-1 !== fileName.indexOf('.')) ? fileName.replace(/.*[.]/, '').toLowerCase() : '';
-        var allowed = this._options.allowedExtensions;
-
-        if (!allowed.length){return true;}
-
-        for (var i=0; i<allowed.length; i++){
-            if (allowed[i].toLowerCase() == ext){ return true;}
-        }
-
-        return false;
-    },
-    _formatSize: function(bytes){
-        var i = -1;
-        do {
-            bytes = bytes / 1024;
-            i++;
-        } while (bytes > 99);
-
-        return Math.max(bytes, 0.1).toFixed(1) + ['kB', 'MB', 'GB', 'TB', 'PB', 'EB'][i];
-    }
-};
-
-
-/**
- * Class that creates upload widget with drag-and-drop and file list
- * @inherits qq.FileUploaderBasic
- */
-
-qq.FileUploader = function(o){
-    // call parent constructor
-    qq.FileUploaderBasic.apply(this, arguments);
-
-    // additional options
-    qq.extend(this._options, {
-        element: null,
-        // if set, will be used instead of qq-upload-list in template
-        listElement: null,
-
-        template: '<div class="qq-uploader">' +
-                '<div class="qq-upload-drop-area"><span>Drop files here to upload</span></div>' +
-                '<div class="qq-upload-button">Upload a file</div>' +
-                '<ul class="qq-upload-list"></ul>' +
-             '</div>',
-
-        // template for one item in file list
-        fileTemplate: '<li>' +
-                '<span class="qq-upload-file"></span>' +
-                '<span class="qq-upload-spinner"></span>' +
-                '<span class="qq-upload-size"></span>' +
-                '<a class="qq-upload-cancel" href="#">Cancel</a>' +
-                '<span class="qq-upload-failed-text">Failed</span>' +
-            '</li>',
-
-        classes: {
-            // used to get elements from templates
-            button: 'qq-upload-button',
-            drop: 'qq-upload-drop-area',
-            dropActive: 'qq-upload-drop-area-active',
-            list: 'qq-upload-list',
-
-            file: 'qq-upload-file',
-            extendedFileName: 'qq-upload-file-extended',
-            spinner: 'qq-upload-spinner',
-            size: 'qq-upload-size',
-            cancel: 'qq-upload-cancel',
-
-            // added to list item when upload completes
-            // used in css to hide progress spinner
-            success: 'qq-upload-success',
-            fail: 'qq-upload-fail'
-        }
-    });
-    // overwrite options with user supplied
-    this._options.dest = "";
-    this._options.fileFieldLabel = "";
-
-    qq.extend(this._options, o);
-
-
-    this._element = this._options.element;
-    this._element.innerHTML = this._options.template;
-    this._listElement = this._options.listElement || this._find(this._element, 'list');
-
-    this._classes = this._options.classes;
-
-    this._button = this._createUploadButton(this._find(this._element, 'button'));
-
-    this._bindCancelEvent();
-    this._bindCancelAllEvent();
-    this._setupDragDrop();
-};
-
-// inherit from Basic Uploader
-qq.extend(qq.FileUploader.prototype, qq.FileUploaderBasic.prototype);
-
-qq.extend(qq.FileUploader.prototype, {
-    /**
-     * Gets one of the elements listed in this._options.classes
-     **/
-    _find: function(parent, type, skipIfNotFound){
-        var element = qq.getByClass(parent, this._options.classes[type])[0];
-        if (!element && typeof skipIfNotFound === 'undefined'){
-            throw new Error('element not found ' + type);
-        }
-
-        return element;
-    },
-    _setupDragDrop: function(){
-        var self = this,
-            dropArea = this._find(this._element, 'drop');
-
-        var dz = new qq.UploadDropZone({
-            element: dropArea,
-            onEnter: function(e){
-                qq.addClass(dropArea, self._classes.dropActive);
-                e.stopPropagation();
-            },
-            onLeave: function(e){
-                e.stopPropagation();
-            },
-            onLeaveNotDescendants: function(e){
-                qq.removeClass(dropArea, self._classes.dropActive);
-            },
-            onDrop: function(e){
-                dropArea.style.display = 'none';
-                qq.removeClass(dropArea, self._classes.dropActive);
-                self._uploadFileList(e.dataTransfer.files);
-            }
-        });
-
-        dropArea.style.display = 'none';
-
-        qq.attach(document, 'dragenter', function(e){
-            if (!dz._isValidFileDrag(e)) return;
-
-            dropArea.style.display = 'block';
-        });
-        qq.attach(document, 'dragleave', function(e){
-            if (!dz._isValidFileDrag(e)) return;
-
-            var relatedTarget = document.elementFromPoint(e.clientX, e.clientY);
-            // only fire when leaving document out
-            if ( ! relatedTarget || relatedTarget.nodeName == "HTML"){
-                dropArea.style.display = 'none';
-            }
-        });
-    },
-    _onSubmit: function(id, fileName){
-        qq.FileUploaderBasic.prototype._onSubmit.apply(this, arguments);
-        this._addToList(id, fileName);
-    },
-    _onProgress: function(id, fileName, loaded, total){
-        qq.FileUploaderBasic.prototype._onProgress.apply(this, arguments);
-
-        var item = this._getItemByFileId(id);
-        var size = this._find(item, 'size');
-        size.style.display = 'inline';
-
-        var text;
-        if (loaded != total){
-            text = Math.round(loaded / total * 100) + '% from ' + this._formatSize(total);
-        } else {
-            text = this._formatSize(total);
-        }
-
-        qq.setText(size, text);
-    },
-    _onComplete: function(id, fileName, result){
-        qq.FileUploaderBasic.prototype._onComplete.apply(this, arguments);
-
-        // mark completed
-        var item = this._getItemByFileId(id);
-        qq.remove(this._find(item, 'cancel'));
-        qq.remove(this._find(item, 'spinner'));
-        if (result.status && result.status == -1){
-          qq.addClass(item, this._classes.fail);
-        } else {
-          qq.addClass(item, this._classes.success);
-        }
-    },
-    _addToList: function(id, fileName){
-        var item = qq.toElement(this._options.fileTemplate);
-        item.qqFileId = id;
-
-        var fileElement = this._find(item, 'file');
-        qq.setText(fileElement, this._formatFileName(fileName));
-
-        var extendedFileElement = this._find(item, 'extendedFileName', true);
-        if (extendedFileElement){
-            qq.setText(extendedFileElement, fileName);
-        }
-
-        this._find(item, 'size').style.display = 'none';
-
-        this._listElement.appendChild(item);
-    },
-    _getItemByFileId: function(id){
-        var item = this._listElement.firstChild;
-
-        // there can't be txt nodes in dynamically created list
-        // and we can  use nextSibling
-        while (item){
-            if (item.qqFileId == id) return item;
-            item = item.nextSibling;
-        }
-    },
-    /**
-     * delegate click event for cancel link
-     **/
-    _bindCancelEvent: function(){
-        var self = this,
-            list = this._listElement;
-
-        qq.attach(list, 'click', function(e){
-            e = e || window.event;
-            var target = e.target || e.srcElement;
-
-            if (qq.hasClass(target, self._classes.cancel)){
-                qq.preventDefault(e);
-
-                var item = target.parentNode;
-                if (qq.hasClass(item, 'complex-layout')){
-                    item = item.parentNode.parentNode.parentNode;
-                }
-                self._handler.cancel(item.qqFileId);
-                qq.remove(item);
-            }
-        });
-    },
-    _bindCancelAllEvent: function() {
-      var self = this,
-        list = this._listElement;
-      $('#uploadFileModal').on('hidden', function () {
-        for (var i = 0, l = list && list.childNodes.length; i < l; i++) {
-          self._handler.cancel(list.childNodes[i].qqFileId);
-        }
-      });
-    }
-});
-
-qq.UploadDropZone = function(o){
-    this._options = {
-        element: null,
-        onEnter: function(e){},
-        onLeave: function(e){},
-        // is not fired when leaving element by hovering descendants
-        onLeaveNotDescendants: function(e){},
-        onDrop: function(e){}
-    };
-    qq.extend(this._options, o);
-
-    this._element = this._options.element;
-
-    this._disableDropOutside();
-    this._attachEvents();
-};
-
-qq.UploadDropZone.prototype = {
-    _disableDropOutside: function(e){
-        // run only once for all instances
-        if (!qq.UploadDropZone.dropOutsideDisabled ){
-
-            qq.attach(document, 'dragover', function(e){
-                if (e.dataTransfer){
-                    e.dataTransfer.dropEffect = 'none';
-                    e.preventDefault();
-                }
-            });
-
-            qq.UploadDropZone.dropOutsideDisabled = true;
-        }
-    },
-    _attachEvents: function(){
-        var self = this;
-
-        qq.attach(self._element, 'dragover', function(e){
-            if (!self._isValidFileDrag(e)) return;
-
-            var effect = e.dataTransfer.effectAllowed;
-            if (effect == 'move' || effect == 'linkMove'){
-                e.dataTransfer.dropEffect = 'move'; // for FF (only move allowed)
-            } else {
-                e.dataTransfer.dropEffect = 'copy'; // for Chrome
-            }
-
-            e.stopPropagation();
-            e.preventDefault();
-        });
-
-        qq.attach(self._element, 'dragenter', function(e){
-            if (!self._isValidFileDrag(e)) return;
-
-            self._options.onEnter(e);
-        });
-
-        qq.attach(self._element, 'dragleave', function(e){
-            if (!self._isValidFileDrag(e)) return;
-
-            self._options.onLeave(e);
-
-            var relatedTarget = document.elementFromPoint(e.clientX, e.clientY);
-            // do not fire when moving a mouse over a descendant
-            if (qq.contains(this, relatedTarget)) return;
-
-            self._options.onLeaveNotDescendants(e);
-        });
-
-        qq.attach(self._element, 'drop', function(e){
-            if (!self._isValidFileDrag(e)) return;
-
-            e.preventDefault();
-            self._options.onDrop(e);
-        });
-    },
-    _isValidFileDrag: function(e){
-        var dt = e.dataTransfer,
-            // do not check dt.types.contains in webkit, because it crashes safari 4
-            isWebkit = navigator.userAgent.indexOf("AppleWebKit") > -1;
-            isIE9 = navigator.appVersion.indexOf("MSIE 9") > -1;
-
-        if (isIE9) return false;
-
-        // dt.effectAllowed is none in Safari 5
-        // dt.types.contains check is for firefox
-        return dt && dt.effectAllowed != 'none' &&
-            (dt.files || (!isWebkit && dt.types && dt.types.contains && dt.types.contains('Files')));
-
-    }
-};
-
-qq.UploadButton = function(o){
-    this._options = {
-        element: null,
-        // if set to true adds multiple attribute to file input
-        multiple: false,
-        // name attribute of file input
-        name: 'file',
-        onChange: function(input){},
-        hoverClass: 'qq-upload-button-hover',
-        focusClass: 'qq-upload-button-focus'
-    };
-
-    qq.extend(this._options, o);
-
-    this._element = this._options.element;
-
-    // make button suitable container for input
-    qq.css(this._element, {
-        position: 'relative',
-        overflow: 'hidden',
-        // Make sure browse button is in the right side
-        // in Internet Explorer
-        direction: 'ltr'
-    });
-
-    this._input = this._createInput();
-};
-
-qq.UploadButton.prototype = {
-    /* returns file input element */
-    getInput: function(){
-        return this._input;
-    },
-    /* cleans/recreates the file input */
-    reset: function(){
-        if (this._input.parentNode){
-            qq.remove(this._input);
-        }
-
-        qq.removeClass(this._element, this._options.focusClass);
-        this._input = this._createInput();
-    },
-    _createInput: function(){
-        var input = document.createElement("input");
-
-        if (this._options.multiple){
-            input.setAttribute("multiple", "multiple");
-        }
-
-        input.setAttribute("type", "file");
-        input.setAttribute("name", this._options.name);
-
-        qq.css(input, {
-            position: 'absolute',
-            // in Opera only 'browse' button
-            // is clickable and it is located at
-            // the right side of the input
-            right: 0,
-            top: 0,
-            fontFamily: 'Arial',
-            // 4 persons reported this, the max values that worked for them were 243, 236, 236, 118
-            fontSize: '118px',
-            margin: 0,
-            padding: 0,
-            cursor: 'pointer',
-            opacity: 0
-        });
-
-        this._element.appendChild(input);
-
-        var self = this;
-        qq.attach(input, 'change', function(){
-            self._options.onChange(input);
-        });
-
-        qq.attach(input, 'mouseover', function(){
-            qq.addClass(self._element, self._options.hoverClass);
-        });
-        qq.attach(input, 'mouseout', function(){
-            qq.removeClass(self._element, self._options.hoverClass);
-        });
-        qq.attach(input, 'focus', function(){
-            qq.addClass(self._element, self._options.focusClass);
-        });
-        qq.attach(input, 'blur', function(){
-            qq.removeClass(self._element, self._options.focusClass);
-        });
-
-        // IE and Opera, unfortunately have 2 tab stops on file input
-        // which is unacceptable in our case, disable keyboard access
-        if (window.attachEvent){
-            // it is IE or Opera
-            input.setAttribute('tabIndex', "-1");
-        }
-
-        return input;
-    }
-};
-
-/**
- * Class for uploading files, uploading itself is handled by child classes
- */
-qq.UploadHandlerAbstract = function(o){
-    this._options = {
-        debug: false,
-        action: '/upload.php',
-        // maximum number of concurrent uploads
-        maxConnections: 999,
-        onProgress: function(id, fileName, loaded, total){},
-        onComplete: function(id, fileName, response){},
-        onCancel: function(id, fileName){}
-    };
-    qq.extend(this._options, o);
-
-    this._queue = [];
-    // params for files in queue
-    this._params = [];
-};
-qq.UploadHandlerAbstract.prototype = {
-    log: function(str){
-        if (this._options.debug && window.console) console.log('[uploader] ' + str);
-    },
-    /**
-     * Adds file or file input to the queue
-     * @returns id
-     **/
-    add: function(file){},
-    /**
-     * Sends the file identified by id and additional query params to the server
-     */
-    upload: function(id, params){
-        var len = this._queue.push(id);
-
-        var copy = {};
-        qq.extend(copy, params);
-        this._params[id] = copy;
-
-        // if too many active uploads, wait...
-        if (len <= this._options.maxConnections){
-            this._upload(id, this._params[id]);
-        }
-    },
-    /**
-     * Cancels file upload by id
-     */
-    cancel: function(id){
-        this._cancel(id);
-        this._dequeue(id);
-    },
-    /**
-     * Cancells all uploads
-     */
-    cancelAll: function(){
-        for (var i=0; i<this._queue.length; i++){
-            this._cancel(this._queue[i]);
-        }
-        this._queue = [];
-    },
-    /**
-     * Returns name of the file identified by id
-     */
-    getName: function(id){},
-    /**
-     * Returns size of the file identified by id
-     */
-    getSize: function(id){},
-    /**
-     * Returns id of files being uploaded or
-     * waiting for their turn
-     */
-    getQueue: function(){
-        return this._queue;
-    },
-    /**
-     * Actual upload method
-     */
-    _upload: function(id){},
-    /**
-     * Actual cancel method
-     */
-    _cancel: function(id){},
-    /**
-     * Removes element from queue, starts upload of next
-     */
-    _dequeue: function(id){
-        var i = qq.indexOf(this._queue, id);
-        this._queue.splice(i, 1);
-
-        var max = this._options.maxConnections;
-
-        if (this._queue.length >= max && i < max){
-            var nextId = this._queue[max-1];
-            this._upload(nextId, this._params[nextId]);
-        }
-    }
-};
-
-/**
- * Class for uploading files using form and iframe
- * @inherits qq.UploadHandlerAbstract
- */
-qq.UploadHandlerForm = function(o){
-    qq.UploadHandlerAbstract.apply(this, arguments);
-
-    this._inputs = {};
-};
-// @inherits qq.UploadHandlerAbstract
-qq.extend(qq.UploadHandlerForm.prototype, qq.UploadHandlerAbstract.prototype);
-
-qq.extend(qq.UploadHandlerForm.prototype, {
-    add: function(fileInput){
-        fileInput.setAttribute('name', 'qqfile');
-        var id = 'qq-upload-handler-iframe' + qq.getUniqueId();
-
-        this._inputs[id] = fileInput;
-
-        // remove file input from DOM
-        if (fileInput.parentNode){
-            qq.remove(fileInput);
-        }
-
-        return id;
-    },
-    getName: function(id){
-        // get input value and remove path to normalize
-        return this._inputs[id].value.replace(/.*(\/|\\)/, "");
-    },
-    _cancel: function(id){
-        if (this._inputs[id]) {
-          this._options.onCancel(id, this.getName(id));
-        }
-
-        delete this._inputs[id];
-
-        var iframe = document.getElementById(id);
-        if (iframe){
-            // to cancel request set src to something else
-            // we use src="javascript:false;" because it doesn't
-            // trigger ie6 prompt on https
-            iframe.setAttribute('src', 'javascript:false;');
-
-            qq.remove(iframe);
-        }
-    },
-    _upload: function(id, params){
-        var input = this._inputs[id];
-
-        if (!input){
-            throw new Error('file with passed id was not added, or already uploaded or cancelled');
-        }
-
-        var fileName = this.getName(id);
-
-        var iframe = this._createIframe(id);
-        var form = this._createForm(iframe, params);
-        input.name = params.fileFieldLabel;
-        form.appendChild(input);
-
-        var dest = document.createElement('input');
-        dest.type = 'text';
-        dest.name = 'dest';
-        dest.value = params.dest;
-        form.appendChild(dest);
-
-        var csrfmiddlewaretoken = document.createElement('input');
-        csrfmiddlewaretoken.type = 'hidden';
-        csrfmiddlewaretoken.name = 'csrfmiddlewaretoken';
-        csrfmiddlewaretoken.value = "${request and request.COOKIES.get('csrftoken', '')}";
-        form.appendChild(csrfmiddlewaretoken);
-
-        var self = this;
-        this._attachLoadEvent(iframe, function(){
-            self.log('iframe loaded');
-
-            var response = self._getIframeContentJSON(iframe);
-
-            self._options.onComplete(id, fileName, response);
-            self._dequeue(id);
-
-            delete self._inputs[id];
-            // timeout added to fix busy state in FF3.6
-            setTimeout(function(){
-                qq.remove(iframe);
-            }, 1);
-        });
-
-        form.submit();
-        qq.remove(form);
-
-        return id;
-    },
-    _attachLoadEvent: function(iframe, callback){
-        qq.attach(iframe, 'load', function(){
-            // when we remove iframe from dom
-            // the request stops, but in IE load
-            // event fires
-            if (!iframe.parentNode){
-                return;
-            }
-
-            // fixing Opera 10.53
-            if (iframe.contentDocument &&
-                iframe.contentDocument.body &&
-                iframe.contentDocument.body.innerHTML == "false"){
-                // In Opera event is fired second time
-                // when body.innerHTML changed from false
-                // to server response approx. after 1 sec
-                // when we upload file with iframe
-                return;
-            }
-
-            callback();
-        });
-    },
-    /**
-     * Returns json object received by iframe from server.
-     */
-    _getIframeContentJSON: function(iframe){
-        // iframe.contentWindow.document - for IE<7
-        var doc = iframe.contentDocument ? iframe.contentDocument: iframe.contentWindow.document,
-            response;
-
-        this.log("converting iframe's innerHTML to JSON");
-        this.log("innerHTML = " + $(doc.body.innerHTML).text());
-
-        try {
-            response = eval("(" + $(doc.body.innerHTML).text() + ")");
-        } catch(err){
-            response = {};
-        }
-
-        return response;
-    },
-    /**
-     * Creates iframe with unique name
-     */
-    _createIframe: function(id){
-        // We can't use following code as the name attribute
-        // won't be properly registered in IE6, and new window
-        // on form submit will open
-        // var iframe = document.createElement('iframe');
-        // iframe.setAttribute('name', id);
-
-        var iframe = qq.toElement('<iframe src="javascript:false;" name="' + id + '" />');
-        // src="javascript:false;" removes ie6 prompt on https
-
-        iframe.setAttribute('id', id);
-
-        iframe.style.display = 'none';
-        document.body.appendChild(iframe);
-
-        return iframe;
-    },
-    /**
-     * Creates form, that will be submitted to iframe
-     */
-    _createForm: function(iframe, params){
-        // We can't use the following code in IE6
-        // var form = document.createElement('form');
-        // form.setAttribute('method', 'post');
-        // form.setAttribute('enctype', 'multipart/form-data');
-        // Because in this case file won't be attached to request
-        var form = qq.toElement('<form method="post" enctype="multipart/form-data"></form>');
-
-        form.setAttribute('action', this._options.action);
-        form.setAttribute('target', iframe.name);
-        form.style.display = 'none';
-        document.body.appendChild(form);
-
-        return form;
-    }
-});
-
-/**
- * Class for uploading files using xhr
- * @inherits qq.UploadHandlerAbstract
- */
-qq.UploadHandlerXhr = function(o){
-    qq.UploadHandlerAbstract.apply(this, arguments);
-
-    this._files = [];
-    this._xhrs = [];
-
-    // current loaded size in bytes for each file
-    this._loaded = [];
-};
-
-// static method
-qq.UploadHandlerXhr.isSupported = function(){
-    var input = document.createElement('input');
-    input.type = 'file';
-
-    return (
-        'multiple' in input &&
-        typeof File != "undefined" &&
-        typeof (new XMLHttpRequest()).upload != "undefined" );
-};
-
-// @inherits qq.UploadHandlerAbstract
-qq.extend(qq.UploadHandlerXhr.prototype, qq.UploadHandlerAbstract.prototype)
-
-qq.extend(qq.UploadHandlerXhr.prototype, {
-    /**
-     * Adds file to the queue
-     * Returns id to use with upload, cancel
-     **/
-    add: function(file){
-        // HUE-815: [fb] Upload button does not work in Firefox 3.6
-        // see https://github.com/valums/ajax-upload/issues/91
-        //if (!(file instanceof File)){
-        if (!(file instanceof File || (file.__proto__ && file.__proto__.constructor.name == 'File') || file instanceof Object) ){
-            throw new Error('Passed obj in not a File (in qq.UploadHandlerXhr)');
-        }
-
-        return this._files.push(file) - 1;
-    },
-    getName: function(id){
-        var file = this._files[id];
-        // fix missing name in Safari 4
-        return file && (file.fileName || file.name);
-    },
-    getSize: function(id){
-        var file = this._files[id];
-        return file && (file.fileSize || file.size);
-    },
-    /**
-     * Returns uploaded bytes for file identified by id
-     */
-    getLoaded: function(id){
-        return this._loaded[id] || 0;
-    },
-    /**
-     * Sends the file identified by id and additional query params to the server
-     * @param {Object} params name-value string pairs
-     */
-    _upload: function(id, params){
-        var file = this._files[id],
-            name = this.getName(id),
-            size = this.getSize(id);
-
-        this._loaded[id] = 0;
-
-        var xhr = this._xhrs[id] = new XMLHttpRequest();
-        var self = this;
-
-        xhr.upload.onprogress = function(e){
-            if (e.lengthComputable){
-                self._loaded[id] = e.loaded;
-                self._options.onProgress(id, name, e.loaded, e.total);
-            }
-        };
-
-        xhr.onreadystatechange = function(){
-            if (xhr.readyState == 4){
-                self._onComplete(id, xhr);
-            }
-        };
-
-        var formData = new FormData();
-        formData.append(params.fileFieldLabel, file);
-        formData.append('dest', params.dest);
-
-        var action = this._options.action + "?dest=" + params.dest;
-        xhr.open("POST", action, true);
-        xhr.send(formData);
-    },
-    _onComplete: function(id, xhr){
-        // the request was aborted/cancelled
-        if (!this._files[id]) return;
-
-        var name = this.getName(id);
-        var size = this.getSize(id);
-
-        this._options.onProgress(id, name, size, size);
-
-        if (xhr.status == 200){
-            this.log("xhr - server response received");
-            this.log("responseText = " + xhr.responseText);
-
-            var response;
-
-            try {
-                response = eval("(" + xhr.responseText + ")");
-            } catch(err){
-                response = {};
-            }
-
-            this._options.onComplete(id, name, response);
-
-        } else {
-            this._options.onComplete(id, name, xhr);
-        }
-
-        this._files[id] = null;
-        this._xhrs[id] = null;
-        this._dequeue(id);
-    },
-    _cancel: function(id){
-        if (this._files[id]) {
-          this._options.onCancel(id, this.getName(id));
-        }
-
-        this._files[id] = null;
-
-        if (this._xhrs[id]){
-            this._xhrs[id].abort();
-            this._xhrs[id] = null;
-        }
-    }
-});

Разница между файлами не показана из-за своего большого размера
+ 0 - 5
desktop/core/src/desktop/static/desktop/ext/js/jquery/plugins/jquery-ui-1.10.4.custom.min.js


+ 0 - 47
desktop/core/src/desktop/static/desktop/ext/js/jquery/plugins/jquery.cookie.js

@@ -1,47 +0,0 @@
-/*!
- * jQuery Cookie Plugin
- * https://github.com/carhartl/jquery-cookie
- *
- * Copyright 2011, Klaus Hartl
- * Dual licensed under the MIT or GPL Version 2 licenses.
- * http://www.opensource.org/licenses/mit-license.php
- * http://www.opensource.org/licenses/GPL-2.0
- */
-(function($) {
-    $.cookie = function(key, value, options) {
-
-        // key and at least value given, set cookie...
-        if (arguments.length > 1 && (!/Object/.test(Object.prototype.toString.call(value)) || value === null || value === undefined)) {
-            options = $.extend({}, options);
-
-            if (value === null || value === undefined) {
-                options.expires = -1;
-            }
-
-            if (typeof options.expires === 'number') {
-                var days = options.expires, t = options.expires = new Date();
-                t.setDate(t.getDate() + days);
-            }
-
-            value = String(value);
-
-            return (document.cookie = [
-                encodeURIComponent(key), '=', options.raw ? value : encodeURIComponent(value),
-                options.expires ? '; expires=' + options.expires.toUTCString() : '', // use expires attribute, max-age is not supported by IE
-                options.path    ? '; path=' + options.path : '',
-                options.domain  ? '; domain=' + options.domain : '',
-                options.secure  ? '; secure' : ''
-            ].join(''));
-        }
-
-        // key and possibly options given, get cookie...
-        options = value || {};
-        var decode = options.raw ? function(s) { return s; } : decodeURIComponent;
-
-        var pairs = document.cookie.split('; ');
-        for (var i = 0, pair; pair = pairs[i] && pairs[i].split('='); i++) {
-            if (decode(pair[0]) === key) return decode(pair[1] || ''); // IE saves cookies with empty string as "c; ", e.g. without "=" as opposed to EOMB, thus pair[1] may be undefined
-        }
-        return null;
-    };
-})(jQuery);

+ 0 - 151
desktop/core/src/desktop/static/desktop/ext/js/jquery/plugins/jquery.dataTables.1.8.2.min.js

@@ -1,151 +0,0 @@
-/*
- * File:        jquery.dataTables.min.js
- * Version:     1.8.2
- * Author:      Allan Jardine (www.sprymedia.co.uk)
- * Info:        www.datatables.net
- *
- * Copyright 2008-2011 Allan Jardine, all rights reserved.
- *
- * This source file is free software, under either the GPL v2 license or a
- * BSD style license, as supplied with this software.
- *
- * This source file is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- * or FITNESS FOR A PARTICULAR PURPOSE. See the license files for details.
- */
-(function(i,za,p){i.fn.dataTableSettings=[];var D=i.fn.dataTableSettings;i.fn.dataTableExt={};var n=i.fn.dataTableExt;n.sVersion="1.8.2";n.sErrMode="alert";n.iApiIndex=0;n.oApi={};n.afnFiltering=[];n.aoFeatures=[];n.ofnSearch={};n.afnSortData=[];n.oStdClasses={sPagePrevEnabled:"paginate_enabled_previous",sPagePrevDisabled:"paginate_disabled_previous",sPageNextEnabled:"paginate_enabled_next",sPageNextDisabled:"paginate_disabled_next",sPageJUINext:"",sPageJUIPrev:"",sPageButton:"paginate_button",sPageButtonActive:"paginate_active",
-sPageButtonStaticDisabled:"paginate_button paginate_button_disabled",sPageFirst:"first",sPagePrevious:"previous",sPageNext:"next",sPageLast:"last",sStripeOdd:"odd",sStripeEven:"even",sRowEmpty:"dataTables_empty",sWrapper:"dataTables_wrapper",sFilter:"dataTables_filter",sInfo:"dataTables_info",sPaging:"dataTables_paginate paging_",sLength:"dataTables_length",sProcessing:"dataTables_processing",sSortAsc:"sorting_asc",sSortDesc:"sorting_desc",sSortable:"sorting",sSortableAsc:"sorting_asc_disabled",sSortableDesc:"sorting_desc_disabled",
-sSortableNone:"sorting_disabled",sSortColumn:"sorting_",sSortJUIAsc:"",sSortJUIDesc:"",sSortJUI:"",sSortJUIAscAllowed:"",sSortJUIDescAllowed:"",sSortJUIWrapper:"",sSortIcon:"",sScrollWrapper:"dataTables_scroll",sScrollHead:"dataTables_scrollHead",sScrollHeadInner:"dataTables_scrollHeadInner",sScrollBody:"dataTables_scrollBody",sScrollFoot:"dataTables_scrollFoot",sScrollFootInner:"dataTables_scrollFootInner",sFooterTH:""};n.oJUIClasses={sPagePrevEnabled:"fg-button ui-button ui-state-default ui-corner-left",
-sPagePrevDisabled:"fg-button ui-button ui-state-default ui-corner-left ui-state-disabled",sPageNextEnabled:"fg-button ui-button ui-state-default ui-corner-right",sPageNextDisabled:"fg-button ui-button ui-state-default ui-corner-right ui-state-disabled",sPageJUINext:"ui-icon ui-icon-circle-arrow-e",sPageJUIPrev:"ui-icon ui-icon-circle-arrow-w",sPageButton:"fg-button ui-button ui-state-default",sPageButtonActive:"fg-button ui-button ui-state-default ui-state-disabled",sPageButtonStaticDisabled:"fg-button ui-button ui-state-default ui-state-disabled",
-sPageFirst:"first ui-corner-tl ui-corner-bl",sPagePrevious:"previous",sPageNext:"next",sPageLast:"last ui-corner-tr ui-corner-br",sStripeOdd:"odd",sStripeEven:"even",sRowEmpty:"dataTables_empty",sWrapper:"dataTables_wrapper",sFilter:"dataTables_filter",sInfo:"dataTables_info",sPaging:"dataTables_paginate fg-buttonset ui-buttonset fg-buttonset-multi ui-buttonset-multi paging_",sLength:"dataTables_length",sProcessing:"dataTables_processing",sSortAsc:"ui-state-default",sSortDesc:"ui-state-default",sSortable:"ui-state-default",
-sSortableAsc:"ui-state-default",sSortableDesc:"ui-state-default",sSortableNone:"ui-state-default",sSortColumn:"sorting_",sSortJUIAsc:"css_right ui-icon ui-icon-triangle-1-n",sSortJUIDesc:"css_right ui-icon ui-icon-triangle-1-s",sSortJUI:"css_right ui-icon ui-icon-carat-2-n-s",sSortJUIAscAllowed:"css_right ui-icon ui-icon-carat-1-n",sSortJUIDescAllowed:"css_right ui-icon ui-icon-carat-1-s",sSortJUIWrapper:"DataTables_sort_wrapper",sSortIcon:"DataTables_sort_icon",sScrollWrapper:"dataTables_scroll",
-sScrollHead:"dataTables_scrollHead ui-state-default",sScrollHeadInner:"dataTables_scrollHeadInner",sScrollBody:"dataTables_scrollBody",sScrollFoot:"dataTables_scrollFoot ui-state-default",sScrollFootInner:"dataTables_scrollFootInner",sFooterTH:"ui-state-default"};n.oPagination={two_button:{fnInit:function(g,l,s){var t,w,y;if(g.bJUI){t=p.createElement("a");w=p.createElement("a");y=p.createElement("span");y.className=g.oClasses.sPageJUINext;w.appendChild(y);y=p.createElement("span");y.className=g.oClasses.sPageJUIPrev;
-t.appendChild(y)}else{t=p.createElement("div");w=p.createElement("div")}t.className=g.oClasses.sPagePrevDisabled;w.className=g.oClasses.sPageNextDisabled;t.title=g.oLanguage.oPaginate.sPrevious;w.title=g.oLanguage.oPaginate.sNext;l.appendChild(t);l.appendChild(w);i(t).bind("click.DT",function(){g.oApi._fnPageChange(g,"previous")&&s(g)});i(w).bind("click.DT",function(){g.oApi._fnPageChange(g,"next")&&s(g)});i(t).bind("selectstart.DT",function(){return false});i(w).bind("selectstart.DT",function(){return false});
-if(g.sTableId!==""&&typeof g.aanFeatures.p=="undefined"){l.setAttribute("id",g.sTableId+"_paginate");t.setAttribute("id",g.sTableId+"_previous");w.setAttribute("id",g.sTableId+"_next")}},fnUpdate:function(g){if(g.aanFeatures.p)for(var l=g.aanFeatures.p,s=0,t=l.length;s<t;s++)if(l[s].childNodes.length!==0){l[s].childNodes[0].className=g._iDisplayStart===0?g.oClasses.sPagePrevDisabled:g.oClasses.sPagePrevEnabled;l[s].childNodes[1].className=g.fnDisplayEnd()==g.fnRecordsDisplay()?g.oClasses.sPageNextDisabled:
-g.oClasses.sPageNextEnabled}}},iFullNumbersShowPages:5,full_numbers:{fnInit:function(g,l,s){var t=p.createElement("span"),w=p.createElement("span"),y=p.createElement("span"),F=p.createElement("span"),x=p.createElement("span");t.innerHTML=g.oLanguage.oPaginate.sFirst;w.innerHTML=g.oLanguage.oPaginate.sPrevious;F.innerHTML=g.oLanguage.oPaginate.sNext;x.innerHTML=g.oLanguage.oPaginate.sLast;var v=g.oClasses;t.className=v.sPageButton+" "+v.sPageFirst;w.className=v.sPageButton+" "+v.sPagePrevious;F.className=
-v.sPageButton+" "+v.sPageNext;x.className=v.sPageButton+" "+v.sPageLast;l.appendChild(t);l.appendChild(w);l.appendChild(y);l.appendChild(F);l.appendChild(x);i(t).bind("click.DT",function(){g.oApi._fnPageChange(g,"first")&&s(g)});i(w).bind("click.DT",function(){g.oApi._fnPageChange(g,"previous")&&s(g)});i(F).bind("click.DT",function(){g.oApi._fnPageChange(g,"next")&&s(g)});i(x).bind("click.DT",function(){g.oApi._fnPageChange(g,"last")&&s(g)});i("span",l).bind("mousedown.DT",function(){return false}).bind("selectstart.DT",
-function(){return false});if(g.sTableId!==""&&typeof g.aanFeatures.p=="undefined"){l.setAttribute("id",g.sTableId+"_paginate");t.setAttribute("id",g.sTableId+"_first");w.setAttribute("id",g.sTableId+"_previous");F.setAttribute("id",g.sTableId+"_next");x.setAttribute("id",g.sTableId+"_last")}},fnUpdate:function(g,l){if(g.aanFeatures.p){var s=n.oPagination.iFullNumbersShowPages,t=Math.floor(s/2),w=Math.ceil(g.fnRecordsDisplay()/g._iDisplayLength),y=Math.ceil(g._iDisplayStart/g._iDisplayLength)+1,F=
-"",x,v=g.oClasses;if(w<s){t=1;x=w}else if(y<=t){t=1;x=s}else if(y>=w-t){t=w-s+1;x=w}else{t=y-Math.ceil(s/2)+1;x=t+s-1}for(s=t;s<=x;s++)F+=y!=s?'<span class="'+v.sPageButton+'">'+s+"</span>":'<span class="'+v.sPageButtonActive+'">'+s+"</span>";x=g.aanFeatures.p;var z,$=function(M){g._iDisplayStart=(this.innerHTML*1-1)*g._iDisplayLength;l(g);M.preventDefault()},X=function(){return false};s=0;for(t=x.length;s<t;s++)if(x[s].childNodes.length!==0){z=i("span:eq(2)",x[s]);z.html(F);i("span",z).bind("click.DT",
-$).bind("mousedown.DT",X).bind("selectstart.DT",X);z=x[s].getElementsByTagName("span");z=[z[0],z[1],z[z.length-2],z[z.length-1]];i(z).removeClass(v.sPageButton+" "+v.sPageButtonActive+" "+v.sPageButtonStaticDisabled);if(y==1){z[0].className+=" "+v.sPageButtonStaticDisabled;z[1].className+=" "+v.sPageButtonStaticDisabled}else{z[0].className+=" "+v.sPageButton;z[1].className+=" "+v.sPageButton}if(w===0||y==w||g._iDisplayLength==-1){z[2].className+=" "+v.sPageButtonStaticDisabled;z[3].className+=" "+
-v.sPageButtonStaticDisabled}else{z[2].className+=" "+v.sPageButton;z[3].className+=" "+v.sPageButton}}}}}};n.oSort={"string-asc":function(g,l){if(typeof g!="string")g="";if(typeof l!="string")l="";g=g.toLowerCase();l=l.toLowerCase();return g<l?-1:g>l?1:0},"string-desc":function(g,l){if(typeof g!="string")g="";if(typeof l!="string")l="";g=g.toLowerCase();l=l.toLowerCase();return g<l?1:g>l?-1:0},"html-asc":function(g,l){g=g.replace(/<.*?>/g,"").toLowerCase();l=l.replace(/<.*?>/g,"").toLowerCase();return g<
-l?-1:g>l?1:0},"html-desc":function(g,l){g=g.replace(/<.*?>/g,"").toLowerCase();l=l.replace(/<.*?>/g,"").toLowerCase();return g<l?1:g>l?-1:0},"date-asc":function(g,l){g=Date.parse(g);l=Date.parse(l);if(isNaN(g)||g==="")g=Date.parse("01/01/1970 00:00:00");if(isNaN(l)||l==="")l=Date.parse("01/01/1970 00:00:00");return g-l},"date-desc":function(g,l){g=Date.parse(g);l=Date.parse(l);if(isNaN(g)||g==="")g=Date.parse("01/01/1970 00:00:00");if(isNaN(l)||l==="")l=Date.parse("01/01/1970 00:00:00");return l-
-g},"numeric-asc":function(g,l){return(g=="-"||g===""?0:g*1)-(l=="-"||l===""?0:l*1)},"numeric-desc":function(g,l){return(l=="-"||l===""?0:l*1)-(g=="-"||g===""?0:g*1)}};n.aTypes=[function(g){if(typeof g=="number")return"numeric";else if(typeof g!="string")return null;var l,s=false;l=g.charAt(0);if("0123456789-".indexOf(l)==-1)return null;for(var t=1;t<g.length;t++){l=g.charAt(t);if("0123456789.".indexOf(l)==-1)return null;if(l=="."){if(s)return null;s=true}}return"numeric"},function(g){var l=Date.parse(g);
-if(l!==null&&!isNaN(l)||typeof g=="string"&&g.length===0)return"date";return null},function(g){if(typeof g=="string"&&g.indexOf("<")!=-1&&g.indexOf(">")!=-1)return"html";return null}];n.fnVersionCheck=function(g){var l=function(x,v){for(;x.length<v;)x+="0";return x},s=n.sVersion.split(".");g=g.split(".");for(var t="",w="",y=0,F=g.length;y<F;y++){t+=l(s[y],3);w+=l(g[y],3)}return parseInt(t,10)>=parseInt(w,10)};n._oExternConfig={iNextUnique:0};i.fn.dataTable=function(g){function l(){this.fnRecordsTotal=
-function(){return this.oFeatures.bServerSide?parseInt(this._iRecordsTotal,10):this.aiDisplayMaster.length};this.fnRecordsDisplay=function(){return this.oFeatures.bServerSide?parseInt(this._iRecordsDisplay,10):this.aiDisplay.length};this.fnDisplayEnd=function(){return this.oFeatures.bServerSide?this.oFeatures.bPaginate===false||this._iDisplayLength==-1?this._iDisplayStart+this.aiDisplay.length:Math.min(this._iDisplayStart+this._iDisplayLength,this._iRecordsDisplay):this._iDisplayEnd};this.sInstance=
-this.oInstance=null;this.oFeatures={bPaginate:true,bLengthChange:true,bFilter:true,bSort:true,bInfo:true,bAutoWidth:true,bProcessing:false,bSortClasses:true,bStateSave:false,bServerSide:false,bDeferRender:false};this.oScroll={sX:"",sXInner:"",sY:"",bCollapse:false,bInfinite:false,iLoadGap:100,iBarWidth:0,bAutoCss:true};this.aanFeatures=[];this.oLanguage={sProcessing:"Processing...",sLengthMenu:"Show _MENU_ entries",sZeroRecords:"No matching records found",sEmptyTable:"No data available in table",
-sLoadingRecords:"Loading...",sInfo:"Showing _START_ to _END_ of _TOTAL_ entries",sInfoEmpty:"Showing 0 to 0 of 0 entries",sInfoFiltered:"(filtered from _MAX_ total entries)",sInfoPostFix:"",sInfoThousands:",",sSearch:"Search:",sUrl:"",oPaginate:{sFirst:"First",sPrevious:"Previous",sNext:"Next",sLast:"Last"},fnInfoCallback:null};this.aoData=[];this.aiDisplay=[];this.aiDisplayMaster=[];this.aoColumns=[];this.aoHeader=[];this.aoFooter=[];this.iNextId=0;this.asDataSearch=[];this.oPreviousSearch={sSearch:"",
-bRegex:false,bSmart:true};this.aoPreSearchCols=[];this.aaSorting=[[0,"asc",0]];this.aaSortingFixed=null;this.asStripeClasses=[];this.asDestroyStripes=[];this.sDestroyWidth=0;this.fnFooterCallback=this.fnHeaderCallback=this.fnRowCallback=null;this.aoDrawCallback=[];this.fnInitComplete=this.fnPreDrawCallback=null;this.sTableId="";this.nTableWrapper=this.nTBody=this.nTFoot=this.nTHead=this.nTable=null;this.bInitialised=this.bDeferLoading=false;this.aoOpenRows=[];this.sDom="lfrtip";this.sPaginationType=
-"two_button";this.iCookieDuration=7200;this.sCookiePrefix="SpryMedia_DataTables_";this.fnCookieCallback=null;this.aoStateSave=[];this.aoStateLoad=[];this.sAjaxSource=this.oLoadedState=null;this.sAjaxDataProp="aaData";this.bAjaxDataGet=true;this.jqXHR=null;this.fnServerData=function(a,b,c,d){d.jqXHR=i.ajax({url:a,data:b,success:function(f){i(d.oInstance).trigger("xhr",d);c(f)},dataType:"json",cache:false,error:function(f,e){e=="parsererror"&&alert("DataTables warning: JSON data from server could not be parsed. This is caused by a JSON formatting error.")}})};
-this.aoServerParams=[];this.fnFormatNumber=function(a){if(a<1E3)return a;else{var b=a+"";a=b.split("");var c="";b=b.length;for(var d=0;d<b;d++){if(d%3===0&&d!==0)c=this.oLanguage.sInfoThousands+c;c=a[b-d-1]+c}}return c};this.aLengthMenu=[10,25,50,100];this.bDrawing=this.iDraw=0;this.iDrawError=-1;this._iDisplayLength=10;this._iDisplayStart=0;this._iDisplayEnd=10;this._iRecordsDisplay=this._iRecordsTotal=0;this.bJUI=false;this.oClasses=n.oStdClasses;this.bSortCellsTop=this.bSorted=this.bFiltered=false;
-this.oInit=null;this.aoDestroyCallback=[]}function s(a){return function(){var b=[A(this[n.iApiIndex])].concat(Array.prototype.slice.call(arguments));return n.oApi[a].apply(this,b)}}function t(a){var b,c,d=a.iInitDisplayStart;if(a.bInitialised===false)setTimeout(function(){t(a)},200);else{Aa(a);X(a);M(a,a.aoHeader);a.nTFoot&&M(a,a.aoFooter);K(a,true);a.oFeatures.bAutoWidth&&ga(a);b=0;for(c=a.aoColumns.length;b<c;b++)if(a.aoColumns[b].sWidth!==null)a.aoColumns[b].nTh.style.width=q(a.aoColumns[b].sWidth);
-if(a.oFeatures.bSort)R(a);else if(a.oFeatures.bFilter)N(a,a.oPreviousSearch);else{a.aiDisplay=a.aiDisplayMaster.slice();E(a);C(a)}if(a.sAjaxSource!==null&&!a.oFeatures.bServerSide){c=[];ha(a,c);a.fnServerData.call(a.oInstance,a.sAjaxSource,c,function(f){var e=f;if(a.sAjaxDataProp!=="")e=aa(a.sAjaxDataProp)(f);for(b=0;b<e.length;b++)v(a,e[b]);a.iInitDisplayStart=d;if(a.oFeatures.bSort)R(a);else{a.aiDisplay=a.aiDisplayMaster.slice();E(a);C(a)}K(a,false);w(a,f)},a)}else if(!a.oFeatures.bServerSide){K(a,
-false);w(a)}}}function w(a,b){a._bInitComplete=true;if(typeof a.fnInitComplete=="function")typeof b!="undefined"?a.fnInitComplete.call(a.oInstance,a,b):a.fnInitComplete.call(a.oInstance,a)}function y(a,b,c){a.oLanguage=i.extend(true,a.oLanguage,b);typeof b.sEmptyTable=="undefined"&&typeof b.sZeroRecords!="undefined"&&o(a.oLanguage,b,"sZeroRecords","sEmptyTable");typeof b.sLoadingRecords=="undefined"&&typeof b.sZeroRecords!="undefined"&&o(a.oLanguage,b,"sZeroRecords","sLoadingRecords");c&&t(a)}function F(a,
-b){var c=a.aoColumns.length;b={sType:null,_bAutoType:true,bVisible:true,bSearchable:true,bSortable:true,asSorting:["asc","desc"],sSortingClass:a.oClasses.sSortable,sSortingClassJUI:a.oClasses.sSortJUI,sTitle:b?b.innerHTML:"",sName:"",sWidth:null,sWidthOrig:null,sClass:null,fnRender:null,bUseRendered:true,iDataSort:c,mDataProp:c,fnGetData:null,fnSetData:null,sSortDataType:"std",sDefaultContent:null,sContentPadding:"",nTh:b?b:p.createElement("th"),nTf:null};a.aoColumns.push(b);if(typeof a.aoPreSearchCols[c]==
-"undefined"||a.aoPreSearchCols[c]===null)a.aoPreSearchCols[c]={sSearch:"",bRegex:false,bSmart:true};else{if(typeof a.aoPreSearchCols[c].bRegex=="undefined")a.aoPreSearchCols[c].bRegex=true;if(typeof a.aoPreSearchCols[c].bSmart=="undefined")a.aoPreSearchCols[c].bSmart=true}x(a,c,null)}function x(a,b,c){b=a.aoColumns[b];if(typeof c!="undefined"&&c!==null){if(typeof c.sType!="undefined"){b.sType=c.sType;b._bAutoType=false}o(b,c,"bVisible");o(b,c,"bSearchable");o(b,c,"bSortable");o(b,c,"sTitle");o(b,
-c,"sName");o(b,c,"sWidth");o(b,c,"sWidth","sWidthOrig");o(b,c,"sClass");o(b,c,"fnRender");o(b,c,"bUseRendered");o(b,c,"iDataSort");o(b,c,"mDataProp");o(b,c,"asSorting");o(b,c,"sSortDataType");o(b,c,"sDefaultContent");o(b,c,"sContentPadding")}b.fnGetData=aa(b.mDataProp);b.fnSetData=Ba(b.mDataProp);if(!a.oFeatures.bSort)b.bSortable=false;if(!b.bSortable||i.inArray("asc",b.asSorting)==-1&&i.inArray("desc",b.asSorting)==-1){b.sSortingClass=a.oClasses.sSortableNone;b.sSortingClassJUI=""}else if(b.bSortable||
-i.inArray("asc",b.asSorting)==-1&&i.inArray("desc",b.asSorting)==-1){b.sSortingClass=a.oClasses.sSortable;b.sSortingClassJUI=a.oClasses.sSortJUI}else if(i.inArray("asc",b.asSorting)!=-1&&i.inArray("desc",b.asSorting)==-1){b.sSortingClass=a.oClasses.sSortableAsc;b.sSortingClassJUI=a.oClasses.sSortJUIAscAllowed}else if(i.inArray("asc",b.asSorting)==-1&&i.inArray("desc",b.asSorting)!=-1){b.sSortingClass=a.oClasses.sSortableDesc;b.sSortingClassJUI=a.oClasses.sSortJUIDescAllowed}}function v(a,b){var c;
-c=i.isArray(b)?b.slice():i.extend(true,{},b);b=a.aoData.length;var d={nTr:null,_iId:a.iNextId++,_aData:c,_anHidden:[],_sRowStripe:""};a.aoData.push(d);for(var f,e=0,h=a.aoColumns.length;e<h;e++){c=a.aoColumns[e];typeof c.fnRender=="function"&&c.bUseRendered&&c.mDataProp!==null&&O(a,b,e,c.fnRender({iDataRow:b,iDataColumn:e,aData:d._aData,oSettings:a}));if(c._bAutoType&&c.sType!="string"){f=G(a,b,e,"type");if(f!==null&&f!==""){f=ia(f);if(c.sType===null)c.sType=f;else if(c.sType!=f&&c.sType!="html")c.sType=
-"string"}}}a.aiDisplayMaster.push(b);a.oFeatures.bDeferRender||z(a,b);return b}function z(a,b){var c=a.aoData[b],d;if(c.nTr===null){c.nTr=p.createElement("tr");typeof c._aData.DT_RowId!="undefined"&&c.nTr.setAttribute("id",c._aData.DT_RowId);typeof c._aData.DT_RowClass!="undefined"&&i(c.nTr).addClass(c._aData.DT_RowClass);for(var f=0,e=a.aoColumns.length;f<e;f++){var h=a.aoColumns[f];d=p.createElement("td");d.innerHTML=typeof h.fnRender=="function"&&(!h.bUseRendered||h.mDataProp===null)?h.fnRender({iDataRow:b,
-iDataColumn:f,aData:c._aData,oSettings:a}):G(a,b,f,"display");if(h.sClass!==null)d.className=h.sClass;if(h.bVisible){c.nTr.appendChild(d);c._anHidden[f]=null}else c._anHidden[f]=d}}}function $(a){var b,c,d,f,e,h,j,k,m;if(a.bDeferLoading||a.sAjaxSource===null){j=a.nTBody.childNodes;b=0;for(c=j.length;b<c;b++)if(j[b].nodeName.toUpperCase()=="TR"){k=a.aoData.length;a.aoData.push({nTr:j[b],_iId:a.iNextId++,_aData:[],_anHidden:[],_sRowStripe:""});a.aiDisplayMaster.push(k);h=j[b].childNodes;d=e=0;for(f=
-h.length;d<f;d++){m=h[d].nodeName.toUpperCase();if(m=="TD"||m=="TH"){O(a,k,e,i.trim(h[d].innerHTML));e++}}}}j=ba(a);h=[];b=0;for(c=j.length;b<c;b++){d=0;for(f=j[b].childNodes.length;d<f;d++){e=j[b].childNodes[d];m=e.nodeName.toUpperCase();if(m=="TD"||m=="TH")h.push(e)}}h.length!=j.length*a.aoColumns.length&&J(a,1,"Unexpected number of TD elements. Expected "+j.length*a.aoColumns.length+" and got "+h.length+". DataTables does not support rowspan / colspan in the table body, and there must be one cell for each row/column combination.");
-d=0;for(f=a.aoColumns.length;d<f;d++){if(a.aoColumns[d].sTitle===null)a.aoColumns[d].sTitle=a.aoColumns[d].nTh.innerHTML;j=a.aoColumns[d]._bAutoType;m=typeof a.aoColumns[d].fnRender=="function";e=a.aoColumns[d].sClass!==null;k=a.aoColumns[d].bVisible;var u,r;if(j||m||e||!k){b=0;for(c=a.aoData.length;b<c;b++){u=h[b*f+d];if(j&&a.aoColumns[d].sType!="string"){r=G(a,b,d,"type");if(r!==""){r=ia(r);if(a.aoColumns[d].sType===null)a.aoColumns[d].sType=r;else if(a.aoColumns[d].sType!=r&&a.aoColumns[d].sType!=
-"html")a.aoColumns[d].sType="string"}}if(m){r=a.aoColumns[d].fnRender({iDataRow:b,iDataColumn:d,aData:a.aoData[b]._aData,oSettings:a});u.innerHTML=r;a.aoColumns[d].bUseRendered&&O(a,b,d,r)}if(e)u.className+=" "+a.aoColumns[d].sClass;if(k)a.aoData[b]._anHidden[d]=null;else{a.aoData[b]._anHidden[d]=u;u.parentNode.removeChild(u)}}}}}function X(a){var b,c,d;a.nTHead.getElementsByTagName("tr");if(a.nTHead.getElementsByTagName("th").length!==0){b=0;for(d=a.aoColumns.length;b<d;b++){c=a.aoColumns[b].nTh;
-a.aoColumns[b].sClass!==null&&i(c).addClass(a.aoColumns[b].sClass);if(a.aoColumns[b].sTitle!=c.innerHTML)c.innerHTML=a.aoColumns[b].sTitle}}else{var f=p.createElement("tr");b=0;for(d=a.aoColumns.length;b<d;b++){c=a.aoColumns[b].nTh;c.innerHTML=a.aoColumns[b].sTitle;a.aoColumns[b].sClass!==null&&i(c).addClass(a.aoColumns[b].sClass);f.appendChild(c)}i(a.nTHead).html("")[0].appendChild(f);Y(a.aoHeader,a.nTHead)}if(a.bJUI){b=0;for(d=a.aoColumns.length;b<d;b++){c=a.aoColumns[b].nTh;f=p.createElement("div");
-f.className=a.oClasses.sSortJUIWrapper;i(c).contents().appendTo(f);var e=p.createElement("span");e.className=a.oClasses.sSortIcon;f.appendChild(e);c.appendChild(f)}}d=function(){this.onselectstart=function(){return false};return false};if(a.oFeatures.bSort)for(b=0;b<a.aoColumns.length;b++)if(a.aoColumns[b].bSortable!==false){ja(a,a.aoColumns[b].nTh,b);i(a.aoColumns[b].nTh).bind("mousedown.DT",d)}else i(a.aoColumns[b].nTh).addClass(a.oClasses.sSortableNone);a.oClasses.sFooterTH!==""&&i(a.nTFoot).children("tr").children("th").addClass(a.oClasses.sFooterTH);
-if(a.nTFoot!==null){c=S(a,null,a.aoFooter);b=0;for(d=a.aoColumns.length;b<d;b++)if(typeof c[b]!="undefined")a.aoColumns[b].nTf=c[b]}}function M(a,b,c){var d,f,e,h=[],j=[],k=a.aoColumns.length;if(typeof c=="undefined")c=false;d=0;for(f=b.length;d<f;d++){h[d]=b[d].slice();h[d].nTr=b[d].nTr;for(e=k-1;e>=0;e--)!a.aoColumns[e].bVisible&&!c&&h[d].splice(e,1);j.push([])}d=0;for(f=h.length;d<f;d++){if(h[d].nTr){a=0;for(e=h[d].nTr.childNodes.length;a<e;a++)h[d].nTr.removeChild(h[d].nTr.childNodes[0])}e=0;
-for(b=h[d].length;e<b;e++){k=c=1;if(typeof j[d][e]=="undefined"){h[d].nTr.appendChild(h[d][e].cell);for(j[d][e]=1;typeof h[d+c]!="undefined"&&h[d][e].cell==h[d+c][e].cell;){j[d+c][e]=1;c++}for(;typeof h[d][e+k]!="undefined"&&h[d][e].cell==h[d][e+k].cell;){for(a=0;a<c;a++)j[d+a][e+k]=1;k++}h[d][e].cell.rowSpan=c;h[d][e].cell.colSpan=k}}}}function C(a){var b,c,d=[],f=0,e=false;b=a.asStripeClasses.length;c=a.aoOpenRows.length;if(!(a.fnPreDrawCallback!==null&&a.fnPreDrawCallback.call(a.oInstance,a)===
-false)){a.bDrawing=true;if(typeof a.iInitDisplayStart!="undefined"&&a.iInitDisplayStart!=-1){a._iDisplayStart=a.oFeatures.bServerSide?a.iInitDisplayStart:a.iInitDisplayStart>=a.fnRecordsDisplay()?0:a.iInitDisplayStart;a.iInitDisplayStart=-1;E(a)}if(a.bDeferLoading){a.bDeferLoading=false;a.iDraw++}else if(a.oFeatures.bServerSide){if(!a.bDestroying&&!Ca(a))return}else a.iDraw++;if(a.aiDisplay.length!==0){var h=a._iDisplayStart,j=a._iDisplayEnd;if(a.oFeatures.bServerSide){h=0;j=a.aoData.length}for(h=
-h;h<j;h++){var k=a.aoData[a.aiDisplay[h]];k.nTr===null&&z(a,a.aiDisplay[h]);var m=k.nTr;if(b!==0){var u=a.asStripeClasses[f%b];if(k._sRowStripe!=u){i(m).removeClass(k._sRowStripe).addClass(u);k._sRowStripe=u}}if(typeof a.fnRowCallback=="function"){m=a.fnRowCallback.call(a.oInstance,m,a.aoData[a.aiDisplay[h]]._aData,f,h);if(!m&&!e){J(a,0,"A node was not returned by fnRowCallback");e=true}}d.push(m);f++;if(c!==0)for(k=0;k<c;k++)m==a.aoOpenRows[k].nParent&&d.push(a.aoOpenRows[k].nTr)}}else{d[0]=p.createElement("tr");
-if(typeof a.asStripeClasses[0]!="undefined")d[0].className=a.asStripeClasses[0];e=a.oLanguage.sZeroRecords.replace("_MAX_",a.fnFormatNumber(a.fnRecordsTotal()));if(a.iDraw==1&&a.sAjaxSource!==null&&!a.oFeatures.bServerSide)e=a.oLanguage.sLoadingRecords;else if(typeof a.oLanguage.sEmptyTable!="undefined"&&a.fnRecordsTotal()===0)e=a.oLanguage.sEmptyTable;b=p.createElement("td");b.setAttribute("valign","top");b.colSpan=Z(a);b.className=a.oClasses.sRowEmpty;b.innerHTML=e;d[f].appendChild(b)}typeof a.fnHeaderCallback==
-"function"&&a.fnHeaderCallback.call(a.oInstance,i(a.nTHead).children("tr")[0],ca(a),a._iDisplayStart,a.fnDisplayEnd(),a.aiDisplay);typeof a.fnFooterCallback=="function"&&a.fnFooterCallback.call(a.oInstance,i(a.nTFoot).children("tr")[0],ca(a),a._iDisplayStart,a.fnDisplayEnd(),a.aiDisplay);f=p.createDocumentFragment();b=p.createDocumentFragment();if(a.nTBody){e=a.nTBody.parentNode;b.appendChild(a.nTBody);if(!a.oScroll.bInfinite||!a._bInitComplete||a.bSorted||a.bFiltered){c=a.nTBody.childNodes;for(b=
-c.length-1;b>=0;b--)c[b].parentNode.removeChild(c[b])}b=0;for(c=d.length;b<c;b++)f.appendChild(d[b]);a.nTBody.appendChild(f);e!==null&&e.appendChild(a.nTBody)}for(b=a.aoDrawCallback.length-1;b>=0;b--)a.aoDrawCallback[b].fn.call(a.oInstance,a);i(a.oInstance).trigger("draw",a);a.bSorted=false;a.bFiltered=false;a.bDrawing=false;if(a.oFeatures.bServerSide){K(a,false);typeof a._bInitComplete=="undefined"&&w(a)}}}function da(a){if(a.oFeatures.bSort)R(a,a.oPreviousSearch);else if(a.oFeatures.bFilter)N(a,
-a.oPreviousSearch);else{E(a);C(a)}}function Ca(a){if(a.bAjaxDataGet){a.iDraw++;K(a,true);var b=Da(a);ha(a,b);a.fnServerData.call(a.oInstance,a.sAjaxSource,b,function(c){Ea(a,c)},a);return false}else return true}function Da(a){var b=a.aoColumns.length,c=[],d,f;c.push({name:"sEcho",value:a.iDraw});c.push({name:"iColumns",value:b});c.push({name:"sColumns",value:ka(a)});c.push({name:"iDisplayStart",value:a._iDisplayStart});c.push({name:"iDisplayLength",value:a.oFeatures.bPaginate!==false?a._iDisplayLength:
--1});for(f=0;f<b;f++){d=a.aoColumns[f].mDataProp;c.push({name:"mDataProp_"+f,value:typeof d=="function"?"function":d})}if(a.oFeatures.bFilter!==false){c.push({name:"sSearch",value:a.oPreviousSearch.sSearch});c.push({name:"bRegex",value:a.oPreviousSearch.bRegex});for(f=0;f<b;f++){c.push({name:"sSearch_"+f,value:a.aoPreSearchCols[f].sSearch});c.push({name:"bRegex_"+f,value:a.aoPreSearchCols[f].bRegex});c.push({name:"bSearchable_"+f,value:a.aoColumns[f].bSearchable})}}if(a.oFeatures.bSort!==false){d=
-a.aaSortingFixed!==null?a.aaSortingFixed.length:0;var e=a.aaSorting.length;c.push({name:"iSortingCols",value:d+e});for(f=0;f<d;f++){c.push({name:"iSortCol_"+f,value:a.aaSortingFixed[f][0]});c.push({name:"sSortDir_"+f,value:a.aaSortingFixed[f][1]})}for(f=0;f<e;f++){c.push({name:"iSortCol_"+(f+d),value:a.aaSorting[f][0]});c.push({name:"sSortDir_"+(f+d),value:a.aaSorting[f][1]})}for(f=0;f<b;f++)c.push({name:"bSortable_"+f,value:a.aoColumns[f].bSortable})}return c}function ha(a,b){for(var c=0,d=a.aoServerParams.length;c<
-d;c++)a.aoServerParams[c].fn.call(a.oInstance,b)}function Ea(a,b){if(typeof b.sEcho!="undefined")if(b.sEcho*1<a.iDraw)return;else a.iDraw=b.sEcho*1;if(!a.oScroll.bInfinite||a.oScroll.bInfinite&&(a.bSorted||a.bFiltered))la(a);a._iRecordsTotal=b.iTotalRecords;a._iRecordsDisplay=b.iTotalDisplayRecords;var c=ka(a);if(c=typeof b.sColumns!="undefined"&&c!==""&&b.sColumns!=c)var d=Fa(a,b.sColumns);b=aa(a.sAjaxDataProp)(b);for(var f=0,e=b.length;f<e;f++)if(c){for(var h=[],j=0,k=a.aoColumns.length;j<k;j++)h.push(b[f][d[j]]);
-v(a,h)}else v(a,b[f]);a.aiDisplay=a.aiDisplayMaster.slice();a.bAjaxDataGet=false;C(a);a.bAjaxDataGet=true;K(a,false)}function Aa(a){var b=p.createElement("div");a.nTable.parentNode.insertBefore(b,a.nTable);a.nTableWrapper=p.createElement("div");a.nTableWrapper.className=a.oClasses.sWrapper;a.sTableId!==""&&a.nTableWrapper.setAttribute("id",a.sTableId+"_wrapper");a.nTableReinsertBefore=a.nTable.nextSibling;for(var c=a.nTableWrapper,d=a.sDom.split(""),f,e,h,j,k,m,u,r=0;r<d.length;r++){e=0;h=d[r];if(h==
-"<"){j=p.createElement("div");k=d[r+1];if(k=="'"||k=='"'){m="";for(u=2;d[r+u]!=k;){m+=d[r+u];u++}if(m=="H")m="fg-toolbar ui-toolbar ui-widget-header ui-corner-tl ui-corner-tr ui-helper-clearfix";else if(m=="F")m="fg-toolbar ui-toolbar ui-widget-header ui-corner-bl ui-corner-br ui-helper-clearfix";if(m.indexOf(".")!=-1){k=m.split(".");j.setAttribute("id",k[0].substr(1,k[0].length-1));j.className=k[1]}else if(m.charAt(0)=="#")j.setAttribute("id",m.substr(1,m.length-1));else j.className=m;r+=u}c.appendChild(j);
-c=j}else if(h==">")c=c.parentNode;else if(h=="l"&&a.oFeatures.bPaginate&&a.oFeatures.bLengthChange){f=Ga(a);e=1}else if(h=="f"&&a.oFeatures.bFilter){f=Ha(a);e=1}else if(h=="r"&&a.oFeatures.bProcessing){f=Ia(a);e=1}else if(h=="t"){f=Ja(a);e=1}else if(h=="i"&&a.oFeatures.bInfo){f=Ka(a);e=1}else if(h=="p"&&a.oFeatures.bPaginate){f=La(a);e=1}else if(n.aoFeatures.length!==0){j=n.aoFeatures;u=0;for(k=j.length;u<k;u++)if(h==j[u].cFeature){if(f=j[u].fnInit(a))e=1;break}}if(e==1&&f!==null){if(typeof a.aanFeatures[h]!=
-"object")a.aanFeatures[h]=[];a.aanFeatures[h].push(f);c.appendChild(f)}}b.parentNode.replaceChild(a.nTableWrapper,b)}function Ja(a){if(a.oScroll.sX===""&&a.oScroll.sY==="")return a.nTable;var b=p.createElement("div"),c=p.createElement("div"),d=p.createElement("div"),f=p.createElement("div"),e=p.createElement("div"),h=p.createElement("div"),j=a.nTable.cloneNode(false),k=a.nTable.cloneNode(false),m=a.nTable.getElementsByTagName("thead")[0],u=a.nTable.getElementsByTagName("tfoot").length===0?null:a.nTable.getElementsByTagName("tfoot")[0],
-r=typeof g.bJQueryUI!="undefined"&&g.bJQueryUI?n.oJUIClasses:n.oStdClasses;c.appendChild(d);e.appendChild(h);f.appendChild(a.nTable);b.appendChild(c);b.appendChild(f);d.appendChild(j);j.appendChild(m);if(u!==null){b.appendChild(e);h.appendChild(k);k.appendChild(u)}b.className=r.sScrollWrapper;c.className=r.sScrollHead;d.className=r.sScrollHeadInner;f.className=r.sScrollBody;e.className=r.sScrollFoot;h.className=r.sScrollFootInner;if(a.oScroll.bAutoCss){c.style.overflow="hidden";c.style.position="relative";
-e.style.overflow="hidden";f.style.overflow="auto"}c.style.border="0";c.style.width="100%";e.style.border="0";d.style.width="150%";j.removeAttribute("id");j.style.marginLeft="0";a.nTable.style.marginLeft="0";if(u!==null){k.removeAttribute("id");k.style.marginLeft="0"}d=i(a.nTable).children("caption");h=0;for(k=d.length;h<k;h++)j.appendChild(d[h]);if(a.oScroll.sX!==""){c.style.width=q(a.oScroll.sX);f.style.width=q(a.oScroll.sX);if(u!==null)e.style.width=q(a.oScroll.sX);i(f).scroll(function(){c.scrollLeft=
-this.scrollLeft;if(u!==null)e.scrollLeft=this.scrollLeft})}if(a.oScroll.sY!=="")f.style.height=q(a.oScroll.sY);a.aoDrawCallback.push({fn:Ma,sName:"scrolling"});a.oScroll.bInfinite&&i(f).scroll(function(){if(!a.bDrawing)if(i(this).scrollTop()+i(this).height()>i(a.nTable).height()-a.oScroll.iLoadGap)if(a.fnDisplayEnd()<a.fnRecordsDisplay()){ma(a,"next");E(a);C(a)}});a.nScrollHead=c;a.nScrollFoot=e;return b}function Ma(a){var b=a.nScrollHead.getElementsByTagName("div")[0],c=b.getElementsByTagName("table")[0],
-d=a.nTable.parentNode,f,e,h,j,k,m,u,r,H=[],L=a.nTFoot!==null?a.nScrollFoot.getElementsByTagName("div")[0]:null,T=a.nTFoot!==null?L.getElementsByTagName("table")[0]:null,B=i.browser.msie&&i.browser.version<=7;h=a.nTable.getElementsByTagName("thead");h.length>0&&a.nTable.removeChild(h[0]);if(a.nTFoot!==null){k=a.nTable.getElementsByTagName("tfoot");k.length>0&&a.nTable.removeChild(k[0])}h=a.nTHead.cloneNode(true);a.nTable.insertBefore(h,a.nTable.childNodes[0]);if(a.nTFoot!==null){k=a.nTFoot.cloneNode(true);
-a.nTable.insertBefore(k,a.nTable.childNodes[1])}if(a.oScroll.sX===""){d.style.width="100%";b.parentNode.style.width="100%"}var U=S(a,h);f=0;for(e=U.length;f<e;f++){u=Na(a,f);U[f].style.width=a.aoColumns[u].sWidth}a.nTFoot!==null&&P(function(I){I.style.width=""},k.getElementsByTagName("tr"));f=i(a.nTable).outerWidth();if(a.oScroll.sX===""){a.nTable.style.width="100%";if(B&&(d.scrollHeight>d.offsetHeight||i(d).css("overflow-y")=="scroll"))a.nTable.style.width=q(i(a.nTable).outerWidth()-a.oScroll.iBarWidth)}else if(a.oScroll.sXInner!==
-"")a.nTable.style.width=q(a.oScroll.sXInner);else if(f==i(d).width()&&i(d).height()<i(a.nTable).height()){a.nTable.style.width=q(f-a.oScroll.iBarWidth);if(i(a.nTable).outerWidth()>f-a.oScroll.iBarWidth)a.nTable.style.width=q(f)}else a.nTable.style.width=q(f);f=i(a.nTable).outerWidth();e=a.nTHead.getElementsByTagName("tr");h=h.getElementsByTagName("tr");P(function(I,na){m=I.style;m.paddingTop="0";m.paddingBottom="0";m.borderTopWidth="0";m.borderBottomWidth="0";m.height=0;r=i(I).width();na.style.width=
-q(r);H.push(r)},h,e);i(h).height(0);if(a.nTFoot!==null){j=k.getElementsByTagName("tr");k=a.nTFoot.getElementsByTagName("tr");P(function(I,na){m=I.style;m.paddingTop="0";m.paddingBottom="0";m.borderTopWidth="0";m.borderBottomWidth="0";m.height=0;r=i(I).width();na.style.width=q(r);H.push(r)},j,k);i(j).height(0)}P(function(I){I.innerHTML="";I.style.width=q(H.shift())},h);a.nTFoot!==null&&P(function(I){I.innerHTML="";I.style.width=q(H.shift())},j);if(i(a.nTable).outerWidth()<f){j=d.scrollHeight>d.offsetHeight||
-i(d).css("overflow-y")=="scroll"?f+a.oScroll.iBarWidth:f;if(B&&(d.scrollHeight>d.offsetHeight||i(d).css("overflow-y")=="scroll"))a.nTable.style.width=q(j-a.oScroll.iBarWidth);d.style.width=q(j);b.parentNode.style.width=q(j);if(a.nTFoot!==null)L.parentNode.style.width=q(j);if(a.oScroll.sX==="")J(a,1,"The table cannot fit into the current element which will cause column misalignment. The table has been drawn at its minimum possible width.");else a.oScroll.sXInner!==""&&J(a,1,"The table cannot fit into the current element which will cause column misalignment. Increase the sScrollXInner value or remove it to allow automatic calculation")}else{d.style.width=
-q("100%");b.parentNode.style.width=q("100%");if(a.nTFoot!==null)L.parentNode.style.width=q("100%")}if(a.oScroll.sY==="")if(B)d.style.height=q(a.nTable.offsetHeight+a.oScroll.iBarWidth);if(a.oScroll.sY!==""&&a.oScroll.bCollapse){d.style.height=q(a.oScroll.sY);B=a.oScroll.sX!==""&&a.nTable.offsetWidth>d.offsetWidth?a.oScroll.iBarWidth:0;if(a.nTable.offsetHeight<d.offsetHeight)d.style.height=q(i(a.nTable).height()+B)}B=i(a.nTable).outerWidth();c.style.width=q(B);b.style.width=q(B+a.oScroll.iBarWidth);
-if(a.nTFoot!==null){L.style.width=q(a.nTable.offsetWidth+a.oScroll.iBarWidth);T.style.width=q(a.nTable.offsetWidth)}if(a.bSorted||a.bFiltered)d.scrollTop=0}function ea(a){if(a.oFeatures.bAutoWidth===false)return false;ga(a);for(var b=0,c=a.aoColumns.length;b<c;b++)a.aoColumns[b].nTh.style.width=a.aoColumns[b].sWidth}function Ha(a){var b=a.oLanguage.sSearch;b=b.indexOf("_INPUT_")!==-1?b.replace("_INPUT_",'<input type="text" />'):b===""?'<input type="text" />':b+' <input type="text" />';var c=p.createElement("div");
-c.className=a.oClasses.sFilter;c.innerHTML="<label>"+b+"</label>";a.sTableId!==""&&typeof a.aanFeatures.f=="undefined"&&c.setAttribute("id",a.sTableId+"_filter");b=i("input",c);b.val(a.oPreviousSearch.sSearch.replace('"',"&quot;"));b.bind("keyup.DT",function(){for(var d=a.aanFeatures.f,f=0,e=d.length;f<e;f++)d[f]!=i(this).parents("div.dataTables_filter")[0]&&i("input",d[f]).val(this.value);this.value!=a.oPreviousSearch.sSearch&&N(a,{sSearch:this.value,bRegex:a.oPreviousSearch.bRegex,bSmart:a.oPreviousSearch.bSmart})});
-b.bind("keypress.DT",function(d){if(d.keyCode==13)return false});return c}function N(a,b,c){Oa(a,b.sSearch,c,b.bRegex,b.bSmart);for(b=0;b<a.aoPreSearchCols.length;b++)Pa(a,a.aoPreSearchCols[b].sSearch,b,a.aoPreSearchCols[b].bRegex,a.aoPreSearchCols[b].bSmart);n.afnFiltering.length!==0&&Qa(a);a.bFiltered=true;i(a.oInstance).trigger("filter",a);a._iDisplayStart=0;E(a);C(a);oa(a,0)}function Qa(a){for(var b=n.afnFiltering,c=0,d=b.length;c<d;c++)for(var f=0,e=0,h=a.aiDisplay.length;e<h;e++){var j=a.aiDisplay[e-
-f];if(!b[c](a,fa(a,j,"filter"),j)){a.aiDisplay.splice(e-f,1);f++}}}function Pa(a,b,c,d,f){if(b!==""){var e=0;b=pa(b,d,f);for(d=a.aiDisplay.length-1;d>=0;d--){f=qa(G(a,a.aiDisplay[d],c,"filter"),a.aoColumns[c].sType);if(!b.test(f)){a.aiDisplay.splice(d,1);e++}}}}function Oa(a,b,c,d,f){var e=pa(b,d,f);if(typeof c=="undefined"||c===null)c=0;if(n.afnFiltering.length!==0)c=1;if(b.length<=0){a.aiDisplay.splice(0,a.aiDisplay.length);a.aiDisplay=a.aiDisplayMaster.slice()}else if(a.aiDisplay.length==a.aiDisplayMaster.length||
-a.oPreviousSearch.sSearch.length>b.length||c==1||b.indexOf(a.oPreviousSearch.sSearch)!==0){a.aiDisplay.splice(0,a.aiDisplay.length);oa(a,1);for(c=0;c<a.aiDisplayMaster.length;c++)e.test(a.asDataSearch[c])&&a.aiDisplay.push(a.aiDisplayMaster[c])}else{var h=0;for(c=0;c<a.asDataSearch.length;c++)if(!e.test(a.asDataSearch[c])){a.aiDisplay.splice(c-h,1);h++}}a.oPreviousSearch.sSearch=b;a.oPreviousSearch.bRegex=d;a.oPreviousSearch.bSmart=f}function oa(a,b){if(!a.oFeatures.bServerSide){a.asDataSearch.splice(0,
-a.asDataSearch.length);b=typeof b!="undefined"&&b==1?a.aiDisplayMaster:a.aiDisplay;for(var c=0,d=b.length;c<d;c++)a.asDataSearch[c]=ra(a,fa(a,b[c],"filter"))}}function ra(a,b){var c="";if(typeof a.__nTmpFilter=="undefined")a.__nTmpFilter=p.createElement("div");for(var d=a.__nTmpFilter,f=0,e=a.aoColumns.length;f<e;f++)if(a.aoColumns[f].bSearchable)c+=qa(b[f],a.aoColumns[f].sType)+"  ";if(c.indexOf("&")!==-1){d.innerHTML=c;c=d.textContent?d.textContent:d.innerText;c=c.replace(/\n/g," ").replace(/\r/g,
-"")}return c}function pa(a,b,c){if(c){a=b?a.split(" "):sa(a).split(" ");a="^(?=.*?"+a.join(")(?=.*?")+").*$";return new RegExp(a,"i")}else{a=b?a:sa(a);return new RegExp(a,"i")}}function qa(a,b){if(typeof n.ofnSearch[b]=="function")return n.ofnSearch[b](a);else if(b=="html")return a.replace(/\n/g," ").replace(/<.*?>/g,"");else if(typeof a=="string")return a.replace(/\n/g," ");else if(a===null)return"";return a}function R(a,b){var c,d,f,e,h=[],j=[],k=n.oSort;d=a.aoData;var m=a.aoColumns;if(!a.oFeatures.bServerSide&&
-(a.aaSorting.length!==0||a.aaSortingFixed!==null)){h=a.aaSortingFixed!==null?a.aaSortingFixed.concat(a.aaSorting):a.aaSorting.slice();for(c=0;c<h.length;c++){var u=h[c][0];f=ta(a,u);e=a.aoColumns[u].sSortDataType;if(typeof n.afnSortData[e]!="undefined"){var r=n.afnSortData[e](a,u,f);f=0;for(e=d.length;f<e;f++)O(a,f,u,r[f])}}c=0;for(d=a.aiDisplayMaster.length;c<d;c++)j[a.aiDisplayMaster[c]]=c;var H=h.length;a.aiDisplayMaster.sort(function(L,T){var B,U;for(c=0;c<H;c++){B=m[h[c][0]].iDataSort;U=m[B].sType;
-B=k[(U?U:"string")+"-"+h[c][1]](G(a,L,B,"sort"),G(a,T,B,"sort"));if(B!==0)return B}return k["numeric-asc"](j[L],j[T])})}if((typeof b=="undefined"||b)&&!a.oFeatures.bDeferRender)V(a);a.bSorted=true;i(a.oInstance).trigger("sort",a);if(a.oFeatures.bFilter)N(a,a.oPreviousSearch,1);else{a.aiDisplay=a.aiDisplayMaster.slice();a._iDisplayStart=0;E(a);C(a)}}function ja(a,b,c,d){i(b).bind("click.DT",function(f){if(a.aoColumns[c].bSortable!==false){var e=function(){var h,j;if(f.shiftKey){for(var k=false,m=0;m<
-a.aaSorting.length;m++)if(a.aaSorting[m][0]==c){k=true;h=a.aaSorting[m][0];j=a.aaSorting[m][2]+1;if(typeof a.aoColumns[h].asSorting[j]=="undefined")a.aaSorting.splice(m,1);else{a.aaSorting[m][1]=a.aoColumns[h].asSorting[j];a.aaSorting[m][2]=j}break}k===false&&a.aaSorting.push([c,a.aoColumns[c].asSorting[0],0])}else if(a.aaSorting.length==1&&a.aaSorting[0][0]==c){h=a.aaSorting[0][0];j=a.aaSorting[0][2]+1;if(typeof a.aoColumns[h].asSorting[j]=="undefined")j=0;a.aaSorting[0][1]=a.aoColumns[h].asSorting[j];
-a.aaSorting[0][2]=j}else{a.aaSorting.splice(0,a.aaSorting.length);a.aaSorting.push([c,a.aoColumns[c].asSorting[0],0])}R(a)};if(a.oFeatures.bProcessing){K(a,true);setTimeout(function(){e();a.oFeatures.bServerSide||K(a,false)},0)}else e();typeof d=="function"&&d(a)}})}function V(a){var b,c,d,f,e,h=a.aoColumns.length,j=a.oClasses;for(b=0;b<h;b++)a.aoColumns[b].bSortable&&i(a.aoColumns[b].nTh).removeClass(j.sSortAsc+" "+j.sSortDesc+" "+a.aoColumns[b].sSortingClass);f=a.aaSortingFixed!==null?a.aaSortingFixed.concat(a.aaSorting):
-a.aaSorting.slice();for(b=0;b<a.aoColumns.length;b++)if(a.aoColumns[b].bSortable){e=a.aoColumns[b].sSortingClass;d=-1;for(c=0;c<f.length;c++)if(f[c][0]==b){e=f[c][1]=="asc"?j.sSortAsc:j.sSortDesc;d=c;break}i(a.aoColumns[b].nTh).addClass(e);if(a.bJUI){c=i("span",a.aoColumns[b].nTh);c.removeClass(j.sSortJUIAsc+" "+j.sSortJUIDesc+" "+j.sSortJUI+" "+j.sSortJUIAscAllowed+" "+j.sSortJUIDescAllowed);c.addClass(d==-1?a.aoColumns[b].sSortingClassJUI:f[d][1]=="asc"?j.sSortJUIAsc:j.sSortJUIDesc)}}else i(a.aoColumns[b].nTh).addClass(a.aoColumns[b].sSortingClass);
-e=j.sSortColumn;if(a.oFeatures.bSort&&a.oFeatures.bSortClasses){d=Q(a);if(a.oFeatures.bDeferRender)i(d).removeClass(e+"1 "+e+"2 "+e+"3");else if(d.length>=h)for(b=0;b<h;b++)if(d[b].className.indexOf(e+"1")!=-1){c=0;for(a=d.length/h;c<a;c++)d[h*c+b].className=i.trim(d[h*c+b].className.replace(e+"1",""))}else if(d[b].className.indexOf(e+"2")!=-1){c=0;for(a=d.length/h;c<a;c++)d[h*c+b].className=i.trim(d[h*c+b].className.replace(e+"2",""))}else if(d[b].className.indexOf(e+"3")!=-1){c=0;for(a=d.length/
-h;c<a;c++)d[h*c+b].className=i.trim(d[h*c+b].className.replace(" "+e+"3",""))}j=1;var k;for(b=0;b<f.length;b++){k=parseInt(f[b][0],10);c=0;for(a=d.length/h;c<a;c++)d[h*c+k].className+=" "+e+j;j<3&&j++}}}function La(a){if(a.oScroll.bInfinite)return null;var b=p.createElement("div");b.className=a.oClasses.sPaging+a.sPaginationType;n.oPagination[a.sPaginationType].fnInit(a,b,function(c){E(c);C(c)});typeof a.aanFeatures.p=="undefined"&&a.aoDrawCallback.push({fn:function(c){n.oPagination[c.sPaginationType].fnUpdate(c,
-function(d){E(d);C(d)})},sName:"pagination"});return b}function ma(a,b){var c=a._iDisplayStart;if(b=="first")a._iDisplayStart=0;else if(b=="previous"){a._iDisplayStart=a._iDisplayLength>=0?a._iDisplayStart-a._iDisplayLength:0;if(a._iDisplayStart<0)a._iDisplayStart=0}else if(b=="next")if(a._iDisplayLength>=0){if(a._iDisplayStart+a._iDisplayLength<a.fnRecordsDisplay())a._iDisplayStart+=a._iDisplayLength}else a._iDisplayStart=0;else if(b=="last")if(a._iDisplayLength>=0){b=parseInt((a.fnRecordsDisplay()-
-1)/a._iDisplayLength,10)+1;a._iDisplayStart=(b-1)*a._iDisplayLength}else a._iDisplayStart=0;else J(a,0,"Unknown paging action: "+b);i(a.oInstance).trigger("page",a);return c!=a._iDisplayStart}function Ka(a){var b=p.createElement("div");b.className=a.oClasses.sInfo;if(typeof a.aanFeatures.i=="undefined"){a.aoDrawCallback.push({fn:Ra,sName:"information"});a.sTableId!==""&&b.setAttribute("id",a.sTableId+"_info")}return b}function Ra(a){if(!(!a.oFeatures.bInfo||a.aanFeatures.i.length===0)){var b=a._iDisplayStart+
-1,c=a.fnDisplayEnd(),d=a.fnRecordsTotal(),f=a.fnRecordsDisplay(),e=a.fnFormatNumber(b),h=a.fnFormatNumber(c),j=a.fnFormatNumber(d),k=a.fnFormatNumber(f);if(a.oScroll.bInfinite)e=a.fnFormatNumber(1);e=a.fnRecordsDisplay()===0&&a.fnRecordsDisplay()==a.fnRecordsTotal()?a.oLanguage.sInfoEmpty+a.oLanguage.sInfoPostFix:a.fnRecordsDisplay()===0?a.oLanguage.sInfoEmpty+" "+a.oLanguage.sInfoFiltered.replace("_MAX_",j)+a.oLanguage.sInfoPostFix:a.fnRecordsDisplay()==a.fnRecordsTotal()?a.oLanguage.sInfo.replace("_START_",
-e).replace("_END_",h).replace("_TOTAL_",k)+a.oLanguage.sInfoPostFix:a.oLanguage.sInfo.replace("_START_",e).replace("_END_",h).replace("_TOTAL_",k)+" "+a.oLanguage.sInfoFiltered.replace("_MAX_",a.fnFormatNumber(a.fnRecordsTotal()))+a.oLanguage.sInfoPostFix;if(a.oLanguage.fnInfoCallback!==null)e=a.oLanguage.fnInfoCallback(a,b,c,d,f,e);a=a.aanFeatures.i;b=0;for(c=a.length;b<c;b++)i(a[b]).html(e)}}function Ga(a){if(a.oScroll.bInfinite)return null;var b='<select size="1" '+(a.sTableId===""?"":'name="'+
-a.sTableId+'_length"')+">",c,d;if(a.aLengthMenu.length==2&&typeof a.aLengthMenu[0]=="object"&&typeof a.aLengthMenu[1]=="object"){c=0;for(d=a.aLengthMenu[0].length;c<d;c++)b+='<option value="'+a.aLengthMenu[0][c]+'">'+a.aLengthMenu[1][c]+"</option>"}else{c=0;for(d=a.aLengthMenu.length;c<d;c++)b+='<option value="'+a.aLengthMenu[c]+'">'+a.aLengthMenu[c]+"</option>"}b+="</select>";var f=p.createElement("div");a.sTableId!==""&&typeof a.aanFeatures.l=="undefined"&&f.setAttribute("id",a.sTableId+"_length");
-f.className=a.oClasses.sLength;f.innerHTML="<label>"+a.oLanguage.sLengthMenu.replace("_MENU_",b)+"</label>";i('select option[value="'+a._iDisplayLength+'"]',f).attr("selected",true);i("select",f).bind("change.DT",function(){var e=i(this).val(),h=a.aanFeatures.l;c=0;for(d=h.length;c<d;c++)h[c]!=this.parentNode&&i("select",h[c]).val(e);a._iDisplayLength=parseInt(e,10);E(a);if(a.fnDisplayEnd()==a.fnRecordsDisplay()){a._iDisplayStart=a.fnDisplayEnd()-a._iDisplayLength;if(a._iDisplayStart<0)a._iDisplayStart=
-0}if(a._iDisplayLength==-1)a._iDisplayStart=0;C(a)});return f}function Ia(a){var b=p.createElement("div");a.sTableId!==""&&typeof a.aanFeatures.r=="undefined"&&b.setAttribute("id",a.sTableId+"_processing");b.innerHTML=a.oLanguage.sProcessing;b.className=a.oClasses.sProcessing;a.nTable.parentNode.insertBefore(b,a.nTable);return b}function K(a,b){if(a.oFeatures.bProcessing){a=a.aanFeatures.r;for(var c=0,d=a.length;c<d;c++)a[c].style.visibility=b?"visible":"hidden"}}function Na(a,b){for(var c=-1,d=0;d<
-a.aoColumns.length;d++){a.aoColumns[d].bVisible===true&&c++;if(c==b)return d}return null}function ta(a,b){for(var c=-1,d=0;d<a.aoColumns.length;d++){a.aoColumns[d].bVisible===true&&c++;if(d==b)return a.aoColumns[d].bVisible===true?c:null}return null}function W(a,b){var c,d;c=a._iDisplayStart;for(d=a._iDisplayEnd;c<d;c++)if(a.aoData[a.aiDisplay[c]].nTr==b)return a.aiDisplay[c];c=0;for(d=a.aoData.length;c<d;c++)if(a.aoData[c].nTr==b)return c;return null}function Z(a){for(var b=0,c=0;c<a.aoColumns.length;c++)a.aoColumns[c].bVisible===
-true&&b++;return b}function E(a){a._iDisplayEnd=a.oFeatures.bPaginate===false?a.aiDisplay.length:a._iDisplayStart+a._iDisplayLength>a.aiDisplay.length||a._iDisplayLength==-1?a.aiDisplay.length:a._iDisplayStart+a._iDisplayLength}function Sa(a,b){if(!a||a===null||a==="")return 0;if(typeof b=="undefined")b=p.getElementsByTagName("body")[0];var c=p.createElement("div");c.style.width=q(a);b.appendChild(c);a=c.offsetWidth;b.removeChild(c);return a}function ga(a){var b=0,c,d=0,f=a.aoColumns.length,e,h=i("th",
-a.nTHead);for(e=0;e<f;e++)if(a.aoColumns[e].bVisible){d++;if(a.aoColumns[e].sWidth!==null){c=Sa(a.aoColumns[e].sWidthOrig,a.nTable.parentNode);if(c!==null)a.aoColumns[e].sWidth=q(c);b++}}if(f==h.length&&b===0&&d==f&&a.oScroll.sX===""&&a.oScroll.sY==="")for(e=0;e<a.aoColumns.length;e++){c=i(h[e]).width();if(c!==null)a.aoColumns[e].sWidth=q(c)}else{b=a.nTable.cloneNode(false);e=a.nTHead.cloneNode(true);d=p.createElement("tbody");c=p.createElement("tr");b.removeAttribute("id");b.appendChild(e);if(a.nTFoot!==
-null){b.appendChild(a.nTFoot.cloneNode(true));P(function(k){k.style.width=""},b.getElementsByTagName("tr"))}b.appendChild(d);d.appendChild(c);d=i("thead th",b);if(d.length===0)d=i("tbody tr:eq(0)>td",b);h=S(a,e);for(e=d=0;e<f;e++){var j=a.aoColumns[e];if(j.bVisible&&j.sWidthOrig!==null&&j.sWidthOrig!=="")h[e-d].style.width=q(j.sWidthOrig);else if(j.bVisible)h[e-d].style.width="";else d++}for(e=0;e<f;e++)if(a.aoColumns[e].bVisible){d=Ta(a,e);if(d!==null){d=d.cloneNode(true);if(a.aoColumns[e].sContentPadding!==
-"")d.innerHTML+=a.aoColumns[e].sContentPadding;c.appendChild(d)}}f=a.nTable.parentNode;f.appendChild(b);if(a.oScroll.sX!==""&&a.oScroll.sXInner!=="")b.style.width=q(a.oScroll.sXInner);else if(a.oScroll.sX!==""){b.style.width="";if(i(b).width()<f.offsetWidth)b.style.width=q(f.offsetWidth)}else if(a.oScroll.sY!=="")b.style.width=q(f.offsetWidth);b.style.visibility="hidden";Ua(a,b);f=i("tbody tr:eq(0)",b).children();if(f.length===0)f=S(a,i("thead",b)[0]);if(a.oScroll.sX!==""){for(e=d=c=0;e<a.aoColumns.length;e++)if(a.aoColumns[e].bVisible){c+=
-a.aoColumns[e].sWidthOrig===null?i(f[d]).outerWidth():parseInt(a.aoColumns[e].sWidth.replace("px",""),10)+(i(f[d]).outerWidth()-i(f[d]).width());d++}b.style.width=q(c);a.nTable.style.width=q(c)}for(e=d=0;e<a.aoColumns.length;e++)if(a.aoColumns[e].bVisible){c=i(f[d]).width();if(c!==null&&c>0)a.aoColumns[e].sWidth=q(c);d++}a.nTable.style.width=q(i(b).outerWidth());b.parentNode.removeChild(b)}}function Ua(a,b){if(a.oScroll.sX===""&&a.oScroll.sY!==""){i(b).width();b.style.width=q(i(b).outerWidth()-a.oScroll.iBarWidth)}else if(a.oScroll.sX!==
-"")b.style.width=q(i(b).outerWidth())}function Ta(a,b){var c=Va(a,b);if(c<0)return null;if(a.aoData[c].nTr===null){var d=p.createElement("td");d.innerHTML=G(a,c,b,"");return d}return Q(a,c)[b]}function Va(a,b){for(var c=-1,d=-1,f=0;f<a.aoData.length;f++){var e=G(a,f,b,"display")+"";e=e.replace(/<.*?>/g,"");if(e.length>c){c=e.length;d=f}}return d}function q(a){if(a===null)return"0px";if(typeof a=="number"){if(a<0)return"0px";return a+"px"}var b=a.charCodeAt(a.length-1);if(b<48||b>57)return a;return a+
-"px"}function Za(a,b){if(a.length!=b.length)return 1;for(var c=0;c<a.length;c++)if(a[c]!=b[c])return 2;return 0}function ia(a){for(var b=n.aTypes,c=b.length,d=0;d<c;d++){var f=b[d](a);if(f!==null)return f}return"string"}function A(a){for(var b=0;b<D.length;b++)if(D[b].nTable==a)return D[b];return null}function ca(a){for(var b=[],c=a.aoData.length,d=0;d<c;d++)b.push(a.aoData[d]._aData);return b}function ba(a){for(var b=[],c=0,d=a.aoData.length;c<d;c++)a.aoData[c].nTr!==null&&b.push(a.aoData[c].nTr);
-return b}function Q(a,b){var c=[],d,f,e,h,j;f=0;var k=a.aoData.length;if(typeof b!="undefined"){f=b;k=b+1}for(f=f;f<k;f++){j=a.aoData[f];if(j.nTr!==null){b=[];e=0;for(h=j.nTr.childNodes.length;e<h;e++){d=j.nTr.childNodes[e].nodeName.toLowerCase();if(d=="td"||d=="th")b.push(j.nTr.childNodes[e])}e=d=0;for(h=a.aoColumns.length;e<h;e++)if(a.aoColumns[e].bVisible)c.push(b[e-d]);else{c.push(j._anHidden[e]);d++}}}return c}function sa(a){return a.replace(new RegExp("(\\/|\\.|\\*|\\+|\\?|\\||\\(|\\)|\\[|\\]|\\{|\\}|\\\\|\\$|\\^)",
-"g"),"\\$1")}function ua(a,b){for(var c=-1,d=0,f=a.length;d<f;d++)if(a[d]==b)c=d;else a[d]>b&&a[d]--;c!=-1&&a.splice(c,1)}function Fa(a,b){b=b.split(",");for(var c=[],d=0,f=a.aoColumns.length;d<f;d++)for(var e=0;e<f;e++)if(a.aoColumns[d].sName==b[e]){c.push(e);break}return c}function ka(a){for(var b="",c=0,d=a.aoColumns.length;c<d;c++)b+=a.aoColumns[c].sName+",";if(b.length==d)return"";return b.slice(0,-1)}function J(a,b,c){a=a.sTableId===""?"DataTables warning: "+c:"DataTables warning (table id = '"+
-a.sTableId+"'): "+c;if(b===0)if(n.sErrMode=="alert")alert(a);else throw a;else typeof console!="undefined"&&typeof console.log!="undefined"&&console.log(a)}function la(a){a.aoData.splice(0,a.aoData.length);a.aiDisplayMaster.splice(0,a.aiDisplayMaster.length);a.aiDisplay.splice(0,a.aiDisplay.length);E(a)}function va(a){if(!(!a.oFeatures.bStateSave||typeof a.bDestroying!="undefined")){var b,c,d,f="{";f+='"iCreate":'+(new Date).getTime()+",";f+='"iStart":'+(a.oScroll.bInfinite?0:a._iDisplayStart)+",";
-f+='"iEnd":'+(a.oScroll.bInfinite?a._iDisplayLength:a._iDisplayEnd)+",";f+='"iLength":'+a._iDisplayLength+",";f+='"sFilter":"'+encodeURIComponent(a.oPreviousSearch.sSearch)+'",';f+='"sFilterEsc":'+!a.oPreviousSearch.bRegex+",";f+='"aaSorting":[ ';for(b=0;b<a.aaSorting.length;b++)f+="["+a.aaSorting[b][0]+',"'+a.aaSorting[b][1]+'"],';f=f.substring(0,f.length-1);f+="],";f+='"aaSearchCols":[ ';for(b=0;b<a.aoPreSearchCols.length;b++)f+='["'+encodeURIComponent(a.aoPreSearchCols[b].sSearch)+'",'+!a.aoPreSearchCols[b].bRegex+
-"],";f=f.substring(0,f.length-1);f+="],";f+='"abVisCols":[ ';for(b=0;b<a.aoColumns.length;b++)f+=a.aoColumns[b].bVisible+",";f=f.substring(0,f.length-1);f+="]";b=0;for(c=a.aoStateSave.length;b<c;b++){d=a.aoStateSave[b].fn(a,f);if(d!=="")f=d}f+="}";Wa(a.sCookiePrefix+a.sInstance,f,a.iCookieDuration,a.sCookiePrefix,a.fnCookieCallback)}}function Xa(a,b){if(a.oFeatures.bStateSave){var c,d,f;d=wa(a.sCookiePrefix+a.sInstance);if(d!==null&&d!==""){try{c=typeof i.parseJSON=="function"?i.parseJSON(d.replace(/'/g,
-'"')):eval("("+d+")")}catch(e){return}d=0;for(f=a.aoStateLoad.length;d<f;d++)if(!a.aoStateLoad[d].fn(a,c))return;a.oLoadedState=i.extend(true,{},c);a._iDisplayStart=c.iStart;a.iInitDisplayStart=c.iStart;a._iDisplayEnd=c.iEnd;a._iDisplayLength=c.iLength;a.oPreviousSearch.sSearch=decodeURIComponent(c.sFilter);a.aaSorting=c.aaSorting.slice();a.saved_aaSorting=c.aaSorting.slice();if(typeof c.sFilterEsc!="undefined")a.oPreviousSearch.bRegex=!c.sFilterEsc;if(typeof c.aaSearchCols!="undefined")for(d=0;d<
-c.aaSearchCols.length;d++)a.aoPreSearchCols[d]={sSearch:decodeURIComponent(c.aaSearchCols[d][0]),bRegex:!c.aaSearchCols[d][1]};if(typeof c.abVisCols!="undefined"){b.saved_aoColumns=[];for(d=0;d<c.abVisCols.length;d++){b.saved_aoColumns[d]={};b.saved_aoColumns[d].bVisible=c.abVisCols[d]}}}}}function Wa(a,b,c,d,f){var e=new Date;e.setTime(e.getTime()+c*1E3);c=za.location.pathname.split("/");a=a+"_"+c.pop().replace(/[\/:]/g,"").toLowerCase();var h;if(f!==null){h=typeof i.parseJSON=="function"?i.parseJSON(b):
-eval("("+b+")");b=f(a,h,e.toGMTString(),c.join("/")+"/")}else b=a+"="+encodeURIComponent(b)+"; expires="+e.toGMTString()+"; path="+c.join("/")+"/";f="";e=9999999999999;if((wa(a)!==null?p.cookie.length:b.length+p.cookie.length)+10>4096){a=p.cookie.split(";");for(var j=0,k=a.length;j<k;j++)if(a[j].indexOf(d)!=-1){var m=a[j].split("=");try{h=eval("("+decodeURIComponent(m[1])+")")}catch(u){continue}if(typeof h.iCreate!="undefined"&&h.iCreate<e){f=m[0];e=h.iCreate}}if(f!=="")p.cookie=f+"=; expires=Thu, 01-Jan-1970 00:00:01 GMT; path="+
-c.join("/")+"/"}p.cookie=b}function wa(a){var b=za.location.pathname.split("/");a=a+"_"+b[b.length-1].replace(/[\/:]/g,"").toLowerCase()+"=";b=p.cookie.split(";");for(var c=0;c<b.length;c++){for(var d=b[c];d.charAt(0)==" ";)d=d.substring(1,d.length);if(d.indexOf(a)===0)return decodeURIComponent(d.substring(a.length,d.length))}return null}function Y(a,b){b=i(b).children("tr");var c,d,f,e,h,j,k,m,u=function(L,T,B){for(;typeof L[T][B]!="undefined";)B++;return B};a.splice(0,a.length);d=0;for(j=b.length;d<
-j;d++)a.push([]);d=0;for(j=b.length;d<j;d++){f=0;for(k=b[d].childNodes.length;f<k;f++){c=b[d].childNodes[f];if(c.nodeName.toUpperCase()=="TD"||c.nodeName.toUpperCase()=="TH"){var r=c.getAttribute("colspan")*1,H=c.getAttribute("rowspan")*1;r=!r||r===0||r===1?1:r;H=!H||H===0||H===1?1:H;m=u(a,d,0);for(h=0;h<r;h++)for(e=0;e<H;e++){a[d+e][m+h]={cell:c,unique:r==1?true:false};a[d+e].nTr=b[d]}}}}}function S(a,b,c){var d=[];if(typeof c=="undefined"){c=a.aoHeader;if(typeof b!="undefined"){c=[];Y(c,b)}}b=0;
-for(var f=c.length;b<f;b++)for(var e=0,h=c[b].length;e<h;e++)if(c[b][e].unique&&(typeof d[e]=="undefined"||!a.bSortCellsTop))d[e]=c[b][e].cell;return d}function Ya(){var a=p.createElement("p"),b=a.style;b.width="100%";b.height="200px";b.padding="0px";var c=p.createElement("div");b=c.style;b.position="absolute";b.top="0px";b.left="0px";b.visibility="hidden";b.width="200px";b.height="150px";b.padding="0px";b.overflow="hidden";c.appendChild(a);p.body.appendChild(c);b=a.offsetWidth;c.style.overflow="scroll";
-a=a.offsetWidth;if(b==a)a=c.clientWidth;p.body.removeChild(c);return b-a}function P(a,b,c){for(var d=0,f=b.length;d<f;d++)for(var e=0,h=b[d].childNodes.length;e<h;e++)if(b[d].childNodes[e].nodeType==1)typeof c!="undefined"?a(b[d].childNodes[e],c[d].childNodes[e]):a(b[d].childNodes[e])}function o(a,b,c,d){if(typeof d=="undefined")d=c;if(typeof b[c]!="undefined")a[d]=b[c]}function fa(a,b,c){for(var d=[],f=0,e=a.aoColumns.length;f<e;f++)d.push(G(a,b,f,c));return d}function G(a,b,c,d){var f=a.aoColumns[c];
-if((c=f.fnGetData(a.aoData[b]._aData))===undefined){if(a.iDrawError!=a.iDraw&&f.sDefaultContent===null){J(a,0,"Requested unknown parameter '"+f.mDataProp+"' from the data source for row "+b);a.iDrawError=a.iDraw}return f.sDefaultContent}if(c===null&&f.sDefaultContent!==null)c=f.sDefaultContent;else if(typeof c=="function")return c();if(d=="display"&&c===null)return"";return c}function O(a,b,c,d){a.aoColumns[c].fnSetData(a.aoData[b]._aData,d)}function aa(a){if(a===null)return function(){return null};
-else if(typeof a=="function")return function(c){return a(c)};else if(typeof a=="string"&&a.indexOf(".")!=-1){var b=a.split(".");return b.length==2?function(c){return c[b[0]][b[1]]}:b.length==3?function(c){return c[b[0]][b[1]][b[2]]}:function(c){for(var d=0,f=b.length;d<f;d++)c=c[b[d]];return c}}else return function(c){return c[a]}}function Ba(a){if(a===null)return function(){};else if(typeof a=="function")return function(c,d){return a(c,d)};else if(typeof a=="string"&&a.indexOf(".")!=-1){var b=a.split(".");
-return b.length==2?function(c,d){c[b[0]][b[1]]=d}:b.length==3?function(c,d){c[b[0]][b[1]][b[2]]=d}:function(c,d){for(var f=0,e=b.length-1;f<e;f++)c=c[b[f]];c[b[b.length-1]]=d}}else return function(c,d){c[a]=d}}this.oApi={};this.fnDraw=function(a){var b=A(this[n.iApiIndex]);if(typeof a!="undefined"&&a===false){E(b);C(b)}else da(b)};this.fnFilter=function(a,b,c,d,f){var e=A(this[n.iApiIndex]);if(e.oFeatures.bFilter){if(typeof c=="undefined")c=false;if(typeof d=="undefined")d=true;if(typeof f=="undefined")f=
-true;if(typeof b=="undefined"||b===null){N(e,{sSearch:a,bRegex:c,bSmart:d},1);if(f&&typeof e.aanFeatures.f!="undefined"){b=e.aanFeatures.f;c=0;for(d=b.length;c<d;c++)i("input",b[c]).val(a)}}else{e.aoPreSearchCols[b].sSearch=a;e.aoPreSearchCols[b].bRegex=c;e.aoPreSearchCols[b].bSmart=d;N(e,e.oPreviousSearch,1)}}};this.fnSettings=function(){return A(this[n.iApiIndex])};this.fnVersionCheck=n.fnVersionCheck;this.fnSort=function(a){var b=A(this[n.iApiIndex]);b.aaSorting=a;R(b)};this.fnSortListener=function(a,
-b,c){ja(A(this[n.iApiIndex]),a,b,c)};this.fnAddData=function(a,b){if(a.length===0)return[];var c=[],d,f=A(this[n.iApiIndex]);if(typeof a[0]=="object")for(var e=0;e<a.length;e++){d=v(f,a[e]);if(d==-1)return c;c.push(d)}else{d=v(f,a);if(d==-1)return c;c.push(d)}f.aiDisplay=f.aiDisplayMaster.slice();if(typeof b=="undefined"||b)da(f);return c};this.fnDeleteRow=function(a,b,c){var d=A(this[n.iApiIndex]);a=typeof a=="object"?W(d,a):a;var f=d.aoData.splice(a,1),e=i.inArray(a,d.aiDisplay);d.asDataSearch.splice(e,
-1);ua(d.aiDisplayMaster,a);ua(d.aiDisplay,a);typeof b=="function"&&b.call(this,d,f);if(d._iDisplayStart>=d.aiDisplay.length){d._iDisplayStart-=d._iDisplayLength;if(d._iDisplayStart<0)d._iDisplayStart=0}if(typeof c=="undefined"||c){E(d);C(d)}return f};this.fnClearTable=function(a){var b=A(this[n.iApiIndex]);la(b);if(typeof a=="undefined"||a)C(b)};this.fnOpen=function(a,b,c){var d=A(this[n.iApiIndex]);this.fnClose(a);var f=p.createElement("tr"),e=p.createElement("td");f.appendChild(e);e.className=c;
-e.colSpan=Z(d);if(typeof b.jquery!="undefined"||typeof b=="object")e.appendChild(b);else e.innerHTML=b;b=i("tr",d.nTBody);i.inArray(a,b)!=-1&&i(f).insertAfter(a);d.aoOpenRows.push({nTr:f,nParent:a});return f};this.fnClose=function(a){for(var b=A(this[n.iApiIndex]),c=0;c<b.aoOpenRows.length;c++)if(b.aoOpenRows[c].nParent==a){(a=b.aoOpenRows[c].nTr.parentNode)&&a.removeChild(b.aoOpenRows[c].nTr);b.aoOpenRows.splice(c,1);return 0}return 1};this.fnGetData=function(a,b){var c=A(this[n.iApiIndex]);if(typeof a!=
-"undefined"){a=typeof a=="object"?W(c,a):a;if(typeof b!="undefined")return G(c,a,b,"");return typeof c.aoData[a]!="undefined"?c.aoData[a]._aData:null}return ca(c)};this.fnGetNodes=function(a){var b=A(this[n.iApiIndex]);if(typeof a!="undefined")return typeof b.aoData[a]!="undefined"?b.aoData[a].nTr:null;return ba(b)};this.fnGetPosition=function(a){var b=A(this[n.iApiIndex]),c=a.nodeName.toUpperCase();if(c=="TR")return W(b,a);else if(c=="TD"||c=="TH"){c=W(b,a.parentNode);for(var d=Q(b,c),f=0;f<b.aoColumns.length;f++)if(d[f]==
-a)return[c,ta(b,f),f]}return null};this.fnUpdate=function(a,b,c,d,f){var e=A(this[n.iApiIndex]);b=typeof b=="object"?W(e,b):b;if(i.isArray(a)&&typeof a=="object"){e.aoData[b]._aData=a.slice();for(c=0;c<e.aoColumns.length;c++)this.fnUpdate(G(e,b,c),b,c,false,false)}else if(a!==null&&typeof a=="object"){e.aoData[b]._aData=i.extend(true,{},a);for(c=0;c<e.aoColumns.length;c++)this.fnUpdate(G(e,b,c),b,c,false,false)}else{a=a;O(e,b,c,a);if(e.aoColumns[c].fnRender!==null){a=e.aoColumns[c].fnRender({iDataRow:b,
-iDataColumn:c,aData:e.aoData[b]._aData,oSettings:e});e.aoColumns[c].bUseRendered&&O(e,b,c,a)}if(e.aoData[b].nTr!==null)Q(e,b)[c].innerHTML=a}c=i.inArray(b,e.aiDisplay);e.asDataSearch[c]=ra(e,fa(e,b,"filter"));if(typeof f=="undefined"||f)ea(e);if(typeof d=="undefined"||d)da(e);return 0};this.fnSetColumnVis=function(a,b,c){var d=A(this[n.iApiIndex]),f,e;e=d.aoColumns.length;var h,j;if(d.aoColumns[a].bVisible!=b){if(b){for(f=j=0;f<a;f++)d.aoColumns[f].bVisible&&j++;j=j>=Z(d);if(!j)for(f=a;f<e;f++)if(d.aoColumns[f].bVisible){h=
-f;break}f=0;for(e=d.aoData.length;f<e;f++)if(d.aoData[f].nTr!==null)j?d.aoData[f].nTr.appendChild(d.aoData[f]._anHidden[a]):d.aoData[f].nTr.insertBefore(d.aoData[f]._anHidden[a],Q(d,f)[h])}else{f=0;for(e=d.aoData.length;f<e;f++)if(d.aoData[f].nTr!==null){h=Q(d,f)[a];d.aoData[f]._anHidden[a]=h;h.parentNode.removeChild(h)}}d.aoColumns[a].bVisible=b;M(d,d.aoHeader);d.nTFoot&&M(d,d.aoFooter);f=0;for(e=d.aoOpenRows.length;f<e;f++)d.aoOpenRows[f].nTr.colSpan=Z(d);if(typeof c=="undefined"||c){ea(d);C(d)}va(d)}};
-this.fnPageChange=function(a,b){var c=A(this[n.iApiIndex]);ma(c,a);E(c);if(typeof b=="undefined"||b)C(c)};this.fnDestroy=function(){var a=A(this[n.iApiIndex]),b=a.nTableWrapper.parentNode,c=a.nTBody,d,f;a.bDestroying=true;d=0;for(f=a.aoDestroyCallback.length;d<f;d++)a.aoDestroyCallback[d].fn();d=0;for(f=a.aoColumns.length;d<f;d++)a.aoColumns[d].bVisible===false&&this.fnSetColumnVis(d,true);i(a.nTableWrapper).find("*").andSelf().unbind(".DT");i("tbody>tr>td."+a.oClasses.sRowEmpty,a.nTable).parent().remove();
-if(a.nTable!=a.nTHead.parentNode){i(a.nTable).children("thead").remove();a.nTable.appendChild(a.nTHead)}if(a.nTFoot&&a.nTable!=a.nTFoot.parentNode){i(a.nTable).children("tfoot").remove();a.nTable.appendChild(a.nTFoot)}a.nTable.parentNode.removeChild(a.nTable);i(a.nTableWrapper).remove();a.aaSorting=[];a.aaSortingFixed=[];V(a);i(ba(a)).removeClass(a.asStripeClasses.join(" "));if(a.bJUI){i("th",a.nTHead).removeClass([n.oStdClasses.sSortable,n.oJUIClasses.sSortableAsc,n.oJUIClasses.sSortableDesc,n.oJUIClasses.sSortableNone].join(" "));
-i("th span."+n.oJUIClasses.sSortIcon,a.nTHead).remove();i("th",a.nTHead).each(function(){var e=i("div."+n.oJUIClasses.sSortJUIWrapper,this),h=e.contents();i(this).append(h);e.remove()})}else i("th",a.nTHead).removeClass([n.oStdClasses.sSortable,n.oStdClasses.sSortableAsc,n.oStdClasses.sSortableDesc,n.oStdClasses.sSortableNone].join(" "));a.nTableReinsertBefore?b.insertBefore(a.nTable,a.nTableReinsertBefore):b.appendChild(a.nTable);d=0;for(f=a.aoData.length;d<f;d++)a.aoData[d].nTr!==null&&c.appendChild(a.aoData[d].nTr);
-if(a.oFeatures.bAutoWidth===true)a.nTable.style.width=q(a.sDestroyWidth);i(c).children("tr:even").addClass(a.asDestroyStripes[0]);i(c).children("tr:odd").addClass(a.asDestroyStripes[1]);d=0;for(f=D.length;d<f;d++)D[d]==a&&D.splice(d,1);a=null};this.fnAdjustColumnSizing=function(a){var b=A(this[n.iApiIndex]);ea(b);if(typeof a=="undefined"||a)this.fnDraw(false);else if(b.oScroll.sX!==""||b.oScroll.sY!=="")this.oApi._fnScrollDraw(b)};for(var xa in n.oApi)if(xa)this[xa]=s(xa);this.oApi._fnExternApiFunc=
-s;this.oApi._fnInitialise=t;this.oApi._fnInitComplete=w;this.oApi._fnLanguageProcess=y;this.oApi._fnAddColumn=F;this.oApi._fnColumnOptions=x;this.oApi._fnAddData=v;this.oApi._fnCreateTr=z;this.oApi._fnGatherData=$;this.oApi._fnBuildHead=X;this.oApi._fnDrawHead=M;this.oApi._fnDraw=C;this.oApi._fnReDraw=da;this.oApi._fnAjaxUpdate=Ca;this.oApi._fnAjaxParameters=Da;this.oApi._fnAjaxUpdateDraw=Ea;this.oApi._fnServerParams=ha;this.oApi._fnAddOptionsHtml=Aa;this.oApi._fnFeatureHtmlTable=Ja;this.oApi._fnScrollDraw=
-Ma;this.oApi._fnAdjustColumnSizing=ea;this.oApi._fnFeatureHtmlFilter=Ha;this.oApi._fnFilterComplete=N;this.oApi._fnFilterCustom=Qa;this.oApi._fnFilterColumn=Pa;this.oApi._fnFilter=Oa;this.oApi._fnBuildSearchArray=oa;this.oApi._fnBuildSearchRow=ra;this.oApi._fnFilterCreateSearch=pa;this.oApi._fnDataToSearch=qa;this.oApi._fnSort=R;this.oApi._fnSortAttachListener=ja;this.oApi._fnSortingClasses=V;this.oApi._fnFeatureHtmlPaginate=La;this.oApi._fnPageChange=ma;this.oApi._fnFeatureHtmlInfo=Ka;this.oApi._fnUpdateInfo=
-Ra;this.oApi._fnFeatureHtmlLength=Ga;this.oApi._fnFeatureHtmlProcessing=Ia;this.oApi._fnProcessingDisplay=K;this.oApi._fnVisibleToColumnIndex=Na;this.oApi._fnColumnIndexToVisible=ta;this.oApi._fnNodeToDataIndex=W;this.oApi._fnVisbleColumns=Z;this.oApi._fnCalculateEnd=E;this.oApi._fnConvertToWidth=Sa;this.oApi._fnCalculateColumnWidths=ga;this.oApi._fnScrollingWidthAdjust=Ua;this.oApi._fnGetWidestNode=Ta;this.oApi._fnGetMaxLenString=Va;this.oApi._fnStringToCss=q;this.oApi._fnArrayCmp=Za;this.oApi._fnDetectType=
-ia;this.oApi._fnSettingsFromNode=A;this.oApi._fnGetDataMaster=ca;this.oApi._fnGetTrNodes=ba;this.oApi._fnGetTdNodes=Q;this.oApi._fnEscapeRegex=sa;this.oApi._fnDeleteIndex=ua;this.oApi._fnReOrderIndex=Fa;this.oApi._fnColumnOrdering=ka;this.oApi._fnLog=J;this.oApi._fnClearTable=la;this.oApi._fnSaveState=va;this.oApi._fnLoadState=Xa;this.oApi._fnCreateCookie=Wa;this.oApi._fnReadCookie=wa;this.oApi._fnDetectHeader=Y;this.oApi._fnGetUniqueThs=S;this.oApi._fnScrollBarWidth=Ya;this.oApi._fnApplyToChildren=
-P;this.oApi._fnMap=o;this.oApi._fnGetRowData=fa;this.oApi._fnGetCellData=G;this.oApi._fnSetCellData=O;this.oApi._fnGetObjectDataFn=aa;this.oApi._fnSetObjectDataFn=Ba;var ya=this;return this.each(function(){var a=0,b,c,d,f;a=0;for(b=D.length;a<b;a++){if(D[a].nTable==this)if(typeof g=="undefined"||typeof g.bRetrieve!="undefined"&&g.bRetrieve===true)return D[a].oInstance;else if(typeof g.bDestroy!="undefined"&&g.bDestroy===true){D[a].oInstance.fnDestroy();break}else{J(D[a],0,"Cannot reinitialise DataTable.\n\nTo retrieve the DataTables object for this table, please pass either no arguments to the dataTable() function, or set bRetrieve to true. Alternatively, to destory the old table and create a new one, set bDestroy to true (note that a lot of changes to the configuration can be made through the API which is usually much faster).");
-return}if(D[a].sTableId!==""&&D[a].sTableId==this.getAttribute("id")){D.splice(a,1);break}}var e=new l;D.push(e);var h=false,j=false;a=this.getAttribute("id");if(a!==null){e.sTableId=a;e.sInstance=a}else e.sInstance=n._oExternConfig.iNextUnique++;if(this.nodeName.toLowerCase()!="table")J(e,0,"Attempted to initialise DataTables on a node which is not a table: "+this.nodeName);else{e.nTable=this;e.oInstance=ya.length==1?ya:i(this).dataTable();e.oApi=ya.oApi;e.sDestroyWidth=i(this).width();if(typeof g!=
-"undefined"&&g!==null){e.oInit=g;o(e.oFeatures,g,"bPaginate");o(e.oFeatures,g,"bLengthChange");o(e.oFeatures,g,"bFilter");o(e.oFeatures,g,"bSort");o(e.oFeatures,g,"bInfo");o(e.oFeatures,g,"bProcessing");o(e.oFeatures,g,"bAutoWidth");o(e.oFeatures,g,"bSortClasses");o(e.oFeatures,g,"bServerSide");o(e.oFeatures,g,"bDeferRender");o(e.oScroll,g,"sScrollX","sX");o(e.oScroll,g,"sScrollXInner","sXInner");o(e.oScroll,g,"sScrollY","sY");o(e.oScroll,g,"bScrollCollapse","bCollapse");o(e.oScroll,g,"bScrollInfinite",
-"bInfinite");o(e.oScroll,g,"iScrollLoadGap","iLoadGap");o(e.oScroll,g,"bScrollAutoCss","bAutoCss");o(e,g,"asStripClasses","asStripeClasses");o(e,g,"asStripeClasses");o(e,g,"fnPreDrawCallback");o(e,g,"fnRowCallback");o(e,g,"fnHeaderCallback");o(e,g,"fnFooterCallback");o(e,g,"fnCookieCallback");o(e,g,"fnInitComplete");o(e,g,"fnServerData");o(e,g,"fnFormatNumber");o(e,g,"aaSorting");o(e,g,"aaSortingFixed");o(e,g,"aLengthMenu");o(e,g,"sPaginationType");o(e,g,"sAjaxSource");o(e,g,"sAjaxDataProp");o(e,
-g,"iCookieDuration");o(e,g,"sCookiePrefix");o(e,g,"sDom");o(e,g,"bSortCellsTop");o(e,g,"oSearch","oPreviousSearch");o(e,g,"aoSearchCols","aoPreSearchCols");o(e,g,"iDisplayLength","_iDisplayLength");o(e,g,"bJQueryUI","bJUI");o(e.oLanguage,g,"fnInfoCallback");typeof g.fnDrawCallback=="function"&&e.aoDrawCallback.push({fn:g.fnDrawCallback,sName:"user"});typeof g.fnServerParams=="function"&&e.aoServerParams.push({fn:g.fnServerParams,sName:"user"});typeof g.fnStateSaveCallback=="function"&&e.aoStateSave.push({fn:g.fnStateSaveCallback,
-sName:"user"});typeof g.fnStateLoadCallback=="function"&&e.aoStateLoad.push({fn:g.fnStateLoadCallback,sName:"user"});if(e.oFeatures.bServerSide&&e.oFeatures.bSort&&e.oFeatures.bSortClasses)e.aoDrawCallback.push({fn:V,sName:"server_side_sort_classes"});else e.oFeatures.bDeferRender&&e.aoDrawCallback.push({fn:V,sName:"defer_sort_classes"});if(typeof g.bJQueryUI!="undefined"&&g.bJQueryUI){e.oClasses=n.oJUIClasses;if(typeof g.sDom=="undefined")e.sDom='<"H"lfr>t<"F"ip>'}if(e.oScroll.sX!==""||e.oScroll.sY!==
-"")e.oScroll.iBarWidth=Ya();if(typeof g.iDisplayStart!="undefined"&&typeof e.iInitDisplayStart=="undefined"){e.iInitDisplayStart=g.iDisplayStart;e._iDisplayStart=g.iDisplayStart}if(typeof g.bStateSave!="undefined"){e.oFeatures.bStateSave=g.bStateSave;Xa(e,g);e.aoDrawCallback.push({fn:va,sName:"state_save"})}if(typeof g.iDeferLoading!="undefined"){e.bDeferLoading=true;e._iRecordsTotal=g.iDeferLoading;e._iRecordsDisplay=g.iDeferLoading}if(typeof g.aaData!="undefined")j=true;if(typeof g!="undefined"&&
-typeof g.aoData!="undefined")g.aoColumns=g.aoData;if(typeof g.oLanguage!="undefined")if(typeof g.oLanguage.sUrl!="undefined"&&g.oLanguage.sUrl!==""){e.oLanguage.sUrl=g.oLanguage.sUrl;i.getJSON(e.oLanguage.sUrl,null,function(u){y(e,u,true)});h=true}else y(e,g.oLanguage,false)}else g={};if(typeof g.asStripClasses=="undefined"&&typeof g.asStripeClasses=="undefined"){e.asStripeClasses.push(e.oClasses.sStripeOdd);e.asStripeClasses.push(e.oClasses.sStripeEven)}c=false;d=i(this).children("tbody").children("tr");
-a=0;for(b=e.asStripeClasses.length;a<b;a++)if(d.filter(":lt(2)").hasClass(e.asStripeClasses[a])){c=true;break}if(c){e.asDestroyStripes=["",""];if(i(d[0]).hasClass(e.oClasses.sStripeOdd))e.asDestroyStripes[0]+=e.oClasses.sStripeOdd+" ";if(i(d[0]).hasClass(e.oClasses.sStripeEven))e.asDestroyStripes[0]+=e.oClasses.sStripeEven;if(i(d[1]).hasClass(e.oClasses.sStripeOdd))e.asDestroyStripes[1]+=e.oClasses.sStripeOdd+" ";if(i(d[1]).hasClass(e.oClasses.sStripeEven))e.asDestroyStripes[1]+=e.oClasses.sStripeEven;
-d.removeClass(e.asStripeClasses.join(" "))}c=[];var k;a=this.getElementsByTagName("thead");if(a.length!==0){Y(e.aoHeader,a[0]);c=S(e)}if(typeof g.aoColumns=="undefined"){k=[];a=0;for(b=c.length;a<b;a++)k.push(null)}else k=g.aoColumns;a=0;for(b=k.length;a<b;a++){if(typeof g.saved_aoColumns!="undefined"&&g.saved_aoColumns.length==b){if(k[a]===null)k[a]={};k[a].bVisible=g.saved_aoColumns[a].bVisible}F(e,c?c[a]:null)}if(typeof g.aoColumnDefs!="undefined")for(a=g.aoColumnDefs.length-1;a>=0;a--){var m=
-g.aoColumnDefs[a].aTargets;i.isArray(m)||J(e,1,"aTargets must be an array of targets, not a "+typeof m);c=0;for(d=m.length;c<d;c++)if(typeof m[c]=="number"&&m[c]>=0){for(;e.aoColumns.length<=m[c];)F(e);x(e,m[c],g.aoColumnDefs[a])}else if(typeof m[c]=="number"&&m[c]<0)x(e,e.aoColumns.length+m[c],g.aoColumnDefs[a]);else if(typeof m[c]=="string"){b=0;for(f=e.aoColumns.length;b<f;b++)if(m[c]=="_all"||i(e.aoColumns[b].nTh).hasClass(m[c]))x(e,b,g.aoColumnDefs[a])}}if(typeof k!="undefined"){a=0;for(b=k.length;a<
-b;a++)x(e,a,k[a])}a=0;for(b=e.aaSorting.length;a<b;a++){if(e.aaSorting[a][0]>=e.aoColumns.length)e.aaSorting[a][0]=0;k=e.aoColumns[e.aaSorting[a][0]];if(typeof e.aaSorting[a][2]=="undefined")e.aaSorting[a][2]=0;if(typeof g.aaSorting=="undefined"&&typeof e.saved_aaSorting=="undefined")e.aaSorting[a][1]=k.asSorting[0];c=0;for(d=k.asSorting.length;c<d;c++)if(e.aaSorting[a][1]==k.asSorting[c]){e.aaSorting[a][2]=c;break}}V(e);a=i(this).children("thead");if(a.length===0){a=[p.createElement("thead")];this.appendChild(a[0])}e.nTHead=
-a[0];a=i(this).children("tbody");if(a.length===0){a=[p.createElement("tbody")];this.appendChild(a[0])}e.nTBody=a[0];a=i(this).children("tfoot");if(a.length>0){e.nTFoot=a[0];Y(e.aoFooter,e.nTFoot)}if(j)for(a=0;a<g.aaData.length;a++)v(e,g.aaData[a]);else $(e);e.aiDisplay=e.aiDisplayMaster.slice();e.bInitialised=true;h===false&&t(e)}})}})(jQuery,window,document);

+ 0 - 1277
desktop/core/src/desktop/static/desktop/ext/js/jquery/plugins/jquery.form.js

@@ -1,1277 +0,0 @@
-/*!
- * jQuery Form Plugin
- * version: 3.51.0-2014.06.20
- * Requires jQuery v1.5 or later
- * Copyright (c) 2014 M. Alsup
- * Examples and documentation at: http://malsup.com/jquery/form/
- * Project repository: https://github.com/malsup/form
- * Dual licensed under the MIT and GPL licenses.
- * https://github.com/malsup/form#copyright-and-license
- */
-/*global ActiveXObject */
-
-// AMD support
-(function (factory) {
-    "use strict";
-    if (typeof define === 'function' && define.amd) {
-        // using AMD; register as anon module
-        define(['jquery'], factory);
-    } else {
-        // no AMD; invoke directly
-        factory( (typeof(jQuery) != 'undefined') ? jQuery : window.Zepto );
-    }
-}
-
-(function($) {
-"use strict";
-
-/*
-    Usage Note:
-    -----------
-    Do not use both ajaxSubmit and ajaxForm on the same form.  These
-    functions are mutually exclusive.  Use ajaxSubmit if you want
-    to bind your own submit handler to the form.  For example,
-
-    $(document).ready(function() {
-        $('#myForm').on('submit', function(e) {
-            e.preventDefault(); // <-- important
-            $(this).ajaxSubmit({
-                target: '#output'
-            });
-        });
-    });
-
-    Use ajaxForm when you want the plugin to manage all the event binding
-    for you.  For example,
-
-    $(document).ready(function() {
-        $('#myForm').ajaxForm({
-            target: '#output'
-        });
-    });
-
-    You can also use ajaxForm with delegation (requires jQuery v1.7+), so the
-    form does not have to exist when you invoke ajaxForm:
-
-    $('#myForm').ajaxForm({
-        delegation: true,
-        target: '#output'
-    });
-
-    When using ajaxForm, the ajaxSubmit function will be invoked for you
-    at the appropriate time.
-*/
-
-/**
- * Feature detection
- */
-var feature = {};
-feature.fileapi = $("<input type='file'/>").get(0).files !== undefined;
-feature.formdata = window.FormData !== undefined;
-
-var hasProp = !!$.fn.prop;
-
-// attr2 uses prop when it can but checks the return type for
-// an expected string.  this accounts for the case where a form 
-// contains inputs with names like "action" or "method"; in those
-// cases "prop" returns the element
-$.fn.attr2 = function() {
-    if ( ! hasProp ) {
-        return this.attr.apply(this, arguments);
-    }
-    var val = this.prop.apply(this, arguments);
-    if ( ( val && val.jquery ) || typeof val === 'string' ) {
-        return val;
-    }
-    return this.attr.apply(this, arguments);
-};
-
-/**
- * ajaxSubmit() provides a mechanism for immediately submitting
- * an HTML form using AJAX.
- */
-$.fn.ajaxSubmit = function(options) {
-    /*jshint scripturl:true */
-
-    // fast fail if nothing selected (http://dev.jquery.com/ticket/2752)
-    if (!this.length) {
-        log('ajaxSubmit: skipping submit process - no element selected');
-        return this;
-    }
-
-    var method, action, url, $form = this;
-
-    if (typeof options == 'function') {
-        options = { success: options };
-    }
-    else if ( options === undefined ) {
-        options = {};
-    }
-
-    method = options.type || this.attr2('method');
-    action = options.url  || this.attr2('action');
-
-    url = (typeof action === 'string') ? $.trim(action) : '';
-    url = url || window.location.href || '';
-    if (url) {
-        // clean url (don't include hash vaue)
-        url = (url.match(/^([^#]+)/)||[])[1];
-    }
-
-    options = $.extend(true, {
-        url:  url,
-        success: $.ajaxSettings.success,
-        type: method || $.ajaxSettings.type,
-        iframeSrc: /^https/i.test(window.location.href || '') ? 'javascript:false' : 'about:blank'
-    }, options);
-
-    // hook for manipulating the form data before it is extracted;
-    // convenient for use with rich editors like tinyMCE or FCKEditor
-    var veto = {};
-    this.trigger('form-pre-serialize', [this, options, veto]);
-    if (veto.veto) {
-        log('ajaxSubmit: submit vetoed via form-pre-serialize trigger');
-        return this;
-    }
-
-    // provide opportunity to alter form data before it is serialized
-    if (options.beforeSerialize && options.beforeSerialize(this, options) === false) {
-        log('ajaxSubmit: submit aborted via beforeSerialize callback');
-        return this;
-    }
-
-    var traditional = options.traditional;
-    if ( traditional === undefined ) {
-        traditional = $.ajaxSettings.traditional;
-    }
-
-    var elements = [];
-    var qx, a = this.formToArray(options.semantic, elements);
-    if (options.data) {
-        options.extraData = options.data;
-        qx = $.param(options.data, traditional);
-    }
-
-    // give pre-submit callback an opportunity to abort the submit
-    if (options.beforeSubmit && options.beforeSubmit(a, this, options) === false) {
-        log('ajaxSubmit: submit aborted via beforeSubmit callback');
-        return this;
-    }
-
-    // fire vetoable 'validate' event
-    this.trigger('form-submit-validate', [a, this, options, veto]);
-    if (veto.veto) {
-        log('ajaxSubmit: submit vetoed via form-submit-validate trigger');
-        return this;
-    }
-
-    var q = $.param(a, traditional);
-    if (qx) {
-        q = ( q ? (q + '&' + qx) : qx );
-    }
-    if (options.type.toUpperCase() == 'GET') {
-        options.url += (options.url.indexOf('?') >= 0 ? '&' : '?') + q;
-        options.data = null;  // data is null for 'get'
-    }
-    else {
-        options.data = q; // data is the query string for 'post'
-    }
-
-    var callbacks = [];
-    if (options.resetForm) {
-        callbacks.push(function() { $form.resetForm(); });
-    }
-    if (options.clearForm) {
-        callbacks.push(function() { $form.clearForm(options.includeHidden); });
-    }
-
-    // perform a load on the target only if dataType is not provided
-    if (!options.dataType && options.target) {
-        var oldSuccess = options.success || function(){};
-        callbacks.push(function(data) {
-            var fn = options.replaceTarget ? 'replaceWith' : 'html';
-            $(options.target)[fn](data).each(oldSuccess, arguments);
-        });
-    }
-    else if (options.success) {
-        callbacks.push(options.success);
-    }
-
-    options.success = function(data, status, xhr) { // jQuery 1.4+ passes xhr as 3rd arg
-        var context = options.context || this ;    // jQuery 1.4+ supports scope context
-        for (var i=0, max=callbacks.length; i < max; i++) {
-            callbacks[i].apply(context, [data, status, xhr || $form, $form]);
-        }
-    };
-
-    if (options.error) {
-        var oldError = options.error;
-        options.error = function(xhr, status, error) {
-            var context = options.context || this;
-            oldError.apply(context, [xhr, status, error, $form]);
-        };
-    }
-
-     if (options.complete) {
-        var oldComplete = options.complete;
-        options.complete = function(xhr, status) {
-            var context = options.context || this;
-            oldComplete.apply(context, [xhr, status, $form]);
-        };
-    }
-
-    // are there files to upload?
-
-    // [value] (issue #113), also see comment:
-    // https://github.com/malsup/form/commit/588306aedba1de01388032d5f42a60159eea9228#commitcomment-2180219
-    var fileInputs = $('input[type=file]:enabled', this).filter(function() { return $(this).val() !== ''; });
-
-    var hasFileInputs = fileInputs.length > 0;
-    var mp = 'multipart/form-data';
-    var multipart = ($form.attr('enctype') == mp || $form.attr('encoding') == mp);
-
-    var fileAPI = feature.fileapi && feature.formdata;
-    log("fileAPI :" + fileAPI);
-    var shouldUseFrame = (hasFileInputs || multipart) && !fileAPI;
-
-    var jqxhr;
-
-    // options.iframe allows user to force iframe mode
-    // 06-NOV-09: now defaulting to iframe mode if file input is detected
-    if (options.iframe !== false && (options.iframe || shouldUseFrame)) {
-        // hack to fix Safari hang (thanks to Tim Molendijk for this)
-        // see:  http://groups.google.com/group/jquery-dev/browse_thread/thread/36395b7ab510dd5d
-        if (options.closeKeepAlive) {
-            $.get(options.closeKeepAlive, function() {
-                jqxhr = fileUploadIframe(a);
-            });
-        }
-        else {
-            jqxhr = fileUploadIframe(a);
-        }
-    }
-    else if ((hasFileInputs || multipart) && fileAPI) {
-        jqxhr = fileUploadXhr(a);
-    }
-    else {
-        jqxhr = $.ajax(options);
-    }
-
-    $form.removeData('jqxhr').data('jqxhr', jqxhr);
-
-    // clear element array
-    for (var k=0; k < elements.length; k++) {
-        elements[k] = null;
-    }
-
-    // fire 'notify' event
-    this.trigger('form-submit-notify', [this, options]);
-    return this;
-
-    // utility fn for deep serialization
-    function deepSerialize(extraData){
-        var serialized = $.param(extraData, options.traditional).split('&');
-        var len = serialized.length;
-        var result = [];
-        var i, part;
-        for (i=0; i < len; i++) {
-            // #252; undo param space replacement
-            serialized[i] = serialized[i].replace(/\+/g,' ');
-            part = serialized[i].split('=');
-            // #278; use array instead of object storage, favoring array serializations
-            result.push([decodeURIComponent(part[0]), decodeURIComponent(part[1])]);
-        }
-        return result;
-    }
-
-     // XMLHttpRequest Level 2 file uploads (big hat tip to francois2metz)
-    function fileUploadXhr(a) {
-        var formdata = new FormData();
-
-        for (var i=0; i < a.length; i++) {
-            formdata.append(a[i].name, a[i].value);
-        }
-
-        if (options.extraData) {
-            var serializedData = deepSerialize(options.extraData);
-            for (i=0; i < serializedData.length; i++) {
-                if (serializedData[i]) {
-                    formdata.append(serializedData[i][0], serializedData[i][1]);
-                }
-            }
-        }
-
-        options.data = null;
-
-        var s = $.extend(true, {}, $.ajaxSettings, options, {
-            contentType: false,
-            processData: false,
-            cache: false,
-            type: method || 'POST'
-        });
-
-        if (options.uploadProgress) {
-            // workaround because jqXHR does not expose upload property
-            s.xhr = function() {
-                var xhr = $.ajaxSettings.xhr();
-                if (xhr.upload) {
-                    xhr.upload.addEventListener('progress', function(event) {
-                        var percent = 0;
-                        var position = event.loaded || event.position; /*event.position is deprecated*/
-                        var total = event.total;
-                        if (event.lengthComputable) {
-                            percent = Math.ceil(position / total * 100);
-                        }
-                        options.uploadProgress(event, position, total, percent);
-                    }, false);
-                }
-                return xhr;
-            };
-        }
-
-        s.data = null;
-        var beforeSend = s.beforeSend;
-        s.beforeSend = function(xhr, o) {
-            //Send FormData() provided by user
-            if (options.formData) {
-                o.data = options.formData;
-            }
-            else {
-                o.data = formdata;
-            }
-            if(beforeSend) {
-                beforeSend.call(this, xhr, o);
-            }
-        };
-        return $.ajax(s);
-    }
-
-    // private function for handling file uploads (hat tip to YAHOO!)
-    function fileUploadIframe(a) {
-        var form = $form[0], el, i, s, g, id, $io, io, xhr, sub, n, timedOut, timeoutHandle;
-        var deferred = $.Deferred();
-
-        // #341
-        deferred.abort = function(status) {
-            xhr.abort(status);
-        };
-
-        if (a) {
-            // ensure that every serialized input is still enabled
-            for (i=0; i < elements.length; i++) {
-                el = $(elements[i]);
-                if ( hasProp ) {
-                    el.prop('disabled', false);
-                }
-                else {
-                    el.removeAttr('disabled');
-                }
-            }
-        }
-
-        s = $.extend(true, {}, $.ajaxSettings, options);
-        s.context = s.context || s;
-        id = 'jqFormIO' + (new Date().getTime());
-        if (s.iframeTarget) {
-            $io = $(s.iframeTarget);
-            n = $io.attr2('name');
-            if (!n) {
-                $io.attr2('name', id);
-            }
-            else {
-                id = n;
-            }
-        }
-        else {
-            $io = $('<iframe name="' + id + '" src="'+ s.iframeSrc +'" />');
-            $io.css({ position: 'absolute', top: '-1000px', left: '-1000px' });
-        }
-        io = $io[0];
-
-
-        xhr = { // mock object
-            aborted: 0,
-            responseText: null,
-            responseXML: null,
-            status: 0,
-            statusText: 'n/a',
-            getAllResponseHeaders: function() {},
-            getResponseHeader: function() {},
-            setRequestHeader: function() {},
-            abort: function(status) {
-                var e = (status === 'timeout' ? 'timeout' : 'aborted');
-                log('aborting upload... ' + e);
-                this.aborted = 1;
-
-                try { // #214, #257
-                    if (io.contentWindow.document.execCommand) {
-                        io.contentWindow.document.execCommand('Stop');
-                    }
-                }
-                catch(ignore) {}
-
-                $io.attr('src', s.iframeSrc); // abort op in progress
-                xhr.error = e;
-                if (s.error) {
-                    s.error.call(s.context, xhr, e, status);
-                }
-                if (g) {
-                    $.event.trigger("ajaxError", [xhr, s, e]);
-                }
-                if (s.complete) {
-                    s.complete.call(s.context, xhr, e);
-                }
-            }
-        };
-
-        g = s.global;
-        // trigger ajax global events so that activity/block indicators work like normal
-        if (g && 0 === $.active++) {
-            $.event.trigger("ajaxStart");
-        }
-        if (g) {
-            $.event.trigger("ajaxSend", [xhr, s]);
-        }
-
-        if (s.beforeSend && s.beforeSend.call(s.context, xhr, s) === false) {
-            if (s.global) {
-                $.active--;
-            }
-            deferred.reject();
-            return deferred;
-        }
-        if (xhr.aborted) {
-            deferred.reject();
-            return deferred;
-        }
-
-        // add submitting element to data if we know it
-        sub = form.clk;
-        if (sub) {
-            n = sub.name;
-            if (n && !sub.disabled) {
-                s.extraData = s.extraData || {};
-                s.extraData[n] = sub.value;
-                if (sub.type == "image") {
-                    s.extraData[n+'.x'] = form.clk_x;
-                    s.extraData[n+'.y'] = form.clk_y;
-                }
-            }
-        }
-
-        var CLIENT_TIMEOUT_ABORT = 1;
-        var SERVER_ABORT = 2;
-                
-        function getDoc(frame) {
-            /* it looks like contentWindow or contentDocument do not
-             * carry the protocol property in ie8, when running under ssl
-             * frame.document is the only valid response document, since
-             * the protocol is know but not on the other two objects. strange?
-             * "Same origin policy" http://en.wikipedia.org/wiki/Same_origin_policy
-             */
-            
-            var doc = null;
-            
-            // IE8 cascading access check
-            try {
-                if (frame.contentWindow) {
-                    doc = frame.contentWindow.document;
-                }
-            } catch(err) {
-                // IE8 access denied under ssl & missing protocol
-                log('cannot get iframe.contentWindow document: ' + err);
-            }
-
-            if (doc) { // successful getting content
-                return doc;
-            }
-
-            try { // simply checking may throw in ie8 under ssl or mismatched protocol
-                doc = frame.contentDocument ? frame.contentDocument : frame.document;
-            } catch(err) {
-                // last attempt
-                log('cannot get iframe.contentDocument: ' + err);
-                doc = frame.document;
-            }
-            return doc;
-        }
-
-        // Rails CSRF hack (thanks to Yvan Barthelemy)
-        var csrf_token = $('meta[name=csrf-token]').attr('content');
-        var csrf_param = $('meta[name=csrf-param]').attr('content');
-        if (csrf_param && csrf_token) {
-            s.extraData = s.extraData || {};
-            s.extraData[csrf_param] = csrf_token;
-        }
-
-        // take a breath so that pending repaints get some cpu time before the upload starts
-        function doSubmit() {
-            // make sure form attrs are set
-            var t = $form.attr2('target'), 
-                a = $form.attr2('action'), 
-                mp = 'multipart/form-data',
-                et = $form.attr('enctype') || $form.attr('encoding') || mp;
-
-            // update form attrs in IE friendly way
-            form.setAttribute('target',id);
-            if (!method || /post/i.test(method) ) {
-                form.setAttribute('method', 'POST');
-            }
-            if (a != s.url) {
-                form.setAttribute('action', s.url);
-            }
-
-            // ie borks in some cases when setting encoding
-            if (! s.skipEncodingOverride && (!method || /post/i.test(method))) {
-                $form.attr({
-                    encoding: 'multipart/form-data',
-                    enctype:  'multipart/form-data'
-                });
-            }
-
-            // support timout
-            if (s.timeout) {
-                timeoutHandle = setTimeout(function() { timedOut = true; cb(CLIENT_TIMEOUT_ABORT); }, s.timeout);
-            }
-
-            // look for server aborts
-            function checkState() {
-                try {
-                    var state = getDoc(io).readyState;
-                    log('state = ' + state);
-                    if (state && state.toLowerCase() == 'uninitialized') {
-                        setTimeout(checkState,50);
-                    }
-                }
-                catch(e) {
-                    log('Server abort: ' , e, ' (', e.name, ')');
-                    cb(SERVER_ABORT);
-                    if (timeoutHandle) {
-                        clearTimeout(timeoutHandle);
-                    }
-                    timeoutHandle = undefined;
-                }
-            }
-
-            // add "extra" data to form if provided in options
-            var extraInputs = [];
-            try {
-                if (s.extraData) {
-                    for (var n in s.extraData) {
-                        if (s.extraData.hasOwnProperty(n)) {
-                           // if using the $.param format that allows for multiple values with the same name
-                           if($.isPlainObject(s.extraData[n]) && s.extraData[n].hasOwnProperty('name') && s.extraData[n].hasOwnProperty('value')) {
-                               extraInputs.push(
-                               $('<input type="hidden" name="'+s.extraData[n].name+'">').val(s.extraData[n].value)
-                                   .appendTo(form)[0]);
-                           } else {
-                               extraInputs.push(
-                               $('<input type="hidden" name="'+n+'">').val(s.extraData[n])
-                                   .appendTo(form)[0]);
-                           }
-                        }
-                    }
-                }
-
-                if (!s.iframeTarget) {
-                    // add iframe to doc and submit the form
-                    $io.appendTo('body');
-                }
-                if (io.attachEvent) {
-                    io.attachEvent('onload', cb);
-                }
-                else {
-                    io.addEventListener('load', cb, false);
-                }
-                setTimeout(checkState,15);
-
-                try {
-                    form.submit();
-                } catch(err) {
-                    // just in case form has element with name/id of 'submit'
-                    var submitFn = document.createElement('form').submit;
-                    submitFn.apply(form);
-                }
-            }
-            finally {
-                // reset attrs and remove "extra" input elements
-                form.setAttribute('action',a);
-                form.setAttribute('enctype', et); // #380
-                if(t) {
-                    form.setAttribute('target', t);
-                } else {
-                    $form.removeAttr('target');
-                }
-                $(extraInputs).remove();
-            }
-        }
-
-        if (s.forceSync) {
-            doSubmit();
-        }
-        else {
-            setTimeout(doSubmit, 10); // this lets dom updates render
-        }
-
-        var data, doc, domCheckCount = 50, callbackProcessed;
-
-        function cb(e) {
-            if (xhr.aborted || callbackProcessed) {
-                return;
-            }
-            
-            doc = getDoc(io);
-            if(!doc) {
-                log('cannot access response document');
-                e = SERVER_ABORT;
-            }
-            if (e === CLIENT_TIMEOUT_ABORT && xhr) {
-                xhr.abort('timeout');
-                deferred.reject(xhr, 'timeout');
-                return;
-            }
-            else if (e == SERVER_ABORT && xhr) {
-                xhr.abort('server abort');
-                deferred.reject(xhr, 'error', 'server abort');
-                return;
-            }
-
-            if (!doc || doc.location.href == s.iframeSrc) {
-                // response not received yet
-                if (!timedOut) {
-                    return;
-                }
-            }
-            if (io.detachEvent) {
-                io.detachEvent('onload', cb);
-            }
-            else {
-                io.removeEventListener('load', cb, false);
-            }
-
-            var status = 'success', errMsg;
-            try {
-                if (timedOut) {
-                    throw 'timeout';
-                }
-
-                var isXml = s.dataType == 'xml' || doc.XMLDocument || $.isXMLDoc(doc);
-                log('isXml='+isXml);
-                if (!isXml && window.opera && (doc.body === null || !doc.body.innerHTML)) {
-                    if (--domCheckCount) {
-                        // in some browsers (Opera) the iframe DOM is not always traversable when
-                        // the onload callback fires, so we loop a bit to accommodate
-                        log('requeing onLoad callback, DOM not available');
-                        setTimeout(cb, 250);
-                        return;
-                    }
-                    // let this fall through because server response could be an empty document
-                    //log('Could not access iframe DOM after mutiple tries.');
-                    //throw 'DOMException: not available';
-                }
-
-                //log('response detected');
-                var docRoot = doc.body ? doc.body : doc.documentElement;
-                xhr.responseText = docRoot ? docRoot.innerHTML : null;
-                xhr.responseXML = doc.XMLDocument ? doc.XMLDocument : doc;
-                if (isXml) {
-                    s.dataType = 'xml';
-                }
-                xhr.getResponseHeader = function(header){
-                    var headers = {'content-type': s.dataType};
-                    return headers[header.toLowerCase()];
-                };
-                // support for XHR 'status' & 'statusText' emulation :
-                if (docRoot) {
-                    xhr.status = Number( docRoot.getAttribute('status') ) || xhr.status;
-                    xhr.statusText = docRoot.getAttribute('statusText') || xhr.statusText;
-                }
-
-                var dt = (s.dataType || '').toLowerCase();
-                var scr = /(json|script|text)/.test(dt);
-                if (scr || s.textarea) {
-                    // see if user embedded response in textarea
-                    var ta = doc.getElementsByTagName('textarea')[0];
-                    if (ta) {
-                        xhr.responseText = ta.value;
-                        // support for XHR 'status' & 'statusText' emulation :
-                        xhr.status = Number( ta.getAttribute('status') ) || xhr.status;
-                        xhr.statusText = ta.getAttribute('statusText') || xhr.statusText;
-                    }
-                    else if (scr) {
-                        // account for browsers injecting pre around json response
-                        var pre = doc.getElementsByTagName('pre')[0];
-                        var b = doc.getElementsByTagName('body')[0];
-                        if (pre) {
-                            xhr.responseText = pre.textContent ? pre.textContent : pre.innerText;
-                        }
-                        else if (b) {
-                            xhr.responseText = b.textContent ? b.textContent : b.innerText;
-                        }
-                    }
-                }
-                else if (dt == 'xml' && !xhr.responseXML && xhr.responseText) {
-                    xhr.responseXML = toXml(xhr.responseText);
-                }
-
-                try {
-                    data = httpData(xhr, dt, s);
-                }
-                catch (err) {
-                    status = 'parsererror';
-                    xhr.error = errMsg = (err || status);
-                }
-            }
-            catch (err) {
-                log('error caught: ',err);
-                status = 'error';
-                xhr.error = errMsg = (err || status);
-            }
-
-            if (xhr.aborted) {
-                log('upload aborted');
-                status = null;
-            }
-
-            if (xhr.status) { // we've set xhr.status
-                status = (xhr.status >= 200 && xhr.status < 300 || xhr.status === 304) ? 'success' : 'error';
-            }
-
-            // ordering of these callbacks/triggers is odd, but that's how $.ajax does it
-            if (status === 'success') {
-                if (s.success) {
-                    s.success.call(s.context, data, 'success', xhr);
-                }
-                deferred.resolve(xhr.responseText, 'success', xhr);
-                if (g) {
-                    $.event.trigger("ajaxSuccess", [xhr, s]);
-                }
-            }
-            else if (status) {
-                if (errMsg === undefined) {
-                    errMsg = xhr.statusText;
-                }
-                if (s.error) {
-                    s.error.call(s.context, xhr, status, errMsg);
-                }
-                deferred.reject(xhr, 'error', errMsg);
-                if (g) {
-                    $.event.trigger("ajaxError", [xhr, s, errMsg]);
-                }
-            }
-
-            if (g) {
-                $.event.trigger("ajaxComplete", [xhr, s]);
-            }
-
-            if (g && ! --$.active) {
-                $.event.trigger("ajaxStop");
-            }
-
-            if (s.complete) {
-                s.complete.call(s.context, xhr, status);
-            }
-
-            callbackProcessed = true;
-            if (s.timeout) {
-                clearTimeout(timeoutHandle);
-            }
-
-            // clean up
-            setTimeout(function() {
-                if (!s.iframeTarget) {
-                    $io.remove();
-                }
-                else { //adding else to clean up existing iframe response.
-                    $io.attr('src', s.iframeSrc);
-                }
-                xhr.responseXML = null;
-            }, 100);
-        }
-
-        var toXml = $.parseXML || function(s, doc) { // use parseXML if available (jQuery 1.5+)
-            if (window.ActiveXObject) {
-                doc = new ActiveXObject('Microsoft.XMLDOM');
-                doc.async = 'false';
-                doc.loadXML(s);
-            }
-            else {
-                doc = (new DOMParser()).parseFromString(s, 'text/xml');
-            }
-            return (doc && doc.documentElement && doc.documentElement.nodeName != 'parsererror') ? doc : null;
-        };
-        var parseJSON = $.parseJSON || function(s) {
-            /*jslint evil:true */
-            return window['eval']('(' + s + ')');
-        };
-
-        var httpData = function( xhr, type, s ) { // mostly lifted from jq1.4.4
-
-            var ct = xhr.getResponseHeader('content-type') || '',
-                xml = type === 'xml' || !type && ct.indexOf('xml') >= 0,
-                data = xml ? xhr.responseXML : xhr.responseText;
-
-            if (xml && data.documentElement.nodeName === 'parsererror') {
-                if ($.error) {
-                    $.error('parsererror');
-                }
-            }
-            if (s && s.dataFilter) {
-                data = s.dataFilter(data, type);
-            }
-            if (typeof data === 'string') {
-                if (type === 'json' || !type && ct.indexOf('json') >= 0) {
-                    data = parseJSON(data);
-                } else if (type === "script" || !type && ct.indexOf("javascript") >= 0) {
-                    $.globalEval(data);
-                }
-            }
-            return data;
-        };
-
-        return deferred;
-    }
-};
-
-/**
- * ajaxForm() provides a mechanism for fully automating form submission.
- *
- * The advantages of using this method instead of ajaxSubmit() are:
- *
- * 1: This method will include coordinates for <input type="image" /> elements (if the element
- *    is used to submit the form).
- * 2. This method will include the submit element's name/value data (for the element that was
- *    used to submit the form).
- * 3. This method binds the submit() method to the form for you.
- *
- * The options argument for ajaxForm works exactly as it does for ajaxSubmit.  ajaxForm merely
- * passes the options argument along after properly binding events for submit elements and
- * the form itself.
- */
-$.fn.ajaxForm = function(options) {
-    options = options || {};
-    options.delegation = options.delegation && $.isFunction($.fn.on);
-
-    // in jQuery 1.3+ we can fix mistakes with the ready state
-    if (!options.delegation && this.length === 0) {
-        var o = { s: this.selector, c: this.context };
-        if (!$.isReady && o.s) {
-            log('DOM not ready, queuing ajaxForm');
-            $(function() {
-                $(o.s,o.c).ajaxForm(options);
-            });
-            return this;
-        }
-        // is your DOM ready?  http://docs.jquery.com/Tutorials:Introducing_$(document).ready()
-        log('terminating; zero elements found by selector' + ($.isReady ? '' : ' (DOM not ready)'));
-        return this;
-    }
-
-    if ( options.delegation ) {
-        $(document)
-            .off('submit.form-plugin', this.selector, doAjaxSubmit)
-            .off('click.form-plugin', this.selector, captureSubmittingElement)
-            .on('submit.form-plugin', this.selector, options, doAjaxSubmit)
-            .on('click.form-plugin', this.selector, options, captureSubmittingElement);
-        return this;
-    }
-
-    return this.ajaxFormUnbind()
-        .bind('submit.form-plugin', options, doAjaxSubmit)
-        .bind('click.form-plugin', options, captureSubmittingElement);
-};
-
-// private event handlers
-function doAjaxSubmit(e) {
-    /*jshint validthis:true */
-    var options = e.data;
-    if (!e.isDefaultPrevented()) { // if event has been canceled, don't proceed
-        e.preventDefault();
-        $(e.target).ajaxSubmit(options); // #365
-    }
-}
-
-function captureSubmittingElement(e) {
-    /*jshint validthis:true */
-    var target = e.target;
-    var $el = $(target);
-    if (!($el.is("[type=submit],[type=image]"))) {
-        // is this a child element of the submit el?  (ex: a span within a button)
-        var t = $el.closest('[type=submit]');
-        if (t.length === 0) {
-            return;
-        }
-        target = t[0];
-    }
-    var form = this;
-    form.clk = target;
-    if (target.type == 'image') {
-        if (e.offsetX !== undefined) {
-            form.clk_x = e.offsetX;
-            form.clk_y = e.offsetY;
-        } else if (typeof $.fn.offset == 'function') {
-            var offset = $el.offset();
-            form.clk_x = e.pageX - offset.left;
-            form.clk_y = e.pageY - offset.top;
-        } else {
-            form.clk_x = e.pageX - target.offsetLeft;
-            form.clk_y = e.pageY - target.offsetTop;
-        }
-    }
-    // clear form vars
-    setTimeout(function() { form.clk = form.clk_x = form.clk_y = null; }, 100);
-}
-
-
-// ajaxFormUnbind unbinds the event handlers that were bound by ajaxForm
-$.fn.ajaxFormUnbind = function() {
-    return this.unbind('submit.form-plugin click.form-plugin');
-};
-
-/**
- * formToArray() gathers form element data into an array of objects that can
- * be passed to any of the following ajax functions: $.get, $.post, or load.
- * Each object in the array has both a 'name' and 'value' property.  An example of
- * an array for a simple login form might be:
- *
- * [ { name: 'username', value: 'jresig' }, { name: 'password', value: 'secret' } ]
- *
- * It is this array that is passed to pre-submit callback functions provided to the
- * ajaxSubmit() and ajaxForm() methods.
- */
-$.fn.formToArray = function(semantic, elements) {
-    var a = [];
-    if (this.length === 0) {
-        return a;
-    }
-
-    var form = this[0];
-    var formId = this.attr('id');
-    var els = semantic ? form.getElementsByTagName('*') : form.elements;
-    var els2;
-
-    if (els && !/MSIE [678]/.test(navigator.userAgent)) { // #390
-        els = $(els).get();  // convert to standard array
-    }
-
-    // #386; account for inputs outside the form which use the 'form' attribute
-    if ( formId ) {
-        els2 = $(':input[form="' + formId + '"]').get(); // hat tip @thet
-        if ( els2.length ) {
-            els = (els || []).concat(els2);
-        }
-    }
-
-    if (!els || !els.length) {
-        return a;
-    }
-
-    var i,j,n,v,el,max,jmax;
-    for(i=0, max=els.length; i < max; i++) {
-        el = els[i];
-        n = el.name;
-        if (!n || el.disabled) {
-            continue;
-        }
-
-        if (semantic && form.clk && el.type == "image") {
-            // handle image inputs on the fly when semantic == true
-            if(form.clk == el) {
-                a.push({name: n, value: $(el).val(), type: el.type });
-                a.push({name: n+'.x', value: form.clk_x}, {name: n+'.y', value: form.clk_y});
-            }
-            continue;
-        }
-
-        v = $.fieldValue(el, true);
-        if (v && v.constructor == Array) {
-            if (elements) {
-                elements.push(el);
-            }
-            for(j=0, jmax=v.length; j < jmax; j++) {
-                a.push({name: n, value: v[j]});
-            }
-        }
-        else if (feature.fileapi && el.type == 'file') {
-            if (elements) {
-                elements.push(el);
-            }
-            var files = el.files;
-            if (files.length) {
-                for (j=0; j < files.length; j++) {
-                    a.push({name: n, value: files[j], type: el.type});
-                }
-            }
-            else {
-                // #180
-                a.push({ name: n, value: '', type: el.type });
-            }
-        }
-        else if (v !== null && typeof v != 'undefined') {
-            if (elements) {
-                elements.push(el);
-            }
-            a.push({name: n, value: v, type: el.type, required: el.required});
-        }
-    }
-
-    if (!semantic && form.clk) {
-        // input type=='image' are not found in elements array! handle it here
-        var $input = $(form.clk), input = $input[0];
-        n = input.name;
-        if (n && !input.disabled && input.type == 'image') {
-            a.push({name: n, value: $input.val()});
-            a.push({name: n+'.x', value: form.clk_x}, {name: n+'.y', value: form.clk_y});
-        }
-    }
-    return a;
-};
-
-/**
- * Serializes form data into a 'submittable' string. This method will return a string
- * in the format: name1=value1&amp;name2=value2
- */
-$.fn.formSerialize = function(semantic) {
-    //hand off to jQuery.param for proper encoding
-    return $.param(this.formToArray(semantic));
-};
-
-/**
- * Serializes all field elements in the jQuery object into a query string.
- * This method will return a string in the format: name1=value1&amp;name2=value2
- */
-$.fn.fieldSerialize = function(successful) {
-    var a = [];
-    this.each(function() {
-        var n = this.name;
-        if (!n) {
-            return;
-        }
-        var v = $.fieldValue(this, successful);
-        if (v && v.constructor == Array) {
-            for (var i=0,max=v.length; i < max; i++) {
-                a.push({name: n, value: v[i]});
-            }
-        }
-        else if (v !== null && typeof v != 'undefined') {
-            a.push({name: this.name, value: v});
-        }
-    });
-    //hand off to jQuery.param for proper encoding
-    return $.param(a);
-};
-
-/**
- * Returns the value(s) of the element in the matched set.  For example, consider the following form:
- *
- *  <form><fieldset>
- *      <input name="A" type="text" />
- *      <input name="A" type="text" />
- *      <input name="B" type="checkbox" value="B1" />
- *      <input name="B" type="checkbox" value="B2"/>
- *      <input name="C" type="radio" value="C1" />
- *      <input name="C" type="radio" value="C2" />
- *  </fieldset></form>
- *
- *  var v = $('input[type=text]').fieldValue();
- *  // if no values are entered into the text inputs
- *  v == ['','']
- *  // if values entered into the text inputs are 'foo' and 'bar'
- *  v == ['foo','bar']
- *
- *  var v = $('input[type=checkbox]').fieldValue();
- *  // if neither checkbox is checked
- *  v === undefined
- *  // if both checkboxes are checked
- *  v == ['B1', 'B2']
- *
- *  var v = $('input[type=radio]').fieldValue();
- *  // if neither radio is checked
- *  v === undefined
- *  // if first radio is checked
- *  v == ['C1']
- *
- * The successful argument controls whether or not the field element must be 'successful'
- * (per http://www.w3.org/TR/html4/interact/forms.html#successful-controls).
- * The default value of the successful argument is true.  If this value is false the value(s)
- * for each element is returned.
- *
- * Note: This method *always* returns an array.  If no valid value can be determined the
- *    array will be empty, otherwise it will contain one or more values.
- */
-$.fn.fieldValue = function(successful) {
-    for (var val=[], i=0, max=this.length; i < max; i++) {
-        var el = this[i];
-        var v = $.fieldValue(el, successful);
-        if (v === null || typeof v == 'undefined' || (v.constructor == Array && !v.length)) {
-            continue;
-        }
-        if (v.constructor == Array) {
-            $.merge(val, v);
-        }
-        else {
-            val.push(v);
-        }
-    }
-    return val;
-};
-
-/**
- * Returns the value of the field element.
- */
-$.fieldValue = function(el, successful) {
-    var n = el.name, t = el.type, tag = el.tagName.toLowerCase();
-    if (successful === undefined) {
-        successful = true;
-    }
-
-    if (successful && (!n || el.disabled || t == 'reset' || t == 'button' ||
-        (t == 'checkbox' || t == 'radio') && !el.checked ||
-        (t == 'submit' || t == 'image') && el.form && el.form.clk != el ||
-        tag == 'select' && el.selectedIndex == -1)) {
-            return null;
-    }
-
-    if (tag == 'select') {
-        var index = el.selectedIndex;
-        if (index < 0) {
-            return null;
-        }
-        var a = [], ops = el.options;
-        var one = (t == 'select-one');
-        var max = (one ? index+1 : ops.length);
-        for(var i=(one ? index : 0); i < max; i++) {
-            var op = ops[i];
-            if (op.selected) {
-                var v = op.value;
-                if (!v) { // extra pain for IE...
-                    v = (op.attributes && op.attributes.value && !(op.attributes.value.specified)) ? op.text : op.value;
-                }
-                if (one) {
-                    return v;
-                }
-                a.push(v);
-            }
-        }
-        return a;
-    }
-    return $(el).val();
-};
-
-/**
- * Clears the form data.  Takes the following actions on the form's input fields:
- *  - input text fields will have their 'value' property set to the empty string
- *  - select elements will have their 'selectedIndex' property set to -1
- *  - checkbox and radio inputs will have their 'checked' property set to false
- *  - inputs of type submit, button, reset, and hidden will *not* be effected
- *  - button elements will *not* be effected
- */
-$.fn.clearForm = function(includeHidden) {
-    return this.each(function() {
-        $('input,select,textarea', this).clearFields(includeHidden);
-    });
-};
-
-/**
- * Clears the selected form elements.
- */
-$.fn.clearFields = $.fn.clearInputs = function(includeHidden) {
-    var re = /^(?:color|date|datetime|email|month|number|password|range|search|tel|text|time|url|week)$/i; // 'hidden' is not in this list
-    return this.each(function() {
-        var t = this.type, tag = this.tagName.toLowerCase();
-        if (re.test(t) || tag == 'textarea') {
-            this.value = '';
-        }
-        else if (t == 'checkbox' || t == 'radio') {
-            this.checked = false;
-        }
-        else if (tag == 'select') {
-            this.selectedIndex = -1;
-        }
-        else if (t == "file") {
-            if (/MSIE/.test(navigator.userAgent)) {
-                $(this).replaceWith($(this).clone(true));
-            } else {
-                $(this).val('');
-            }
-        }
-        else if (includeHidden) {
-            // includeHidden can be the value true, or it can be a selector string
-            // indicating a special test; for example:
-            //  $('#myForm').clearForm('.special:hidden')
-            // the above would clean hidden inputs that have the class of 'special'
-            if ( (includeHidden === true && /hidden/.test(t)) ||
-                 (typeof includeHidden == 'string' && $(this).is(includeHidden)) ) {
-                this.value = '';
-            }
-        }
-    });
-};
-
-/**
- * Resets the form data.  Causes all form elements to be reset to their original value.
- */
-$.fn.resetForm = function() {
-    return this.each(function() {
-        // guard against an input with the name of 'reset'
-        // note that IE reports the reset function as an 'object'
-        if (typeof this.reset == 'function' || (typeof this.reset == 'object' && !this.reset.nodeType)) {
-            this.reset();
-        }
-    });
-};
-
-/**
- * Enables or disables any matching elements.
- */
-$.fn.enable = function(b) {
-    if (b === undefined) {
-        b = true;
-    }
-    return this.each(function() {
-        this.disabled = !b;
-    });
-};
-
-/**
- * Checks/unchecks any matching checkboxes or radio buttons and
- * selects/deselects and matching option elements.
- */
-$.fn.selected = function(select) {
-    if (select === undefined) {
-        select = true;
-    }
-    return this.each(function() {
-        var t = this.type;
-        if (t == 'checkbox' || t == 'radio') {
-            this.checked = select;
-        }
-        else if (this.tagName.toLowerCase() == 'option') {
-            var $sel = $(this).parent('select');
-            if (select && $sel[0] && $sel[0].type == 'select-one') {
-                // deselect all other options
-                $sel.find('option').selected(false);
-            }
-            this.selected = select;
-        }
-    });
-};
-
-// expose debug var
-$.fn.ajaxSubmit.debug = false;
-
-// helper fn for console logging
-function log() {
-    if (!$.fn.ajaxSubmit.debug) {
-        return;
-    }
-    var msg = '[jquery.form] ' + Array.prototype.join.call(arguments,'');
-    if (window.console && window.console.log) {
-        window.console.log(msg);
-    }
-    else if (window.opera && window.opera.postError) {
-        window.opera.postError(msg);
-    }
-}
-
-}));

+ 0 - 25
desktop/core/src/desktop/static/desktop/ext/js/jquery/plugins/jquery.total-storage.min.js

@@ -1,25 +0,0 @@
-/**
- * TotalStorage
- *
- * Copyright (c) 2012 Jared Novack & Upstatement (upstatement.com)
- * Dual licensed under the MIT and GPL licenses:
- * http://www.opensource.org/licenses/mit-license.php
- * http://www.gnu.org/licenses/gpl.html
- *
- * Total Storage is the conceptual the love child of jStorage by Andris Reinman,
- * and Cookie by Klaus Hartl -- though this is not connected to either project.
- *
- * @name $.totalStorage
- * @cat Plugins/Cookie
- * @author Jared Novack/jared@upstatement.com
- * @version 1.1.3
- * @url http://upstatement.com/blog/2012/01/jquery-local-storage-done-right-and-easy/
- */
-!function(t,e){var o,r,n="test"
-if("localStorage"in window)try{r="undefined"==typeof window.localStorage?e:window.localStorage,o="undefined"!=typeof r&&"undefined"!=typeof window.JSON,window.localStorage.setItem(n,"1"),window.localStorage.removeItem(n)}catch(t){o=!1}t.totalStorage=function(e,o,r){return t.totalStorage.impl.init(e,o,r)},t.totalStorage.setItem=function(e,o,r){return t.totalStorage.impl.setItem(e,o,r)},t.totalStorage.getItem=function(e){return t.totalStorage.impl.getItem(e)},t.totalStorage.getAll=function(){return t.totalStorage.impl.getAll()},t.totalStorage.deleteItem=function(e){return t.totalStorage.impl.deleteItem(e)},t.totalStorage.impl={init:function(t,e,o){return"undefined"!=typeof e?this.setItem(t,e,o):this.getItem(t)},setItem:function(e,n,a){if(!o)try{return t.cookie(e,n,a),n}catch(t){console.log("Local Storage not supported by this browser. Install the cookie plugin on your site to take advantage of the same functionality. You can get it at https://github.com/carhartl/jquery-cookie")}var l=JSON.stringify(n)
-return r.setItem(e,l),this.parseResult(l)},getItem:function(e){if(!o)try{return this.parseResult(t.cookie(e))}catch(t){return null}var n=r.getItem(e)
-return this.parseResult(n)},deleteItem:function(e){if(!o)try{return t.cookie(e,null),!0}catch(t){return!1}return r.removeItem(e),!0},getAll:function(){var e=[]
-if(o)for(var n in r)n.length&&e.push({key:n,value:this.parseResult(r.getItem(n))})
-else try{for(var a=document.cookie.split(";"),l=0;l<a.length;l++){var i=a[l].split("="),u=i[0]
-e.push({key:u,value:this.parseResult(t.cookie(u))})}}catch(t){return null}return e},parseResult:function(t){var e
-try{e=JSON.parse(t),"undefined"==typeof e&&(e=t),"true"==e&&(e=!0),"false"==e&&(e=!1),parseFloat(e)==e&&"object"!=typeof e&&(e=parseFloat(e))}catch(o){e=t}return e}}}(jQuery)

Разница между файлами не показана из-за своего большого размера
+ 0 - 5
desktop/core/src/desktop/static/desktop/ext/js/jquery/plugins/jquery.ui.position.min.js


Разница между файлами не показана из-за своего большого размера
+ 0 - 1
desktop/core/src/desktop/static/desktop/ext/js/knockout-sortable.min.js


Разница между файлами не показана из-за своего большого размера
+ 0 - 9
desktop/core/src/desktop/static/desktop/ext/js/knockout.validation.min.js


+ 0 - 1123
desktop/core/src/desktop/static/desktop/ext/js/page.js

@@ -1,1123 +0,0 @@
-!function(e){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{var f;"undefined"!=typeof window?f=window:"undefined"!=typeof global?f=global:"undefined"!=typeof self&&(f=self),f.page=e()}}(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){
-(function (process){
-  /* globals require, module */
-
-  'use strict';
-
-  /**
-   * Module dependencies.
-   */
-
-  var pathtoRegexp = require('path-to-regexp');
-
-  /**
-   * Module exports.
-   */
-
-  module.exports = page;
-
-  /**
-   * Detect click event
-   */
-  var clickEvent = ('undefined' !== typeof document) && document.ontouchstart ? 'touchstart' : 'click';
-
-  /**
-   * To work properly with the URL
-   * history.location generated polyfill in https://github.com/devote/HTML5-History-API
-   */
-
-  var location = ('undefined' !== typeof window) && (window.history.location || window.location);
-
-  /**
-   * Perform initial dispatch.
-   */
-
-  var dispatch = true;
-
-
-  /**
-   * Decode URL components (query string, pathname, hash).
-   * Accommodates both regular percent encoding and x-www-form-urlencoded format.
-   */
-  var decodeURLComponents = true;
-
-  /**
-   * Base path.
-   */
-
-  var base = '';
-
-  /**
-   * Running flag.
-   */
-
-  var running;
-
-  /**
-   * HashBang option
-   */
-
-  var hashbang = false;
-
-  /**
-   * Previous context, for capturing
-   * page exit events.
-   */
-
-  var prevContext;
-
-  /**
-   * Register `path` with callback `fn()`,
-   * or route `path`, or redirection,
-   * or `page.start()`.
-   *
-   *   page(fn);
-   *   page('*', fn);
-   *   page('/user/:id', load, user);
-   *   page('/user/' + user.id, { some: 'thing' });
-   *   page('/user/' + user.id);
-   *   page('/from', '/to')
-   *   page();
-   *
-   * @param {string|!Function|!Object} path
-   * @param {Function=} fn
-   * @api public
-   */
-
-  function page(path, fn) {
-    // <callback>
-    if ('function' === typeof path) {
-      return page('*', path);
-    }
-
-    // route <path> to <callback ...>
-    if ('function' === typeof fn) {
-      var route = new Route(/** @type {string} */ (path));
-      for (var i = 1; i < arguments.length; ++i) {
-        page.callbacks.push(route.middleware(arguments[i]));
-      }
-      // show <path> with [state]
-    } else if ('string' === typeof path) {
-      page['string' === typeof fn ? 'redirect' : 'show'](path, fn);
-      // start [options]
-    } else {
-      page.start(path);
-    }
-  }
-
-  /**
-   * Callback functions.
-   */
-
-  page.callbacks = [];
-  page.exits = [];
-
-  /**
-   * Current path being processed
-   * @type {string}
-   */
-  page.current = '';
-
-  /**
-   * Number of pages navigated to.
-   * @type {number}
-   *
-   *     page.len == 0;
-   *     page('/login');
-   *     page.len == 1;
-   */
-
-  page.len = 0;
-
-  /**
-   * Get or set basepath to `path`.
-   *
-   * @param {string} path
-   * @api public
-   */
-
-  page.base = function(path) {
-    if (0 === arguments.length) return base;
-    base = path;
-  };
-
-  /**
-   * Bind with the given `options`.
-   *
-   * Options:
-   *
-   *    - `click` bind to click events [true]
-   *    - `popstate` bind to popstate [true]
-   *    - `dispatch` perform initial dispatch [true]
-   *
-   * @param {Object} options
-   * @api public
-   */
-
-  page.baseSearch = '';
-
-  page.start = function(options) {
-    options = options || {};
-    if (running) return;
-    running = true;
-    if (false === options.dispatch) dispatch = false;
-    if (false === options.decodeURLComponents) decodeURLComponents = false;
-    if (false !== options.popstate) window.addEventListener('popstate', onpopstate, false);
-    if (false !== options.click) {
-      document.addEventListener(clickEvent, onclick, false);
-    }
-    if (true === options.hashbang) hashbang = true;
-    if (!dispatch) return;
-    var search = location.search.replace(page.baseSearch, '').replace('&&', '&').replace('?&', '?');
-    if (search === '?') {
-      search = '';
-    }
-    var url = (hashbang && ~location.hash.indexOf('#!')) ? location.hash.substr(2) + search : location.pathname + search + location.hash;
-    page.replace(url, null, true, dispatch);
-  };
-
-  /**
-   * Unbind click and popstate event handlers.
-   *
-   * @api public
-   */
-
-  page.stop = function() {
-    if (!running) return;
-    page.current = '';
-    page.len = 0;
-    running = false;
-    document.removeEventListener(clickEvent, onclick, false);
-    window.removeEventListener('popstate', onpopstate, false);
-  };
-
-  /**
-   * Show `path` with optional `state` object.
-   *
-   * @param {string} path
-   * @param {Object=} state
-   * @param {boolean=} dispatch
-   * @param {boolean=} push
-   * @return {!Context}
-   * @api public
-   */
-
-  page.show = function(path, state, dispatch, push) {
-    var ctx = new Context(path, state);
-    page.current = ctx.path;
-    if (false !== dispatch) page.dispatch(ctx);
-    if (false !== ctx.handled && false !== push) ctx.pushState();
-    return ctx;
-  };
-
-  /**
-   * Goes back in the history
-   * Back should always let the current route push state and then go back.
-   *
-   * @param {string} path - fallback path to go back if no more history exists, if undefined defaults to page.base
-   * @param {Object=} state
-   * @api public
-   */
-
-  page.back = function(path, state) {
-    if (page.len > 0) {
-      // this may need more testing to see if all browsers
-      // wait for the next tick to go back in history
-      history.back();
-      page.len--;
-    } else if (path) {
-      setTimeout(function() {
-        page.show(path, state);
-      });
-    }else{
-      setTimeout(function() {
-        page.show(base, state);
-      });
-    }
-  };
-
-
-  /**
-   * Register route to redirect from one path to other
-   * or just redirect to another route
-   *
-   * @param {string} from - if param 'to' is undefined redirects to 'from'
-   * @param {string=} to
-   * @api public
-   */
-  page.redirect = function(from, to) {
-    // Define route from a path to another
-    if ('string' === typeof from && 'string' === typeof to) {
-      page(from, function(e) {
-        setTimeout(function() {
-          page.replace(/** @type {!string} */ (to));
-        }, 0);
-      });
-    }
-
-    // Wait for the push state and replace it with another
-    if ('string' === typeof from && 'undefined' === typeof to) {
-      setTimeout(function() {
-        page.replace(from);
-      }, 0);
-    }
-  };
-
-  /**
-   * Replace `path` with optional `state` object.
-   *
-   * @param {string} path
-   * @param {Object=} state
-   * @param {boolean=} init
-   * @param {boolean=} dispatch
-   * @return {!Context}
-   * @api public
-   */
-
-
-  page.replace = function(path, state, init, dispatch) {
-    var ctx = new Context(path, state);
-    page.current = ctx.path;
-    ctx.init = init;
-    ctx.save(); // save before dispatching, which may redirect
-    if (false !== dispatch) page.dispatch(ctx);
-    return ctx;
-  };
-
-  /**
-   * Dispatch the given `ctx`.
-   *
-   * @param {Context} ctx
-   * @api private
-   */
-  page.dispatch = function(ctx) {
-    var prev = prevContext,
-      i = 0,
-      j = 0;
-
-    prevContext = ctx;
-
-    function nextExit() {
-      var fn = page.exits[j++];
-      if (!fn) return nextEnter();
-      fn(prev, nextExit);
-    }
-
-    function nextEnter() {
-      var fn = page.callbacks[i++];
-
-      if (ctx.path !== page.current) {
-        ctx.handled = false;
-        return;
-      }
-      if (!fn) return unhandled(ctx);
-      fn(ctx, nextEnter);
-    }
-
-    if (prev) {
-      nextExit();
-    } else {
-      nextEnter();
-    }
-  };
-
-  /**
-   * Unhandled `ctx`. When it's not the initial
-   * popstate then redirect. If you wish to handle
-   * 404s on your own use `page('*', callback)`.
-   *
-   * @param {Context} ctx
-   * @api private
-   */
-  function unhandled(ctx) {
-    if (ctx.handled) return;
-    var current;
-
-    if (hashbang) {
-      current = base + location.hash.replace('#!', '');
-    } else {
-      var search = location.search.replace(page.baseSearch, '').replace('&&', '&').replace('?&', '?');
-      if (search === '?') {
-        search = '';
-      }
-      current = location.pathname + search;
-    }
-
-    if (current === ctx.canonicalPath) return;
-    page.stop();
-    ctx.handled = false;
-    location.href = ctx.canonicalPath;
-  }
-
-  /**
-   * Register an exit route on `path` with
-   * callback `fn()`, which will be called
-   * on the previous context when a new
-   * page is visited.
-   */
-  page.exit = function(path, fn) {
-    if (typeof path === 'function') {
-      return page.exit('*', path);
-    }
-
-    var route = new Route(path);
-    for (var i = 1; i < arguments.length; ++i) {
-      page.exits.push(route.middleware(arguments[i]));
-    }
-  };
-
-  /**
-   * Remove URL encoding from the given `str`.
-   * Accommodates whitespace in both x-www-form-urlencoded
-   * and regular percent-encoded form.
-   *
-   * @param {string} val - URL component to decode
-   */
-  function decodeURLEncodedURIComponent(val) {
-    if (typeof val !== 'string') { return val; }
-    return decodeURLComponents ? decodeURIComponent(val.replace(/\+/g, ' ')) : val;
-  }
-
-  /**
-   * Initialize a new "request" `Context`
-   * with the given `path` and optional initial `state`.
-   *
-   * @constructor
-   * @param {string} path
-   * @param {Object=} state
-   * @api public
-   */
-
-  function Context(path, state) {
-    if ('/' === path[0] && 0 !== path.indexOf(base)) path = base + (hashbang ? '#!' : '') + path;
-    var i = path.indexOf('?');
-
-    this.canonicalPath = path;
-    this.path = path.replace(base, '') || '/';
-    if (hashbang) this.path = this.path.replace('#!', '') || '/';
-
-    this.title = document.title;
-    this.state = state || {};
-    this.state.path = path;
-    this.querystring = ~i ? decodeURLEncodedURIComponent(path.slice(i + 1)) : '';
-    this.pathname = decodeURLEncodedURIComponent(~i ? path.slice(0, i) : path);
-    this.params = {};
-
-    // fragment
-    this.hash = '';
-    if (!hashbang) {
-      if (!~this.path.indexOf('#')) return;
-      var parts = this.path.split('#');
-      this.path = parts[0];
-      this.hash = decodeURLEncodedURIComponent(parts[1]) || '';
-      this.querystring = this.querystring.split('#')[0];
-    }
-  }
-
-  /**
-   * Expose `Context`.
-   */
-
-  page.Context = Context;
-
-  /**
-   * Push state.
-   *
-   * @api private
-   */
-
-  Context.prototype.pushState = function() {
-    page.len++;
-    history.pushState(this.state, this.title, hashbang && this.path !== '/' ? '#!' + this.path : this.canonicalPath);
-  };
-
-  /**
-   * Save the context state.
-   *
-   * @api public
-   */
-
-  Context.prototype.save = function() {
-    history.replaceState(this.state, this.title, hashbang && this.path !== '/' ? '#!' + this.path : this.canonicalPath);
-  };
-
-  /**
-   * Initialize `Route` with the given HTTP `path`,
-   * and an array of `callbacks` and `options`.
-   *
-   * Options:
-   *
-   *   - `sensitive`    enable case-sensitive routes
-   *   - `strict`       enable strict matching for trailing slashes
-   *
-   * @constructor
-   * @param {string} path
-   * @param {Object=} options
-   * @api private
-   */
-
-  function Route(path, options) {
-    options = options || {};
-    this.path = (path === '*') ? '(.*)' : path;
-    this.method = 'GET';
-    this.regexp = pathtoRegexp(this.path,
-      this.keys = [],
-      options);
-  }
-
-  /**
-   * Expose `Route`.
-   */
-
-  page.Route = Route;
-
-  /**
-   * Return route middleware with
-   * the given callback `fn()`.
-   *
-   * @param {Function} fn
-   * @return {Function}
-   * @api public
-   */
-
-  Route.prototype.middleware = function(fn) {
-    var self = this;
-    return function(ctx, next) {
-      if (self.match(ctx.path, ctx.params)) return fn(ctx, next);
-      next();
-    };
-  };
-
-  /**
-   * Check if this route matches `path`, if so
-   * populate `params`.
-   *
-   * @param {string} path
-   * @param {Object} params
-   * @return {boolean}
-   * @api private
-   */
-
-  Route.prototype.match = function(path, params) {
-    var keys = this.keys,
-      qsIndex = path.indexOf('?'),
-      pathname = ~qsIndex ? path.slice(0, qsIndex) : path,
-      m = this.regexp.exec(decodeURIComponent(pathname));
-
-    if (!m) return false;
-
-    for (var i = 1, len = m.length; i < len; ++i) {
-      var key = keys[i - 1];
-      var val = decodeURLEncodedURIComponent(m[i]);
-      if (val !== undefined || !(hasOwnProperty.call(params, key.name))) {
-        params[key.name] = val;
-      }
-    }
-
-    return true;
-  };
-
-
-  /**
-   * Handle "populate" events.
-   */
-
-  var onpopstate = (function () {
-    var loaded = false;
-    if ('undefined' === typeof window) {
-      return;
-    }
-    if (document.readyState === 'complete') {
-      loaded = true;
-    } else {
-      window.addEventListener('load', function() {
-        setTimeout(function() {
-          loaded = true;
-        }, 0);
-      });
-    }
-    return function onpopstate(e) {
-      if (!loaded) return;
-      if (e.state) {
-        var path = e.state.path;
-        page.replace(path, e.state);
-      } else {
-        page.show(location.pathname + location.hash, undefined, undefined, false);
-      }
-    };
-  })();
-  /**
-   * Handle "click" events.
-   */
-
-  function onclick(e) {
-
-    if (1 !== which(e)) return;
-
-    if (e.metaKey || e.ctrlKey || e.shiftKey) return;
-    if (e.defaultPrevented) return;
-
-
-
-    // ensure link
-    // use shadow dom when available
-    var el = e.path ? e.path[0] : e.target;
-    while (el && 'A' !== el.nodeName) el = el.parentNode;
-    if (!el || 'A' !== el.nodeName) return;
-
-
-
-    // Ignore if tag has
-    // 1. "download" attribute
-    // 2. rel="external" attribute
-    if (el.hasAttribute('download') || el.getAttribute('rel') === 'external') return;
-
-    // ensure non-hash for the same path
-    var link = el.getAttribute('href');
-    if (!hashbang && el.pathname === location.pathname && (el.hash || '#' === link)) return;
-
-
-
-    // Check for mailto: in the href
-    if (link && link.indexOf('mailto:') > -1) return;
-
-    // check target
-    if (el.target) return;
-
-    // x-origin
-    if (!sameOrigin(el.href)) return;
-
-
-
-    // rebuild path
-    var path = el.pathname + el.search + (el.hash || '');
-
-    // strip leading "/[drive letter]:" on NW.js on Windows
-    if (typeof process !== 'undefined' && path.match(/^\/[a-zA-Z]:\//)) {
-      path = path.replace(/^\/[a-zA-Z]:\//, '/');
-    }
-
-    // same page
-    var orig = path;
-
-    if (path.indexOf(base) === 0) {
-      path = path.substr(base.length);
-    }
-
-    if (hashbang) path = path.replace('#!', '');
-
-    if (base && orig === path) return;
-
-    e.preventDefault();
-    page.show(orig);
-  }
-
-  /**
-   * Event button.
-   */
-
-  function which(e) {
-    e = e || window.event;
-    return null === e.which ? e.button : e.which;
-  }
-
-  /**
-   * Check if `href` is the same origin.
-   */
-
-  function sameOrigin(href) {
-    var origin = location.protocol + '//' + location.hostname;
-    if (location.port) origin += ':' + location.port;
-    return (href && (0 === href.indexOf(origin)));
-  }
-
-  page.sameOrigin = sameOrigin;
-
-}).call(this,require('_process'))
-},{"_process":2,"path-to-regexp":3}],2:[function(require,module,exports){
-// shim for using process in browser
-
-var process = module.exports = {};
-
-process.nextTick = (function () {
-    var canSetImmediate = typeof window !== 'undefined'
-    && window.setImmediate;
-    var canMutationObserver = typeof window !== 'undefined'
-    && window.MutationObserver;
-    var canPost = typeof window !== 'undefined'
-    && window.postMessage && window.addEventListener
-    ;
-
-    if (canSetImmediate) {
-        return function (f) { return window.setImmediate(f) };
-    }
-
-    var queue = [];
-
-    if (canMutationObserver) {
-        var hiddenDiv = document.createElement("div");
-        var observer = new MutationObserver(function () {
-            var queueList = queue.slice();
-            queue.length = 0;
-            queueList.forEach(function (fn) {
-                fn();
-            });
-        });
-
-        observer.observe(hiddenDiv, { attributes: true });
-
-        return function nextTick(fn) {
-            if (!queue.length) {
-                hiddenDiv.setAttribute('yes', 'no');
-            }
-            queue.push(fn);
-        };
-    }
-
-    if (canPost) {
-        window.addEventListener('message', function (ev) {
-            var source = ev.source;
-            if ((source === window || source === null) && ev.data === 'process-tick') {
-                ev.stopPropagation();
-                if (queue.length > 0) {
-                    var fn = queue.shift();
-                    fn();
-                }
-            }
-        }, true);
-
-        return function nextTick(fn) {
-            queue.push(fn);
-            window.postMessage('process-tick', '*');
-        };
-    }
-
-    return function nextTick(fn) {
-        setTimeout(fn, 0);
-    };
-})();
-
-process.title = 'browser';
-process.browser = true;
-process.env = {};
-process.argv = [];
-
-function noop() {}
-
-process.on = noop;
-process.addListener = noop;
-process.once = noop;
-process.off = noop;
-process.removeListener = noop;
-process.removeAllListeners = noop;
-process.emit = noop;
-
-process.binding = function (name) {
-    throw new Error('process.binding is not supported');
-};
-
-// TODO(shtylman)
-process.cwd = function () { return '/' };
-process.chdir = function (dir) {
-    throw new Error('process.chdir is not supported');
-};
-
-},{}],3:[function(require,module,exports){
-var isarray = require('isarray')
-
-/**
- * Expose `pathToRegexp`.
- */
-module.exports = pathToRegexp
-module.exports.parse = parse
-module.exports.compile = compile
-module.exports.tokensToFunction = tokensToFunction
-module.exports.tokensToRegExp = tokensToRegExp
-
-/**
- * The main path matching regexp utility.
- *
- * @type {RegExp}
- */
-var PATH_REGEXP = new RegExp([
-  // Match escaped characters that would otherwise appear in future matches.
-  // This allows the user to escape special characters that won't transform.
-  '(\\\\.)',
-  // Match Express-style parameters and un-named parameters with a prefix
-  // and optional suffixes. Matches appear as:
-  //
-  // "/:test(\\d+)?" => ["/", "test", "\d+", undefined, "?", undefined]
-  // "/route(\\d+)"  => [undefined, undefined, undefined, "\d+", undefined, undefined]
-  // "/*"            => ["/", undefined, undefined, undefined, undefined, "*"]
-  '([\\/.])?(?:(?:\\:(\\w+)(?:\\(((?:\\\\.|[^()])+)\\))?|\\(((?:\\\\.|[^()])+)\\))([+*?])?|(\\*))'
-].join('|'), 'g')
-
-/**
- * Parse a string for the raw tokens.
- *
- * @param  {String} str
- * @return {Array}
- */
-function parse (str) {
-  var tokens = []
-  var key = 0
-  var index = 0
-  var path = ''
-  var res
-
-  while ((res = PATH_REGEXP.exec(str)) != null) {
-    var m = res[0]
-    var escaped = res[1]
-    var offset = res.index
-    path += str.slice(index, offset)
-    index = offset + m.length
-
-    // Ignore already escaped sequences.
-    if (escaped) {
-      path += escaped[1]
-      continue
-    }
-
-    // Push the current path onto the tokens.
-    if (path) {
-      tokens.push(path)
-      path = ''
-    }
-
-    var prefix = res[2]
-    var name = res[3]
-    var capture = res[4]
-    var group = res[5]
-    var suffix = res[6]
-    var asterisk = res[7]
-
-    var repeat = suffix === '+' || suffix === '*'
-    var optional = suffix === '?' || suffix === '*'
-    var delimiter = prefix || '/'
-    var pattern = capture || group || (asterisk ? '.*' : '[^' + delimiter + ']+?')
-
-    tokens.push({
-      name: name || key++,
-      prefix: prefix || '',
-      delimiter: delimiter,
-      optional: optional,
-      repeat: repeat,
-      pattern: escapeGroup(pattern)
-    })
-  }
-
-  // Match any characters still remaining.
-  if (index < str.length) {
-    path += str.substr(index)
-  }
-
-  // If the path exists, push it onto the end.
-  if (path) {
-    tokens.push(path)
-  }
-
-  return tokens
-}
-
-/**
- * Compile a string to a template function for the path.
- *
- * @param  {String}   str
- * @return {Function}
- */
-function compile (str) {
-  return tokensToFunction(parse(str))
-}
-
-/**
- * Expose a method for transforming tokens into the path function.
- */
-function tokensToFunction (tokens) {
-  // Compile all the tokens into regexps.
-  var matches = new Array(tokens.length)
-
-  // Compile all the patterns before compilation.
-  for (var i = 0; i < tokens.length; i++) {
-    if (typeof tokens[i] === 'object') {
-      matches[i] = new RegExp('^' + tokens[i].pattern + '$')
-    }
-  }
-
-  return function (obj) {
-    var path = ''
-    var data = obj || {}
-
-    for (var i = 0; i < tokens.length; i++) {
-      var token = tokens[i]
-
-      if (typeof token === 'string') {
-        path += token
-
-        continue
-      }
-
-      var value = data[token.name]
-      var segment
-
-      if (value == null) {
-        if (token.optional) {
-          continue
-        } else {
-          throw new TypeError('Expected "' + token.name + '" to be defined')
-        }
-      }
-
-      if (isarray(value)) {
-        if (!token.repeat) {
-          throw new TypeError('Expected "' + token.name + '" to not repeat, but received "' + value + '"')
-        }
-
-        if (value.length === 0) {
-          if (token.optional) {
-            continue
-          } else {
-            throw new TypeError('Expected "' + token.name + '" to not be empty')
-          }
-        }
-
-        for (var j = 0; j < value.length; j++) {
-          segment = encodeURIComponent(value[j])
-
-          if (!matches[i].test(segment)) {
-            throw new TypeError('Expected all "' + token.name + '" to match "' + token.pattern + '", but received "' + segment + '"')
-          }
-
-          path += (j === 0 ? token.prefix : token.delimiter) + segment
-        }
-
-        continue
-      }
-
-      segment = encodeURIComponent(value)
-
-      if (!matches[i].test(segment)) {
-        throw new TypeError('Expected "' + token.name + '" to match "' + token.pattern + '", but received "' + segment + '"')
-      }
-
-      path += token.prefix + segment
-    }
-
-    return path
-  }
-}
-
-/**
- * Escape a regular expression string.
- *
- * @param  {String} str
- * @return {String}
- */
-function escapeString (str) {
-  return str.replace(/([.+*?=^!:${}()[\]|\/])/g, '\\$1')
-}
-
-/**
- * Escape the capturing group by escaping special characters and meaning.
- *
- * @param  {String} group
- * @return {String}
- */
-function escapeGroup (group) {
-  return group.replace(/([=!:$\/()])/g, '\\$1')
-}
-
-/**
- * Attach the keys as a property of the regexp.
- *
- * @param  {RegExp} re
- * @param  {Array}  keys
- * @return {RegExp}
- */
-function attachKeys (re, keys) {
-  re.keys = keys
-  return re
-}
-
-/**
- * Get the flags for a regexp from the options.
- *
- * @param  {Object} options
- * @return {String}
- */
-function flags (options) {
-  return options.sensitive ? '' : 'i'
-}
-
-/**
- * Pull out keys from a regexp.
- *
- * @param  {RegExp} path
- * @param  {Array}  keys
- * @return {RegExp}
- */
-function regexpToRegexp (path, keys) {
-  // Use a negative lookahead to match only capturing groups.
-  var groups = path.source.match(/\((?!\?)/g)
-
-  if (groups) {
-    for (var i = 0; i < groups.length; i++) {
-      keys.push({
-        name: i,
-        prefix: null,
-        delimiter: null,
-        optional: false,
-        repeat: false,
-        pattern: null
-      })
-    }
-  }
-
-  return attachKeys(path, keys)
-}
-
-/**
- * Transform an array into a regexp.
- *
- * @param  {Array}  path
- * @param  {Array}  keys
- * @param  {Object} options
- * @return {RegExp}
- */
-function arrayToRegexp (path, keys, options) {
-  var parts = []
-
-  for (var i = 0; i < path.length; i++) {
-    parts.push(pathToRegexp(path[i], keys, options).source)
-  }
-
-  var regexp = new RegExp('(?:' + parts.join('|') + ')', flags(options))
-
-  return attachKeys(regexp, keys)
-}
-
-/**
- * Create a path regexp from string input.
- *
- * @param  {String} path
- * @param  {Array}  keys
- * @param  {Object} options
- * @return {RegExp}
- */
-function stringToRegexp (path, keys, options) {
-  var tokens = parse(path)
-  var re = tokensToRegExp(tokens, options)
-
-  // Attach keys back to the regexp.
-  for (var i = 0; i < tokens.length; i++) {
-    if (typeof tokens[i] !== 'string') {
-      keys.push(tokens[i])
-    }
-  }
-
-  return attachKeys(re, keys)
-}
-
-/**
- * Expose a function for taking tokens and returning a RegExp.
- *
- * @param  {Array}  tokens
- * @param  {Array}  keys
- * @param  {Object} options
- * @return {RegExp}
- */
-function tokensToRegExp (tokens, options) {
-  options = options || {}
-
-  var strict = options.strict
-  var end = options.end !== false
-  var route = ''
-  var lastToken = tokens[tokens.length - 1]
-  var endsWithSlash = typeof lastToken === 'string' && /\/$/.test(lastToken)
-
-  // Iterate over the tokens and create our regexp string.
-  for (var i = 0; i < tokens.length; i++) {
-    var token = tokens[i]
-
-    if (typeof token === 'string') {
-      route += escapeString(token)
-    } else {
-      var prefix = escapeString(token.prefix)
-      var capture = token.pattern
-
-      if (token.repeat) {
-        capture += '(?:' + prefix + capture + ')*'
-      }
-
-      if (token.optional) {
-        if (prefix) {
-          capture = '(?:' + prefix + '(' + capture + '))?'
-        } else {
-          capture = '(' + capture + ')?'
-        }
-      } else {
-        capture = prefix + '(' + capture + ')'
-      }
-
-      route += capture
-    }
-  }
-
-  // In non-strict mode we allow a slash at the end of match. If the path to
-  // match already ends with a slash, we remove it for consistency. The slash
-  // is valid at the end of a path match, not in the middle. This is important
-  // in non-ending mode, where "/test/" shouldn't match "/test//route".
-  if (!strict) {
-    route = (endsWithSlash ? route.slice(0, -2) : route) + '(?:\\/(?=$))?'
-  }
-
-  if (end) {
-    route += '$'
-  } else {
-    // In non-ending mode, we need the capturing groups to match as much as
-    // possible by using a positive lookahead to the end or next path segment.
-    route += strict && endsWithSlash ? '' : '(?=\\/|$)'
-  }
-
-  return new RegExp('^' + route, flags(options))
-}
-
-/**
- * Normalize the given path string, returning a regular expression.
- *
- * An empty array can be passed in for the keys, which will hold the
- * placeholder key descriptions. For example, using `/user/:id`, `keys` will
- * contain `[{ name: 'id', delimiter: '/', optional: false, repeat: false }]`.
- *
- * @param  {(String|RegExp|Array)} path
- * @param  {Array}                 [keys]
- * @param  {Object}                [options]
- * @return {RegExp}
- */
-function pathToRegexp (path, keys, options) {
-  keys = keys || []
-
-  if (!isarray(keys)) {
-    options = keys
-    keys = []
-  } else if (!options) {
-    options = {}
-  }
-
-  if (path instanceof RegExp) {
-    return regexpToRegexp(path, keys, options)
-  }
-
-  if (isarray(path)) {
-    return arrayToRegexp(path, keys, options)
-  }
-
-  return stringToRegexp(path, keys, options)
-}
-
-},{"isarray":4}],4:[function(require,module,exports){
-module.exports = Array.isArray || function (arr) {
-  return Object.prototype.toString.call(arr) == '[object Array]';
-};
-
-},{}]},{},[1])(1)
-});

+ 0 - 74
desktop/core/src/desktop/static/desktop/ext/js/selectize-plugin-clear.js

@@ -1,74 +0,0 @@
-/*! selectize clear button plugin by Alexey Petushkov | https://github.com/mentatxx/selectize-plugin-clear | Apache License (v2) */
-
-Selectize.define('clear_button', function (options) {
-    /**
-     * Escapes a string for use within HTML.
-     *
-     * @param {string} str
-     * @returns {string}
-     */
-    var escape_html = function (str) {
-        return (str + '')
-            .replace(/&/g, '&amp;')
-            .replace(/</g, '&lt;')
-            .replace(/>/g, '&gt;')
-            .replace(/"/g, '&quot;');
-    };
-
-    options = $.extend({
-        label: '&times;',
-        title: 'Remove',
-        className: 'clearAll',
-        append: true,
-        hideWhenEmpty: true,
-        leaveOpen: false
-    }, options);
-
-    var self = this,
-        $html = $('<span class="' +
-            options.className +
-            '" tabindex="-1" title="' +
-            escape_html(options.title) +
-            '">' +
-            options.label +
-            '</span>');
-
-
-    this.setup = (function () {
-        var original = self.setup;
-        return function () {
-            // override the item rendering method to add the button to each
-            original.apply(this, arguments);
-
-            this.$wrapper.append($html);
-
-            if (options.hideWhenEmpty) {
-                var $input = this.$input;
-                var hideShowClrBtn = function ($inpt) {
-                    var val = $inpt.val();
-                    if (val) {
-                        $html.show();
-                    } else {
-                        $html.hide();
-                    }
-                }
-
-                hideShowClrBtn($input);
-                $input.change(function () {
-                    hideShowClrBtn($input);
-                });
-            }
-
-            // add event listener
-            this.$wrapper.on('click', '.' + options.className, function (e) {
-                e.preventDefault();
-                if (self.isLocked) return;
-                self.clear();
-
-                if (options.leaveOpen) {
-                    self.$control_input.focus();
-                }
-            });
-        };
-    })();
-});

Разница между файлами не показана из-за своего большого размера
+ 0 - 1
desktop/core/src/desktop/static/desktop/ext/js/selectize.min.js


Разница между файлами не показана из-за своего большого размера
+ 0 - 0
desktop/core/src/desktop/static/desktop/js/bundles/hue-bundle-5a1bf7f66484544c5faf.js


Разница между файлами не показана из-за своего большого размера
+ 0 - 0
desktop/core/src/desktop/static/desktop/js/bundles/hue-bundle-5a1bf7f66484544c5faf.js.map


Разница между файлами не показана из-за своего большого размера
+ 0 - 0
desktop/core/src/desktop/static/desktop/js/bundles/hue-bundle-c56027ed5fcc7f4abc0b.js.map


+ 1 - 1
desktop/core/src/desktop/static/desktop/js/bundles/sqlSyntaxWebWorker-bundle-c56027ed5fcc7f4abc0b.js → desktop/core/src/desktop/static/desktop/js/bundles/sqlSyntaxWebWorker-bundle-5a1bf7f66484544c5faf.js

@@ -37,4 +37,4 @@
   !*** multi ./desktop/core/src/desktop/js/sql/sqlSyntaxWebWorker.js ***!
   \*********************************************************************/
 /*! no static exports found */function(e,t,a){e.exports=a(/*! ./desktop/core/src/desktop/js/sql/sqlSyntaxWebWorker.js */"./desktop/core/src/desktop/js/sql/sqlSyntaxWebWorker.js")}});
-//# sourceMappingURL=sqlSyntaxWebWorker-bundle-c56027ed5fcc7f4abc0b.js.map
+//# sourceMappingURL=sqlSyntaxWebWorker-bundle-5a1bf7f66484544c5faf.js.map

Разница между файлами не показана из-за своего большого размера
+ 0 - 0
desktop/core/src/desktop/static/desktop/js/bundles/sqlSyntaxWebWorker-bundle-5a1bf7f66484544c5faf.js.map


+ 0 - 321
desktop/core/src/desktop/static/desktop/js/hue.json.js

@@ -1,321 +0,0 @@
-// Licensed to Cloudera, Inc. under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  Cloudera, Inc. 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.
-
-
-JSON.bigdataParse = (function () {
-  "use strict";
-
-// This is a function that can parse a JSON text, producing a JavaScript
-// data structure. It is a simple, recursive descent parser. It does not use
-// eval or regular expressions, so it can be used as a model for implementing
-// a JSON parser in other languages.
-
-// We are defining the function inside of another function to avoid creating
-// global variables.
-
-  var at,     // The index of the current character
-      ch,     // The current character
-      escapee = {
-        '"': '"',
-        '\\': '\\',
-        '/': '/',
-        b: '\b',
-        f: '\f',
-        n: '\n',
-        r: '\r',
-        t: '\t'
-      },
-      text,
-
-      error = function (m) {
-
-// Call error when something is wrong.
-
-        throw {
-          name: 'SyntaxError',
-          message: m,
-          at: at,
-          text: text
-        };
-      },
-
-      next = function (c) {
-
-// If a c parameter is provided, verify that it matches the current character.
-
-        if (c && c !== ch) {
-          error("Expected '" + c + "' instead of '" + ch + "'");
-        }
-
-// Get the next character. When there are no more characters,
-// return the empty string.
-        try {
-          ch = text.charAt(at);
-          at += 1;
-          return ch;
-        }
-        catch (e) {
-          return '';
-        }
-      },
-
-      number = function () {
-// Parse a number value.
-
-        var number,
-            string = '';
-
-        if (ch === '-') {
-          string = '-';
-          next('-');
-        }
-        while (ch >= '0' && ch <= '9') {
-          string += ch;
-          next();
-        }
-        if (ch === '.') {
-          string += '.';
-          while (next() && ch >= '0' && ch <= '9') {
-            string += ch;
-          }
-        }
-        if (ch === 'e' || ch === 'E') {
-          string += ch;
-          next();
-          if (ch === '-' || ch === '+') {
-            string += ch;
-            next();
-          }
-          while (ch >= '0' && ch <= '9') {
-            string += ch;
-            next();
-          }
-        }
-        number = +string;
-        if (!isFinite(number)) {
-          error("Bad number");
-        } else {
-          //if (number > 9007199254740992 || number < -9007199254740992)
-          // Bignumber has stricter check: everything with length > 15 digits disallowed
-          if (string.length > 15)
-            return string;
-          return number;
-        }
-      },
-
-      string = function () {
-
-// Parse a string value.
-
-        var hex,
-            i,
-            string = '',
-            uffff;
-
-// When parsing for string values, we must look for " and \ characters.
-
-        if (ch === '"') {
-          while (next()) {
-            if (ch === '"') {
-              next();
-              return string;
-            }
-            if (ch === '\\') {
-              next();
-              if (ch === 'u') {
-                uffff = 0;
-                for (i = 0; i < 4; i += 1) {
-                  hex = parseInt(next(), 16);
-                  if (!isFinite(hex)) {
-                    break;
-                  }
-                  uffff = uffff * 16 + hex;
-                }
-                string += String.fromCharCode(uffff);
-              } else if (typeof escapee[ch] === 'string') {
-                string += escapee[ch];
-              } else {
-                break;
-              }
-            } else {
-              string += ch;
-            }
-          }
-        }
-        error("Bad string");
-      },
-
-      white = function () {
-
-// Skip whitespace.
-
-        while (ch && ch <= ' ') {
-          next();
-        }
-      },
-
-      word = function () {
-
-// true, false, or null.
-
-        switch (ch) {
-          case 't':
-            next('t');
-            next('r');
-            next('u');
-            next('e');
-            return true;
-          case 'f':
-            next('f');
-            next('a');
-            next('l');
-            next('s');
-            next('e');
-            return false;
-          case 'n':
-            next('n');
-            next('u');
-            next('l');
-            next('l');
-            return null;
-        }
-        error("Unexpected '" + ch + "'");
-      },
-
-      value,  // Place holder for the value function.
-
-      array = function () {
-
-// Parse an array value.
-
-        var array = [];
-
-        if (ch === '[') {
-          next('[');
-          white();
-          if (ch === ']') {
-            next(']');
-            return array;   // empty array
-          }
-          while (ch) {
-            array.push(value());
-            white();
-            if (ch === ']') {
-              next(']');
-              return array;
-            }
-            next(',');
-            white();
-          }
-        }
-        error("Bad array");
-      },
-
-      object = function () {
-
-// Parse an object value.
-
-        var key,
-            object = {};
-
-        if (ch === '{') {
-          next('{');
-          white();
-          if (ch === '}') {
-            next('}');
-            return object;   // empty object
-          }
-          while (ch) {
-            key = string();
-            white();
-            next(':');
-            if (Object.hasOwnProperty.call(object, key)) {
-              error('Duplicate key "' + key + '"');
-            }
-            object[key] = value();
-            white();
-            if (ch === '}') {
-              next('}');
-              return object;
-            }
-            next(',');
-            white();
-          }
-        }
-        error("Bad object");
-      };
-
-  value = function () {
-
-// Parse a JSON value. It could be an object, an array, a string, a number,
-// or a word.
-
-    white();
-    switch (ch) {
-      case '{':
-        return object();
-      case '[':
-        return array();
-      case '"':
-        return string();
-      case '-':
-        return number();
-      default:
-        return ch >= '0' && ch <= '9' ? number() : word();
-    }
-  };
-
-// Return the json_parse function. It will have access to all of the above
-// functions and variables.
-
-  return function (source, reviver) {
-    var result;
-
-    text = source;
-    at = 0;
-    ch = ' ';
-    result = value();
-    white();
-    if (ch) {
-      error("Syntax error");
-    }
-
-// If there is a reviver function, we recursively walk the new structure,
-// passing each name/value pair to the reviver function for possible
-// transformation, starting with a temporary root object that holds the result
-// in an empty key. If there is not a reviver function, we simply return the
-// result.
-
-    return typeof reviver === 'function'
-        ? (function walk(holder, key) {
-      var k, v, value = holder[key];
-      if (value && typeof value === 'object') {
-        for (k in value) {
-          if (Object.prototype.hasOwnProperty.call(value, k)) {
-            v = walk(value, k);
-            if (v !== undefined) {
-              value[k] = v;
-            } else {
-              delete value[k];
-            }
-          }
-        }
-      }
-      return reviver.call(holder, key, value);
-    }({'': result}, ''))
-        : result;
-  };
-}());

+ 0 - 765
desktop/core/src/desktop/static/desktop/js/hue.utils.js

@@ -1,765 +0,0 @@
-// Licensed to Cloudera, Inc. under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  Cloudera, Inc. 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.
-
-/*
- * Array polyfills
-*/
-if (!('clean' in Array.prototype)) {
-  Array.prototype.clean = function (deleteValue) {
-    for (var i = 0; i < this.length; i++) {
-      if (this[i] == deleteValue) {
-        this.splice(i, 1);
-        i--;
-      }
-    }
-    return this;
-  };
-}
-
-if (!('move' in Array.prototype)) {
-  Array.prototype.move = function (old_index, new_index) {
-    if (new_index >= this.length) {
-      var k = new_index - this.length;
-      while ((k--) + 1) {
-        this.push(undefined);
-      }
-    }
-    this.splice(new_index, 0, this.splice(old_index, 1)[0]);
-    return this;
-  };
-}
-
-if (!('indexOf' in Array.prototype)) {
-  Array.prototype.indexOf = function (needle) {
-    for (var i = 0; i < this.length; i++) {
-      if (this[i] === needle) {
-        return i;
-      }
-    }
-    return -1;
-  };
-}
-
-if (!('filter' in Array.prototype)) {
-  Array.prototype.filter = function (filter, that /*opt*/) {
-    var other = [], v;
-    for (var i = 0, n = this.length; i < n; i++) {
-      if (i in this && filter.call(that, v = this[i], i, this)) {
-        other.push(v);
-      }
-    }
-    return other;
-  };
-}
-
-Array.prototype.diff = function (a) {
-  return this.filter(function (i) {
-    return a.indexOf(i) < 0;
-  });
-};
-
-/*
- * String polyfills
-*/
-if (!String.prototype.startsWith) {
-  String.prototype.startsWith = function (searchString, position) {
-    position = position || 0;
-    return this.substr(position, searchString.length) === searchString;
-  };
-}
-
-if (!String.prototype.endsWith) {
-  String.prototype.endsWith = function (searchString, position) {
-    var subjectString = this.toString();
-    if (typeof position !== 'number' || !isFinite(position) || Math.floor(position) !== position || position > subjectString.length) {
-      position = subjectString.length;
-    }
-    position -= searchString.length;
-    var lastIndex = subjectString.lastIndexOf(searchString, position);
-    return lastIndex !== -1 && lastIndex === position;
-  };
-}
-
-if (!String.prototype.includes) {
-  String.prototype.includes = function (search, start) {
-    'use strict';
-    if (typeof start !== 'number') {
-      start = 0;
-    }
-
-    if (start + search.length > this.length) {
-      return false;
-    } else {
-      return this.indexOf(search, start) !== -1;
-    }
-  };
-}
-
-if (!('addRule' in CSSStyleSheet.prototype)) {
-  CSSStyleSheet.prototype.addRule = function (selector, rule, idx) {
-    return this.insertRule(selector + "{" + rule + "}", idx || 0);
-  }
-}
-
-
-/*
- * Add utility methods to the HUE object
-*/
-
-window.hueUtils = window.hueUtils || (function () {
-  'use strict';
-
-  var hueUtils = {};
-
-  hueUtils.bootstrapRatios = {
-    span3: function () {
-      var windowWidth = $(window).width();
-      if (windowWidth >= 1200) {
-        return 23.07692308;
-      } else if (windowWidth >= 768 && windowWidth <= 979) {
-        return 22.9281768;
-      } else {
-        return 23.17073171;
-      }
-    },
-    span9: function () {
-      var windowWidth = $(window).width();
-      if (windowWidth >= 1200) {
-        return 74.35897436;
-      } else if (windowWidth >= 768 && windowWidth <= 979) {
-        return 74.30939227;
-      } else {
-        return 74.3902439;
-      }
-    },
-    margin: function () {
-      return 2.56410256;
-    }
-  };
-
-  /*
-   * Convert text to URLs
-   * Selector arg can be jQuery or document.querySelectorAll()
-  */
-  hueUtils.text2Url = function (selectors) {
-    var i = 0,
-      len = selectors.length;
-
-    for (i; i < len; i++) {
-      var arr = [],
-        selector = selectors[i],
-        val = selector.innerHTML.replace(/&nbsp;/g, ' ').split(' ');
-
-      val.forEach(function(word) {
-        var matched = null,
-          re = /(https?:\/\/)?([\da-z\.-]+)\.([a-z\.]{2,6})([\/\w \.-]*)*\/?/gi;
-
-        if (re.test(word)) {
-          matched = word.match(re);
-          word = word.replace(matched, '<a href="' + matched + '">' + matched + '</a>')
-          arr.push(word);
-        } else {
-          arr.push(word);
-        }
-      });
-
-      selector.innerHTML = arr.join(' ');
-    }
-    return this;
-  };
-
-  /*
-   * Create a in-memory div, set it's inner text(which jQuery automatically encodes)
-   * then grab the encoded contents back out.
-  */
-
-  hueUtils.htmlEncode = function (value){
-    return $('<div/>').text(value).html();
-  };
-
-  hueUtils.html2text = function (value){
-    return $('<div/>').html(value).text().replace(/\u00A0/g, ' ');
-  };
-
-  hueUtils.goFullScreen = function () {
-    if (!document.fullscreenElement && !document.mozFullScreenElement && !document.webkitFullscreenElement && !document.msFullscreenElement) {
-      if (document.documentElement.requestFullscreen) {
-        document.documentElement.requestFullscreen();
-      } else if (document.documentElement.msRequestFullscreen) {
-        document.documentElement.msRequestFullscreen();
-      } else if (document.documentElement.mozRequestFullScreen) {
-        document.documentElement.mozRequestFullScreen();
-      } else if (document.documentElement.webkitRequestFullscreen) {
-        document.documentElement.webkitRequestFullscreen(Element.ALLOW_KEYBOARD_INPUT);
-      }
-    }
-  };
-
-  hueUtils.exitFullScreen = function () {
-    if (document.fullscreenElement ||
-        document.mozFullScreenElement || document.webkitFullscreenElement || document.msFullscreenElement) {
-      if (document.exitFullscreen) {
-        document.exitFullscreen();
-      } else if (document.msExitFullscreen) {
-        document.msExitFullscreen();
-      } else if (document.mozCancelFullScreen) {
-        document.mozCancelFullScreen();
-      } else if (document.webkitExitFullscreen) {
-        document.webkitExitFullscreen();
-      }
-    }
-  };
-
-  hueUtils.changeURL = function (newURL, params) {
-    var extraSearch = '';
-    if (params) {
-      var newSearchKeys = Object.keys(params);
-      if (newSearchKeys.length) {
-        while (newSearchKeys.length) {
-          var newKey = newSearchKeys.pop();
-          extraSearch += newKey + '=' + params[newKey];
-          if (newSearchKeys.length) {
-            extraSearch += '&';
-          }
-        }
-      }
-    }
-
-    if (typeof IS_EMBEDDED !== 'undefined' && IS_EMBEDDED) {
-      var search = window.location.search;
-      if (extraSearch) {
-        search += (search ? '&' : '?') + extraSearch
-      }
-      newURL = window.location.pathname + search + '#!' + newURL.replace('/hue', '');
-      window.history.pushState(null, null, newURL);
-      return;
-    }
-
-    var hashSplit = newURL.split('#');
-    var url = hashSplit[0];
-    if (extraSearch) {
-      url += (url.indexOf('?') === -1 ? '?' : '&') + extraSearch;
-    }
-    if (hashSplit.length > 1) {
-      url += '#' + hashSplit[1];
-    } else if (window.location.hash) {
-      url += window.location.hash;
-    }
-    window.history.pushState(null, null, url);
-  };
-
-  hueUtils.replaceURL = function (newURL) {
-    window.history.replaceState(null, null, newURL);
-  };
-
-  hueUtils.changeURLParameter = function (param, value) {
-    if (typeof IS_EMBEDDED !== 'undefined' && IS_EMBEDDED) {
-      var currentUrl = window.location.hash.replace('#!', '');
-      var parts = currentUrl.split('?');
-      var path = parts[0];
-      var search = parts.length > 1 ? parts[1] : '';
-      if (~search.indexOf(param + '=' + value)) {
-        return;
-      }
-      if (~search.indexOf(param + '=')) {
-        if (!value) {
-          search = search.replace(new RegExp(param + '=[^&]*&?'), '');
-        } else {
-          search = search.replace(new RegExp(param + '=[^&]*'), param + '=' + value);
-        }
-      } else if (value) {
-        if (search) {
-          search += '&';
-        }
-        search += param + '=' + value;
-      } else {
-        return;
-      }
-
-      hueUtils.changeURL(search ? path + '?' + search : path);
-    } else {
-      var newSearch = '';
-      if (window.location.getParameter(param, true) !== null) {
-        newSearch += '?';
-        window.location.search.replace(/\?/gi, '').split('&').forEach(function (p) {
-          if (p.split('=')[0] !== param) {
-            newSearch += p;
-          }
-        });
-        if (value){
-          newSearch += (newSearch !== '?' ? '&' : '') + param + '=' + value;
-        }
-      } else {
-        newSearch = window.location.search + (value ? (window.location.search.indexOf('?') > -1 ? '&' : '?') + param + '=' + value : '' );
-      }
-
-      if (newSearch === '?') {
-        newSearch = '';
-      }
-
-      hueUtils.changeURL(window.location.pathname + newSearch);
-    }
-  };
-
-  hueUtils.removeURLParameter = function (param) {
-    hueUtils.changeURLParameter(param, null);
-  };
-
-  /**
-   * @param {string} pseudoJson
-   * @constructor
-   */
-  hueUtils.parseHivePseudoJson = function (pseudoJson) {
-    // Hive returns a pseudo-json with parameters, like
-    // "{Lead Developer=John Foo, Lead Developer Email=jfoo@somewhere.com, date=2013-07-11 }"
-    var parsedParams = {};
-    if (pseudoJson && pseudoJson.length > 2){
-      var splits = pseudoJson.substring(1, pseudoJson.length-1).split(', ');
-      splits.forEach(function(part){
-        if (part.indexOf('=') > -1){
-          parsedParams[part.split('=')[0]] = part.split('=')[1];
-        }
-      });
-    }
-    return parsedParams;
-  };
-
-  hueUtils.isOverflowing = function (element) {
-    if (element instanceof jQuery) {
-      element = element[0];
-    }
-    return element.scrollHeight > element.clientHeight || element.scrollWidth > element.clientWidth;
-  };
-
-  /**
-   * @param {string} selector
-   * @param {Function} condition
-   * @param {Function} callback
-   * @param {number} [timeout]
-   * @constructor
-   */
-  hueUtils.waitForRendered = function (selector, condition, callback, timeout) {
-    var $el = selector instanceof jQuery ? selector: $(selector);
-    if (condition($el)) {
-      callback($el);
-    } else {
-      window.clearTimeout($el.data('waitForRenderTimeout'));
-      var waitForRenderTimeout = window.setTimeout(function () {
-        hueUtils.waitForRendered(selector, condition, callback);
-      }, timeout || 100);
-      $el.data('waitForRenderTimeout', waitForRenderTimeout);
-    }
-  };
-
-  /**
-   * @param {Function} observable
-   * @param {Function} callback
-   * @param {number} [timeout]
-   * @constructor
-   */
-  hueUtils.waitForObservable = function (observable, callback, timeout) {
-    if (observable()) {
-      callback(observable);
-    }
-    else {
-      var subscription = observable.subscribe(function(newValue) {
-        if (newValue) {
-          subscription.dispose();
-          callback(observable);
-        }
-      });
-    }
-  };
-
-  /**
-   * @param {Function} variable
-   * @param {Function} callback
-   * @param {number} [timeout]
-   * @constructor
-   */
-  hueUtils.waitForVariable = function (variable, callback, timeout) {
-    if (variable) {
-      callback(variable);
-    }
-    else {
-      window.setTimeout(function () {
-        hueUtils.waitForVariable(variable, callback);
-      }, timeout || 100)
-    }
-  };
-
-  hueUtils.scrollbarWidth = function () {
-    var $parent, $children, width;
-    $parent = $('<div style="width:50px;height:50px;overflow:auto"><div/></div>').appendTo(HUE_CONTAINER);
-    $children = $parent.children();
-    width = $children.innerWidth() - $children.height(99).innerWidth();
-    $parent.remove();
-    return width;
-  };
-
-  hueUtils.getSearchParameter = function (search, name, returnNull) {
-    name = name.replace(/[\[]/, "\\[").replace(/[\]]/, "\\]");
-    var regex = new RegExp("[\\?&]" + name + "=([^&#]*)"),
-        results = regex.exec(search);
-    if (returnNull && results === null){
-      return null;
-    }
-    return results === null ? "" : decodeURIComponent(results[1].replace(/\+/g, " "));
-  };
-
-  hueUtils.logError = function (error) {
-    if (typeof window.console !== 'undefined' && typeof window.console.error !== 'undefined') {
-      if (typeof error !== 'undefined') {
-        console.error(error);
-      }
-      console.error(new Error().stack);
-    }
-  };
-
-  hueUtils.equalIgnoreCase = function (a, b) {
-    return a && b && a.toLowerCase() === b.toLowerCase();
-  };
-
-  hueUtils.deXSS = function (str) {
-    if (typeof str !== 'undefined' && str !== null && typeof str === 'string') {
-      return str.replace(/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi, '');
-    }
-    return str;
-  }
-
-  hueUtils.getStyleFromCSSClass = function (cssClass) {
-    for (var i = 0; i < document.styleSheets.length; i++) {
-      var cssClasses = document.styleSheets[i].rules || document.styleSheets[i].cssRules;
-      for (var x = 0; x < cssClasses.length; x++) {
-        if (cssClasses[x].selectorText == cssClass) {
-          return (cssClasses[x].style) ? cssClasses[x].style : cssClasses[x];
-        }
-      }
-    }
-  };
-
-  hueUtils.highlight = function (text, searchTerm) {
-    if (searchTerm === '' || text === '') {
-      return text;
-    }
-
-    var remText = text;
-    var highLightedText = '';
-    searchTerm = searchTerm.toLowerCase();
-
-    do {
-      var remLowerText = remText.toLowerCase();
-      var startIndex = remLowerText.indexOf(searchTerm);
-      if(startIndex >= 0) {
-        highLightedText += remText.substring(0, startIndex) + '<strong>' + remText.substring(startIndex, startIndex + searchTerm.length) + '</strong>';
-        remText = remText.substring(startIndex + searchTerm.length);
-      } else {
-         highLightedText += remText;
-      }
-    } while (startIndex >= 0);
-
-    return highLightedText;
-  };
-
-  hueUtils.dfs = function(node, callback) {
-    if (!node || typeof(node) !== 'object') {
-      return;
-    }
-    Object.keys(node).forEach(function(key) {
-      callback(node, key);
-      hueUtils.dfs(node[key], callback);
-    });
-  };
-
-  hueUtils.deleteAllEmptyStringKey = function(node) {
-    var fDeleteEmptyStringKey = function (node, key) {
-      if (node[key] || typeof(node[key]) !== 'string') {
-        return;
-      }
-      delete node[key];
-    };
-    hueUtils.dfs(node, fDeleteEmptyStringKey);
-  };
-
-  function s4() {
-    return Math.floor((1 + Math.random()) * 0x10000)
-      .toString(16)
-      .substring(1);
-  }
-
-  hueUtils.UUID = function() {
-    return s4() + s4() + '-' + s4() + '-' + s4() + '-' + s4() + '-' + s4() + s4() + s4();
-  };
-
-
-  hueUtils.escapeOutput = function (str) {
-    return $('<span>').text(str).html().trim();
-  };
-
-  return hueUtils;
-
-})();
-
-if (!Object.keys) {
-
-  Object.keys = (function () {
-    'use strict';
-    var hasOwnProperty = Object.prototype.hasOwnProperty,
-        hasDontEnumBug = !({toString: null}).propertyIsEnumerable('toString'),
-        dontEnums = [
-          'toString',
-          'toLocaleString',
-          'valueOf',
-          'hasOwnProperty',
-          'isPrototypeOf',
-          'propertyIsEnumerable',
-          'constructor'
-        ],
-        dontEnumsLength = dontEnums.length;
-
-    return function (obj) {
-      if (typeof obj !== 'object' && (typeof obj !== 'function' || obj === null)) {
-        throw new TypeError('Object.keys called on non-object');
-      }
-
-      var result = [], prop, i;
-
-      for (prop in obj) {
-        if (hasOwnProperty.call(obj, prop)) {
-          result.push(prop);
-        }
-      }
-
-      if (hasDontEnumBug) {
-        for (i = 0; i < dontEnumsLength; i++) {
-          if (hasOwnProperty.call(obj, dontEnums[i])) {
-            result.push(dontEnums[i]);
-          }
-        }
-      }
-      return result;
-    };
-  }());
-}
-
-var hueDrop = (function () {
-  var draggableMeta = {};
-  huePubSub.subscribe('draggable.text.meta', function (meta) {
-    draggableMeta = meta;
-  });
-
-  return {
-    fromAssist: function (element, callback) {
-      if (typeof element === 'function' && !(element instanceof jQuery)) {
-        callback = element;
-      }
-      if (typeof element === 'string') {
-        element = $(element);
-      }
-      if (element.length > 0) {
-        element.droppable({
-          accept: '.draggableText',
-          drop: function (e, ui) {
-            var droppedText = ui.helper.text();
-            if (callback) {
-              callback({
-                text: ui.helper.text(),
-                meta: draggableMeta
-              });
-            }
-          }
-        });
-      }
-      else {
-        console.warn('hueDrop.fromAssist could not be attached to the element');
-      }
-    },
-    fromDesktop: function (element, callback, method) {
-      if (window.FileReader) {
-        if (typeof element === 'function' && !(element instanceof jQuery)) {
-          callback = element;
-        }
-        if (typeof element === 'string') {
-          element = $(element);
-        }
-
-        function handleFileSelect(e) {
-          e.stopPropagation();
-          e.preventDefault();
-          var dt = e.dataTransfer;
-          var files = dt.files;
-          for (var i = 0, f; f = files[i]; i++) {
-            var reader = new FileReader();
-            reader.onload = (function (file) {
-              return function (e) {
-                callback(e.target.result);
-              };
-            })(f);
-            switch (method) {
-              case 'arrayBuffer':
-                reader.readAsArrayBuffer(f);
-                break;
-              case 'binaryString':
-                reader.readAsBinaryString(f);
-                break;
-              case 'dataURL':
-                reader.readAsDataURL(f);
-                break;
-              default:
-                reader.readAsText(f);
-            }
-          }
-        }
-
-        function handleDragOver(e) {
-          e.stopPropagation();
-          e.preventDefault();
-          e.dataTransfer.dropEffect = 'copy';
-        }
-
-        if (element.length > 0) {
-          element[0].addEventListener('dragover', handleDragOver, false);
-          element[0].addEventListener('drop', handleFileSelect, false);
-        }
-        else {
-          console.warn('hueDrop.fromDesktop could not be attached to the element');
-        }
-
-      }
-      else {
-        console.warn('FileReader is not supported by your browser. Please consider upgrading to fully experience Hue!')
-      }
-    }
-  };
-})();
-
-if (!window.hueDebug) {
-  window.hueDebug = {};
-}
-
-window.hueDebug.clearCaches = function () {
-  var promises = [];
-  var clearInstance = function(prefix) {
-    promises.push(localforage.createInstance({ name: prefix + LOGGED_USERNAME }).clear());
-  };
-  clearInstance('HueContextCatalog_');
-  clearInstance('HueDataCatalog_');
-  clearInstance('HueDataCatalog_hive_');
-  clearInstance('HueDataCatalog_hive_multiTable_');
-  clearInstance('HueDataCatalog_impala_');
-  clearInstance('HueDataCatalog_impala_multiTable_');
-  Promise.all(promises).then(function () {
-    console.log('Done! Refresh the browser.');
-  })
-};
-
-var hueDebugTimer = (function () {
-  var initialTime = null;
-  var times = [];
-  var withConsole = false;
-  return {
-    start: function (enableConsole) {
-      times = [];
-      initialTime = (new Date()).getTime();
-      times.push(initialTime);
-      if (enableConsole){
-        withConsole = true;
-        console.log('Start', initialTime);
-      }
-    },
-    mark: function (label) {
-      var mark = (new Date()).getTime();
-      times.push(mark);
-      if (withConsole){
-        console.log(label ? label : times.length, mark - times[times.length - 2], mark - initialTime);
-      }
-      return mark - times[times.length - 2];
-    },
-    total: function () {
-      return times[times.length - 1] - times[0];
-    },
-    timeline: function () {
-      return times;
-    }
-  };
-})();
-
-var hueAnalytics = (function () {
-  return {
-    log: function (app, page) {
-      if (typeof trackOnGA == 'function') {
-        trackOnGA(app + '/' + page);
-      }
-    },
-    convert: function (app, page) {
-      $.post("/desktop/log_analytics", {
-        page: app + '/' + page,
-      });
-    }
-  };
-})();
-
-Number.prototype.toHHMMSS = function (skipZeroSeconds) {
-  var n = this;
-  var millis = n % 1000;
-  n = (n - millis) / 1000;
-  millis = +(millis/10).toFixed();
-  var seconds = n % 60;
-  n = (n - seconds) / 60;
-  var minutes = n % 60;
-  n = (n - minutes) / 60;
-  var hours = n % 24;
-  var days = (n - hours) / 24;
-  var val = $.trim((days > 0 ? days + "d, " : "") + (hours > 0 ? hours + "h, " : "") + (minutes > 0 ? minutes + "m, " : "") + ((skipZeroSeconds && seconds === 0) ? '' : (seconds + (millis > 0 && minutes == 0 && hours == 0 && days == 0 ? "." + millis : "") + "s")));
-  if (val[val.length - 1] === ',') {
-    val = val.substr(0, val.length - 1);
-  }
-  return val;
-};
-
-String.prototype.hashCode = function() {
-  var hash = 0, i, chr, len;
-  if (this.length === 0) return hash;
-  for (i = 0, len = this.length; i < len; i++) {
-    chr   = this.charCodeAt(i);
-    hash  = ((hash << 5) - hash) + chr;
-    hash |= 0; // Convert to 32bit integer
-  }
-  return hash;
-};
-
-String.prototype.regexLastIndexOf = function (regex, startpos) {
-  regex = (regex.global) ? regex : new RegExp(regex.source, "g" + (regex.ignoreCase ? "i" : "") + (regex.multiLine ? "m" : ""));
-  if (typeof (startpos) == "undefined") {
-    startpos = this.length;
-  } else if (startpos < 0) {
-    startpos = 0;
-  }
-  var stringToWorkWith = this.substring(0, startpos + 1);
-  var lastIndexOf = -1;
-  var nextStop = 0;
-  while ((result = regex.exec(stringToWorkWith)) != null) {
-    lastIndexOf = result.index;
-    regex.lastIndex = ++nextStop;
-  }
-  return lastIndexOf;
-};
-
-if (!('getParameter' in window.location)) {
-  window.location.getParameter = function (name, returnNull) {
-    return hueUtils.getSearchParameter(window.location.search, name, returnNull);
-  };
-}

+ 0 - 106
desktop/core/src/desktop/static/desktop/js/hue4.utils.js

@@ -1,106 +0,0 @@
-// Licensed to Cloudera, Inc. under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  Cloudera, Inc. 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.
-
-(function () {
-
-  var originalSetInterval = window.setInterval;
-  var originalClearInterval = window.clearInterval;
-  var hueIntervals = [];
-
-  /**
-   * @param {string} [app] - context for the intervals
-   */
-  window.getIntervals = function(app) {
-    if (app) {
-      return hueIntervals.filter(function(obj){ return obj.app == app; });
-    }
-    return hueIntervals;
-  }
-
-  /**
-   * @param {Function} fn - the function to be called at intervals
-   * @param {Number} timeout - timeout in milliseconds
-   * @param {string} [app] - context for the interval
-   */
-  window.setInterval = function (fn, timeout, app) {
-    var id = originalSetInterval(fn, timeout);
-    hueIntervals.push({
-      fn: fn,
-      timeout: timeout,
-      app: app,
-      id: id,
-      originalId: id,
-      status: 'running'
-    });
-    return id;
-  }
-
-  /**
-   * @param {Number} id - the original interval id generated by window.setInterval
-   */
-
-  window.clearInterval = function (id) {
-    var foundIntervals = hueIntervals.filter(function (obj) {
-      return obj.originalId === id
-    });
-    if (foundIntervals && foundIntervals.length > 0) {
-      originalClearInterval(foundIntervals[0].id);
-    }
-    else {
-      originalClearInterval(id);
-    }
-    hueIntervals = hueIntervals.filter(function (obj) {
-      return obj.originalId !== id
-    });
-  }
-
-  /**
-   * @param {string} app - context for the intervals to be suspended
-   */
-  window.pauseAppIntervals = function (app) {
-    hueIntervals.forEach(function (interval) {
-      if (typeof interval.app !== 'undefined' && interval.app !== null && (interval.app === app || (interval.app.split('-') && interval.app.split('-')[0] === app))) {
-        interval.status = 'paused';
-        originalClearInterval(interval.id);
-      }
-    });
-  }
-
-  /**
-   * @param {string} app - context for the intervals to be restarted
-   */
-  window.resumeAppIntervals = function (app) {
-    hueIntervals.forEach(function (interval) {
-      if (typeof interval.app !== 'undefined' && interval.app !== null && (interval.app == app || interval.app.split('-')[0] === app) && interval.status === 'paused') {
-        interval.status = 'running';
-        var id = originalSetInterval(interval.fn, interval.timeout);
-        interval.id = id;
-      }
-    });
-  }
-
-  /**
-   * @param {string} app - context for the intervals to be cleared
-   */
-  window.clearAppIntervals = function (app) {
-    hueIntervals.forEach(function (interval) {
-      if (interval.app == app || (typeof interval.app !== 'undefined' && interval.app !== null && interval.app.split('-')[0] === app)) {
-        window.clearInterval(interval.originalId);
-      }
-    });
-  }
-
-})()

+ 0 - 7699
desktop/core/src/desktop/static/desktop/js/ko.hue-bindings.js

@@ -1,7699 +0,0 @@
-// Licensed to Cloudera, Inc. under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  Cloudera, Inc. 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.
-
-(function () {
-  ko.extenders.numeric = function (target, config) {
-    var precision = typeof config.precision === 'undefined' ? config : config.precision;
-    var roundingMultiplier = Math.pow(10, precision);
-
-    var result = ko.computed({
-      read: target,
-      write: function (newValue) {
-        var current = target(),
-            newValueAsNum = isNaN(newValue) ? 0 : parseFloat(+newValue),
-            valueToWrite = Math.round(newValueAsNum * roundingMultiplier) / roundingMultiplier;
-
-        if (newValue === '' && config.allowEmpty) {
-          valueToWrite = newValue;
-        }
-        if (valueToWrite !== current) {
-          target(valueToWrite);
-        } else {
-          if (newValue !== current) {
-            target.notifySubscribers(valueToWrite);
-          }
-        }
-      }
-    }).extend({ notify: 'always' });
-    result(target());
-    return result;
-  };
-
-  ko.extenders.maxLength = function (target, maxLength) {
-    var result = ko.computed({
-      read: target,
-      write: function (val) {
-        if (maxLength > 0) {
-          if (val.length > maxLength) {
-            var limitedVal = val.substring(0, maxLength);
-            if (target() === limitedVal) {
-              target.notifySubscribers();
-            }
-            else {
-              target(limitedVal);
-            }
-          }
-          else {
-            target(val);
-          }
-        }
-        else {
-          target(val);
-        }
-      }
-    }).extend({notify: 'always'});
-    result(target());
-    return result;
-  };
-
-  // we override the default html binding to prevent XSS/JS injection
-  var originalHtmlBinding = ko.bindingHandlers.html;
-  ko.bindingHandlers.html = {
-    init: function (element, valueAccessor, allBindings, viewModel, bindingContext) {
-      var newValueAccessor = function () {
-        return hueUtils.deXSS(ko.unwrap(valueAccessor()));
-      };
-      originalHtmlBinding.init(element, newValueAccessor, allBindings, viewModel, bindingContext);
-    },
-    update: function (element, valueAccessor, allBindings, viewModel, bindingContext) {
-      var newValueAccessor = function () {
-        return hueUtils.deXSS(ko.unwrap(valueAccessor()));
-      };
-      originalHtmlBinding.update(element, newValueAccessor, allBindings, viewModel, bindingContext);
-    },
-  };
-
-  ko.bindingHandlers.htmlUnsecure = {
-    init: function (element, valueAccessor, allBindings, viewModel, bindingContext) {
-      originalHtmlBinding.init(element, valueAccessor, allBindings, viewModel, bindingContext);
-    },
-    update: function (element, valueAccessor, allBindings, viewModel, bindingContext) {
-      originalHtmlBinding.update(element, valueAccessor, allBindings, viewModel, bindingContext);
-    },
-  };
-
-  ko.observableDefault = function () {
-    var prop = arguments[0], defvalue = arguments[1] || null;
-    return ko.observable(typeof prop != "undefined" && prop != null ? prop : defvalue);
-  };
-
-  ko.observableArrayDefault = function () {
-    var prop = arguments[0], defvalue = arguments[1] || null;
-    return ko.observableArray(typeof prop != "undefined" && prop != null ? prop : defvalue);
-  };
-
-  ko.bindingHandlers.hueLink = {
-    init: function (element, valueAccessor, allBindings, viewModel, bindingContext) {
-      ko.bindingHandlers.click.init(element, function () {
-        return function (data, event) {
-          var url = ko.unwrap(valueAccessor());
-          if (url) {
-            var prefix = '';
-            if (IS_HUE_4) {
-              prefix = '/hue' + (url.indexOf('/') === 0 ? '' : '/');
-            }
-            if ($(element).attr('target')) {
-              window.open(prefix + url, $(element).attr('target'));
-            } else if (event.ctrlKey || event.metaKey || event.which === 2) {
-              window.open(prefix + url, '_blank');
-            } else {
-              huePubSub.publish('open.link', url);
-            }
-          }
-        }
-      }, allBindings, viewModel, bindingContext);
-
-      ko.bindingHandlers.hueLink.update(element, valueAccessor);
-    },
-    update: function (element, valueAccessor) {
-      var url = ko.unwrap(valueAccessor());
-      if (url) {
-        if (IS_HUE_4) {
-          $(element).attr('href', '/hue' + (url.indexOf('/') === 0 ? url : '/' + url));
-        } else {
-          $(element).attr('href', url);
-        }
-      } else {
-        $(element).attr('href', 'javascript: void(0);');
-      }
-    }
-  };
-
-  ko.bindingHandlers.publish = {
-    init: function (element, valueAccessor, allBindings, viewModel, bindingContext) {
-      ko.bindingHandlers.click.init(element, function () {
-        return function () {
-          var topicDetails = ko.unwrap(valueAccessor());
-          if (typeof topicDetails === 'string') {
-            huePubSub.publish(topicDetails)
-          } else if (typeof topicDetails === 'object') {
-            var keys = Object.keys(topicDetails);
-            if (keys.length === 1) {
-              huePubSub.publish(keys[0], topicDetails[keys[0]]);
-            }
-          }
-        }
-      }, allBindings, viewModel, bindingContext);
-    },
-  };
-
-  ko.bindingHandlers.clickToCopy = {
-    init: function (element, valueAccessor) {
-      $(element).click(function () {
-        var $input = $('<textarea>').css({ opacity: 0 }).val(ko.unwrap(valueAccessor())).appendTo(HUE_CONTAINER).select();
-        document.execCommand('copy');
-        $input.remove()
-      });
-    }
-  };
-
-  ko.bindingHandlers.fetchMore = {
-    init: function (element, valueAccessor) {
-      var options = valueAccessor();
-      var $element = $(element);
-
-      var throttle = -1;
-      $element.on('scroll.fetchMore', function () {
-        window.clearTimeout(throttle);
-        throttle = window.setTimeout(function () {
-          if ((element.scrollTop + $element.innerHeight() >= element.scrollHeight - 10) && ko.unwrap(options.hasMore) && !ko.unwrap(options.loadingMore)) {
-            options.fetchMore();
-          }
-        }, 100);
-      });
-
-      ko.utils.domNodeDisposal.addDisposeCallback(element, function() {
-        $element.off('scroll.fetchMore');
-      });
-    }
-  };
-
-  ko.bindingHandlers.autocomplete = {
-    init: function (element, valueAccessor) {
-      var options = valueAccessor();
-      var $element = $(element);
-
-      var delay = 400;
-
-      var showSpinner = function () {
-        if (options.showSpinner) {
-          $element.addClass('input-spinner');
-        }
-      };
-
-      var spinThrottle = -1;
-      var hideSpinner = function () {
-        window.clearTimeout(spinThrottle);
-        $element.removeClass('input-spinner');
-      };
-
-      options = $.extend({
-        addCount: false,
-        closeOnEnter: true,
-        blurOnEnter: false,
-        classPrefix: 'hue-',
-        showOnFocus: false,
-        minLength: 0,
-        limitWidthToInput: false,
-        minWidth: 200,
-        disabled: true,
-        delay: delay,
-        search: function(event, ui) {
-          window.clearTimeout(spinThrottle);
-          if (!$element.hueAutocomplete("option", "disabled")) {
-            spinThrottle = window.setTimeout(showSpinner, 50);
-          }
-        },
-        open: function(event, ui) {
-          hideSpinner();
-        },
-        close: function(event, ui) {
-          hideSpinner();
-        }
-      }, options);
-
-      if (options.addCount) {
-        var oldSource = options.source;
-        options.source = function (request, callback) {
-          oldSource(request, function (values) {
-            callback(values);
-            var $menu = $($element.data('custom-hueAutocomplete').menu.element);
-            $menu.children('.autocomplete-count').remove();
-            var count = options.realCountCallback ? options.realCountCallback() : values.filter(function (value) { return ! value.divider && ! value.noMatch }).length;
-            if (count > 0) {
-              $('<div>').addClass('autocomplete-count').text('(' + count + ')').appendTo($menu);
-            }
-          });
-        }
-      }
-
-      if (typeof $().hueAutocomplete === 'undefined') {
-        $.widget('custom.hueAutocomplete', $.ui.autocomplete, {
-          _renderItemData: function( ul, item ) {
-            if (item.error && this.options.errorTemplate) {
-              var $li = $('<li data-bind="template: { name: \'' + this.options.errorTemplate + '\' }">')
-                  .addClass(this.options.classPrefix + 'autocomplete-item')
-                  .appendTo(ul)
-                  .data( "ui-autocomplete-item", item );
-              ko.applyBindings(item, $li[0]);
-            } else if (item.noMatch && this.options.noMatchTemplate) {
-              var $li = $('<li data-bind="template: { name: \'' + this.options.noMatchTemplate + '\' }">')
-                  .addClass(this.options.classPrefix + 'autocomplete-item')
-                  .appendTo(ul)
-                  .data( "ui-autocomplete-item", item );
-              ko.applyBindings(item, $li[0]);
-            } else if (item.divider) {
-              $('<li/>').addClass(this.options.classPrefix + 'autocomplete-divider').appendTo(ul);
-            } else {
-              var $li = $('<li data-bind="template: { name: \'' + this.options.itemTemplate + '\', data: $data }">')
-                .addClass(this.options.classPrefix + 'autocomplete-item')
-                .appendTo(ul)
-                .data( "ui-autocomplete-item", item );
-              ko.applyBindings(item.data, $li[0]);
-            }
-          },
-          _resizeMenu: function () {
-            // This overrides the default behaviour of using dropdown width of the same size as input autocomplete box
-            if (options.limitWidthToInput) {
-              this.menu.element.outerWidth(options.minWidth);
-            }
-          },
-          _renderMenu: function (ul, items) {
-            var self = this;
-            hideSpinner();
-            if (options.limitWidthToInput) {
-              ul.css('max-width', Math.max(options.minWidth, $element.outerWidth(true)) + 'px');
-            }
-
-            ul.addClass(this.options.classPrefix + 'autocomplete');
-            $.each(items, function (index, item) {
-              self._renderItemData(ul, item);
-            });
-          }
-        });
-      }
-
-      if (options.closeOnEnter || options.onEnter || options.blurOnEnter) {
-        $element.on('keyup', function (e) {
-          if(e.which === 13) {
-            if (options.reopenPattern && options.reopenPattern.test($element.val())) {
-              window.setTimeout(function () {
-                $element.hueAutocomplete('search', $element.val());
-              }, 0);
-              return;
-            }
-            if (options.closeOnEnter) {
-              hideSpinner();
-              $element.hueAutocomplete('close');
-              // Prevent autocomplete on enter
-              $element.hueAutocomplete("option", "disabled", true);
-              window.setTimeout(function () {
-                $element.hueAutocomplete("option", "disabled", false);
-              }, delay + 200);
-            }
-            if (options.valueObservable) {
-              options.valueObservable($element.val());
-            }
-            if (options.onEnter) {
-              options.onEnter();
-            }
-            if (options.blurOnEnter) {
-              hideSpinner();
-              $element.blur();
-            }
-          }
-        });
-      }
-
-      $element.on('keydown', function (e) {
-        // ctrl + backspace to delete words
-        if (e.which === 8 && e.ctrlKey) {
-          var lastSpaceOrColon = Math.max($element.val().lastIndexOf(' '), $element.val().lastIndexOf(':'));
-          if (lastSpaceOrColon < $element.val().length - 1) {
-            if (lastSpaceOrColon !== -1) {
-              $element.val($element.val().substring(0, lastSpaceOrColon + 1));
-            } else {
-              $element.val('');
-            }
-            e.preventDefault();
-            return false;
-          }
-        } else if (e.which === 32 && e.ctrlKey) {
-          $element.hueAutocomplete('search', $element.val());
-        }
-      });
-
-      if (options.showOnFocus) {
-        $element.on('focus', function () {
-          $element.hueAutocomplete('search', $element.val());
-        })
-      }
-
-      var closeSubscription = huePubSub.subscribe('autocomplete.close', function () {
-        hideSpinner();
-        $element.hueAutocomplete('close');
-      });
-
-      ko.utils.domNodeDisposal.addDisposeCallback(element, function() {
-        closeSubscription.remove();
-      });
-
-      if (options.reopenPattern || options.valueObservable || options.onSelect) {
-        var oldSelect = options.select;
-        options.select = function (event, ui) {
-          if (options.reopenPattern && options.reopenPattern.test(ui.item.value)) {
-            window.setTimeout(function () {
-              $element.hueAutocomplete('search', $element.val());
-            }, 0);
-            return;
-          }
-          if (options.valueObservable) {
-            options.valueObservable(ui.item.value);
-          }
-          if (options.onSelect) {
-            options.onSelect(ui.item);
-          }
-          if (oldSelect) {
-            oldSelect(event, ui);
-          }
-        };
-      }
-
-      $element.hueAutocomplete(options);
-
-      var enableAutocomplete = function () {
-        if ($element.data('custom-hueAutocomplete')) {
-          $element.hueAutocomplete("option", "disabled", false);
-          $element.off('click', enableAutocomplete)
-        } else {
-          window.setTimeout(enableAutocomplete, 200);
-        }
-      };
-      // IE 11 trick to prevent it from being shown on page refresh
-      $element.on('click', enableAutocomplete)
-    }
-  };
-
-  ko.bindingHandlers.tagEditor = {
-    init: function (element, valueAccessor) {
-      var options = valueAccessor();
-      var $element = $(element);
-
-      var validRegExp = options.validRegExp ? new RegExp(options.validRegExp) : undefined;
-
-      var showValidationError = function () {
-        var $errorWrapper = $element.siblings('.selectize-error');
-        if (options.invalidMessage && $errorWrapper.length > 0) {
-          $errorWrapper.find('.message').text(options.invalidMessage);
-          $errorWrapper.show();
-          window.setTimeout(function () {
-            $errorWrapper.fadeOut(400, function () {
-              $errorWrapper.hide();
-            })
-          }, 5000);
-        }
-      };
-
-      options = $.extend({
-        plugins: ['remove_button'],
-        options: $.map(options.setTags(), function (value) { return { value: value, text: value } }),
-        delimiter: ',',
-        items: options.setTags(),
-        closeAfterSelect: true,
-        persist: true,
-        preload: true,
-        create: function(input) {
-          if (typeof validRegExp !== 'undefined' && !validRegExp.test(input)) {
-            showValidationError();
-            return false;
-          }
-
-          return {
-            value: input.replace(/\s/g, '-'),
-            text: input.replace(/\s/g, '-')
-          }
-        }
-      }, options);
-
-      var $readOnlyContainer = $('<div>').hide().addClass('selectize-control selectize-read-only multi').attr('style', $element.attr('style')).insertAfter($(element));
-
-      if (!options.readOnly) {
-        $readOnlyContainer.on('mouseover', function () {
-          $readOnlyContainer.find('.selectize-actions').addClass('selectize-actions-visible');
-        });
-
-        $readOnlyContainer.on('mouseout', function () {
-          $readOnlyContainer.find('.selectize-actions').removeClass('selectize-actions-visible');
-        });
-      }
-
-      $element.hide();
-
-      var currentSelectize;
-      var optionsBeforeEdit = [];
-
-      var saveOnClickOutside = function (event) {
-        if ($.contains(document, event.target) && currentSelectize && !$.contains(currentSelectize.$wrapper[0], event.target)) {
-          if (currentSelectize.getValue() !== optionsBeforeEdit.join(',')) {
-            options.onSave(currentSelectize.getValue());
-          }
-          $(document).off('click', saveOnClickOutside);
-          $(document).off('keyup', hideOnEscape);
-          showReadOnly();
-        }
-      };
-
-      var hideOnEscape = function (event) {
-        if (event.which === 27) {
-          showReadOnly();
-        }
-      };
-
-      var sizeCheckInterval = -1;
-
-      ko.utils.domNodeDisposal.addDisposeCallback(element, function() {
-        window.clearInterval(sizeCheckInterval);
-      });
-
-      var showEdit = function () {
-        window.clearInterval(sizeCheckInterval);
-        optionsBeforeEdit = options.setTags().concat();
-        options.options = $.map(options.setTags(), function (value) { return { value: value, text: value } });
-        currentSelectize = $element.selectize(options)[0].selectize;
-        $readOnlyContainer.hide();
-        $element.next().find('.selectize-input').css('padding-right', '38px');
-        $element.next().find('input').focus();
-        var $editActions = $('<div>').addClass('selectize-actions').appendTo($element.next());
-        $('<i>').addClass('fa fa-check').click(function () {
-          if (currentSelectize.getValue() !== optionsBeforeEdit.join(',')) {
-            options.onSave(currentSelectize.getValue());
-          }
-          showReadOnly();
-        }).appendTo($editActions);
-        $('<i>').addClass('fa fa-close').click(function () {
-          showReadOnly();
-        }).appendTo($editActions);
-        window.setTimeout(function () {
-          $(document).on('click', saveOnClickOutside);
-          $(document).on('keyup', hideOnEscape);
-        }, 0);
-      };
-
-      var lastKnownOffsetWidth = -1;
-      var lastKnownOffsetHeight = -1;
-
-      var addReadOnlyTagsTillOverflow = function ($readOnlyInner) {
-        $readOnlyInner.empty();
-        var tagElements = [];
-        options.setTags().forEach(function (tag) {
-          tagElements.push($('<div>').text(tag).appendTo($readOnlyInner));
-        });
-
-        if (! options.readOnly && !options.hasErrors()) {
-          $('<i>').addClass('fa fa-pencil selectize-edit pointer').attr('title', HUE_I18n.selectize.editTags).appendTo($readOnlyInner);
-          $readOnlyInner.click(function () {
-            showEdit();
-          });
-        }
-
-        if (!options.overflowEllipsis) {
-          return;
-        }
-
-        if ($readOnlyInner[0].offsetHeight < $readOnlyInner[0].scrollHeight || $readOnlyInner[0].offsetWidth < $readOnlyInner[0].scrollWidth && tagElements.length) {
-          tagElements[tagElements.length - 1].after($('<div>').addClass('hue-tag-overflow').text('...'));
-        }
-
-        while (tagElements.length && ($readOnlyInner[0].offsetHeight < $readOnlyInner[0].scrollHeight || $readOnlyInner[0].offsetWidth < $readOnlyInner[0].scrollWidth)) {
-          tagElements.pop().remove();
-        }
-
-        lastKnownOffsetWidth = $readOnlyInner[0].offsetWidth;
-        lastKnownOffsetHeight = $readOnlyInner[0].offsetHeight;
-      };
-
-      var showReadOnly = function () {
-        window.clearInterval(sizeCheckInterval);
-        $(document).off('click', saveOnClickOutside);
-        $(document).off('keyup', hideOnEscape);
-        if (currentSelectize) {
-          currentSelectize.destroy();
-          $element.hide();
-          $element.val(options.setTags().join(','))
-        }
-        $readOnlyContainer.empty();
-        var $readOnlyInner = $('<div>').addClass('selectize-input items not-full has-options has-items').appendTo($readOnlyContainer);
-        if (options.setTags().length > 0) {
-          addReadOnlyTagsTillOverflow($readOnlyInner);
-          if (options.overflowEllipsis) {
-            sizeCheckInterval = window.setInterval(function () {
-              if ($readOnlyInner[0].offsetWidth !== lastKnownOffsetWidth || $readOnlyInner[0].offsetHeight !== lastKnownOffsetHeight) {
-                addReadOnlyTagsTillOverflow($readOnlyInner);
-              }
-            }, 500);
-          }
-        } else {
-          if (options.hasErrors()) {
-            $('<span>').addClass('selectize-no-tags').text(options.errorMessage).appendTo($readOnlyInner);
-          } else {
-            $('<span>').addClass('selectize-no-tags').text(options.emptyPlaceholder).appendTo($readOnlyInner);
-          }
-
-          if (! options.readOnly && !options.hasErrors()) {
-            $('<i>').addClass('fa fa-pencil selectize-edit pointer').attr('title', HUE_I18n.selectize.editTags).appendTo($readOnlyInner);
-            $readOnlyInner.click(function () {
-              showEdit();
-            });
-          }
-        }
-
-        $readOnlyContainer.attr('title', options.setTags().join(', '));
-
-        $readOnlyContainer.show();
-      };
-
-      showReadOnly();
-    }
-  };
-
-  window.MultiLineEllipsisHandler = (function () {
-
-    function MultiLineEllipsisHandler(options) {
-      var self = this;
-
-      self.element = options.element;
-      self.$element = $(options.element);
-      self.overflowHeight = options.overflowHeight;
-      self.expandable = options.expandable;
-      self.expandClass = options.expandClass;
-      self.expandActionClass = options.expandActionClass;
-      self.overflowing = options.overflowing;
-
-      self.onActionRender = options.onActionRender;
-
-      self.lastKnownOffsetHeight;
-      self.lastKnownOffsetWidth;
-      self.isOverflowing;
-
-      self.expanded = options.expanded || ko.observable(false);
-      self.updateOverflowHeight();
-
-      self.contents = options.text;
-      self.element.innerHTML = self.contents;
-
-      var linkRegex = /(?:(?:[a-z]+:\/\/)|www\.)[^\s\/]+(?:[.\/]\S+)*[^\s`!()\[\]{};:'".,<>?«»“”‘’]/ig;
-
-      self.renderContents = function (contents) {
-        if (options.linkify) {
-          return hueUtils.deXSS(contents.replace(linkRegex, function (val) {
-            return '<a href="' + (val.toLowerCase().indexOf('www') === 0 ? 'http://' + val : val) + '" target="_blank">' + val + '</a>';
-          }));
-        }
-        return hueUtils.deXSS(contents);
-      };
-
-      self.delayedResumeTimeout = window.setTimeout(function () {
-        self.resume();
-      }, 0);
-    }
-
-    MultiLineEllipsisHandler.prototype.updateOverflowHeight = function () {
-      var self = this;
-      if (self.overflowHeight) {
-        self.$element.css('max-height', self.expanded() ? '' : self.overflowHeight);
-        self.$element.css('overflow', self.expanded() ? '' : 'hidden');
-      }
-    };
-
-    MultiLineEllipsisHandler.prototype.resume = function () {
-      var self = this;
-      self.refresh();
-      window.clearInterval(self.sizeCheckInterval);
-      self.sizeCheckInterval = window.setInterval(function () {
-        if (self.element.offsetWidth !== self.lastKnownOffsetWidth || self.element.offsetHeight !== self.lastKnownOffsetHeight) {
-          self.refresh();
-        }
-      }, 500);
-    };
-
-    MultiLineEllipsisHandler.prototype.pause = function () {
-      var self = this;
-      window.clearTimeout(self.delayedResumeTimeout);
-      window.clearInterval(self.sizeCheckInterval);
-    };
-
-    MultiLineEllipsisHandler.prototype.dispose = function () {
-      var self = this;
-      self.pause();
-    };
-
-    var checkOverflow = function (element) {
-      return element.offsetHeight < element.scrollHeight || element.offsetWidth < element.scrollWidth
-    };
-
-    MultiLineEllipsisHandler.prototype.refresh = function () {
-      var self = this;
-      self.$element.empty();
-      var textElement = $('<span>').appendTo(self.$element)[0];
-      if (self.expandable) {
-        textElement.innerHTML = self.renderContents ? self.renderContents(self.contents) : self.contents;
-        if (self.expanded() || checkOverflow(self.element)) {
-          self.$element.append('&nbsp;');
-          var $expandLink = $('<a href="javascript:void(0);"><i class="fa fa-fw ' + (self.expanded() ? 'fa-chevron-up' : 'fa-chevron-down') + '"></i></a>');
-          if (self.expandActionClass) {
-            $expandLink.addClass(self.expandActionClass);
-          }
-          $expandLink.appendTo(self.$element);
-          $expandLink.add(textElement).click(function (e) {
-            self.expanded(!self.expanded());
-            self.updateOverflowHeight();
-            if (self.expanded()) {
-              if (self.expandClass) {
-                self.$element.addClass(self.expandClass);
-              }
-              self.refresh();
-              self.pause();
-            } else {
-              if (self.expandClass) {
-                self.$element.removeClass(self.expandClass);
-              }
-              self.resume();
-            }
-          })
-        }
-      } else {
-        textElement.innerHTML = self.renderContents ? self.renderContents(self.contents) : self.contents;
-      }
-
-      if (self.onActionRender) {
-        self.onActionRender(self.$element, checkOverflow(self.element));
-      }
-
-      self.isOverflowing = false;
-
-      if (!self.expanded()) {
-        while (checkOverflow(self.element)) {
-          self.isOverflowing = true;
-          var contents = $(textElement).contents();
-          var lastContent = contents[contents.length - 1];
-          // Check for text node
-          if (lastContent.nodeType === 3 ) {
-            var lastSpaceIndex = lastContent.textContent.regexLastIndexOf(/\s\S+/);
-            if (lastSpaceIndex !== -1) {
-              lastContent.replaceWith(document.createTextNode(lastContent.textContent.substring(0, lastSpaceIndex) + '...'));
-            } else if (contents.length > 1) {
-              textElement.removeChild(lastContent);
-            } else {
-              break;
-            }
-          } else if (contents.length > 1) { // Remove any elements like links
-            textElement.removeChild(lastContent)
-          }
-        }
-      }
-
-      if (ko.isObservable(self.overflowing) && self.overflowing() !== self.isOverflowing) {
-        self.overflowing(self.isOverflowing);
-      }
-      self.lastKnownOffsetHeight = self.element.offsetHeight;
-      self.lastKnownOffsetWidth = self.element.offsetWidth;
-    };
-
-    MultiLineEllipsisHandler.prototype.setText = function (text) {
-      var self = this;
-      self.contents = text;
-      self.refresh();
-    };
-
-    return MultiLineEllipsisHandler;
-  })();
-
-  ko.bindingHandlers.multiLineEllipsis = {
-    after: ['text', 'value'],
-    init: function (element, valueAccessor) { },
-    update: function (element, valueAccessor) {
-      var options = {};
-      if (valueAccessor && ko.isObservable(valueAccessor())) {
-        options.overflowing = valueAccessor();
-      } else if (valueAccessor) {
-        options = valueAccessor() || {};
-      }
-      var multiLineEllipsisHandler = new MultiLineEllipsisHandler({
-        element: element,
-        text: element.textContent,
-        overflowing: options.overflowing,
-        linkify: true,
-        expandable: options.expandable,
-        expanded: options.expanded,
-        expandActionClass: options.expandActionClass,
-        expandClass: options.expandClass
-      });
-
-      ko.utils.domNodeDisposal.addDisposeCallback(element, function() {
-        multiLineEllipsisHandler.dispose();
-      });
-    }
-  };
-
-  ko.bindingHandlers.toggleOverflow = {
-    render: function ($element, options) {
-      if (hueUtils.isOverflowing($element.find('.toggle-overflow'))) {
-        $('<div>').addClass('toggle-overflow-toggle').html('<i class="fa fa-caret-down muted"></i>').appendTo($element);
-        $element.on('click', function () {
-          if ($element.find('.toggle-overflow-toggle i').hasClass('fa-caret-down')){
-            $element.find('.toggle-overflow').css('height', '');
-            $element.css('cursor', 'n-resize');
-            $element.find('.toggle-overflow-toggle').removeClass('toggle-hidden').css('cursor', 'n-resize');
-            $element.find('.toggle-overflow-toggle i').removeClass('fa-caret-down').addClass('fa-caret-up');
-          } else {
-            if (options.height) {
-              $element.find('.toggle-overflow').height(options.height);
-            }
-            $element.css('cursor', 's-resize');
-            $element.find('.toggle-overflow-toggle').addClass('toggle-hidden').css('cursor', 's-resize');
-            $element.find('.toggle-overflow-toggle i').removeClass('fa-caret-up').addClass('fa-caret-down');
-          }
-        });
-      }
-    },
-
-    init: function (element, valueAccessor) {
-      var $element = $(element);
-      var options = valueAccessor() || {};
-      $element.wrapInner('<div class="toggle-overflow"></div>');
-      if (options.height) {
-        $element.find('.toggle-overflow').height(options.height);
-      }
-      if (options.width) {
-        $element.find('.toggle-overflow').width(options.width);
-      }
-    },
-
-    update: function (element, valueAccessor) {
-      var $element = $(element);
-      var options = valueAccessor() || {};
-      window.setTimeout(function () {
-        ko.bindingHandlers.toggleOverflow.render($element, options);
-      }, 100);
-    }
-  };
-
-  ko.bindingHandlers.draggableText = {
-    init: function (element, valueAccessor) {
-      var $element = $(element);
-      var options = valueAccessor();
-      if ((ko.isObservable(options.text) && !options.text()) || !options.text) {
-        return;
-      }
-      $element.addClass("draggableText");
-
-      var $helper = $("<div>").text(ko.isObservable(options.text) ? options.text() : options.text).css("z-index", "99999");
-      var dragStartX = -1;
-      var dragStartY = -1;
-      var notifiedOnDragStarted = false;
-      $element.draggable({
-        helper: function () { return $helper },
-        appendTo: "body",
-        start: function (event) {
-          dragStartX = event.clientX;
-          dragStartY = event.clientY;
-          huePubSub.publish('draggable.text.meta', options.meta);
-          notifiedOnDragStarted = false;
-        },
-        drag: function (event) {
-          huePubSub.publish('draggable.text.drag', {
-            event: event,
-            meta: options.meta
-          });
-          if (!notifiedOnDragStarted && Math.sqrt((dragStartX-event.clientX)*(dragStartX-event.clientX) + (dragStartY-event.clientY)*(dragStartY-event.clientY)) >= 10) {
-            huePubSub.publish('draggable.text.started', options.meta);
-            notifiedOnDragStarted = true;
-          }
-        },
-        stop: function (event) {
-          if (Math.sqrt((dragStartX-event.clientX)*(dragStartX-event.clientX) + (dragStartY-event.clientY)*(dragStartY-event.clientY)) < 10) {
-            $helper.remove();
-            var elementAtStart = document.elementFromPoint(dragStartX, dragStartY);
-            var elementAtStop = document.elementFromPoint(event.clientX, event.clientY);
-            if (elementAtStart === elementAtStop) {
-              $(elementAtStop).trigger('click');
-            }
-          }
-          notifiedOnDragStarted = false;
-          huePubSub.publish('draggable.text.stopped');
-        }
-      });
-    }
-  };
-
-  /**
-   * Binding for adding a spinner to the page
-   *
-   * Example:
-   *
-   * <!-- ko hueSpinner: { spin: loading, center: true, size: 'large' } --><!-- /ko -->
-   *
-   */
-  ko.bindingHandlers.hueSpinner = {
-    update: function (element, valueAccessor) {
-      var value = ko.unwrap(valueAccessor());
-
-      var options = {
-        size: 'default',
-        center: false,
-        overlay: false,
-        inline: false,
-        blackout: false
-      };
-
-      var spin = false;
-      if (ko.isObservable(valueAccessor())) {
-        spin = value();
-      } else {
-        $.extend(options, value);
-        spin = typeof value.spin === 'function' ? value.spin() : value.spin;
-      }
-
-      ko.virtualElements.emptyNode(element);
-
-      if (spin) {
-        var $container = $('<div>');
-        $container.addClass(options.overlay ? 'hue-spinner-overlay' : ( options.inline ? 'hue-spinner-inline' : 'hue-spinner'));
-        if (options.blackout) {
-          $container.addClass('hue-spinner-blackout');
-        }
-        if (!options.overlay) {
-          var $spinner = $('<i>');
-          $spinner.addClass('fa fa-spinner fa-spin');
-          if (options.size === 'large') {
-            $spinner.addClass('hue-spinner-large');
-          }
-          if (options.size === 'xlarge') {
-            $spinner.addClass('hue-spinner-xlarge');
-          }
-          if (options.center) {
-            $spinner.addClass('hue-spinner-center');
-            if (options.inline) {
-              $container.css('width', '100%');
-            }
-          }
-        }
-        $container.append($spinner);
-        ko.virtualElements.prepend(element, $container[0]);
-      }
-    }
-  };
-  ko.virtualElements.allowedBindings.hueSpinner = true;
-
-  ko.bindingHandlers.visibleOnHover = {
-    init: function (element, valueAccessor, allBindings, viewModel, bindingContext) {
-      var options = valueAccessor();
-      var $element  = $(element);
-
-      var selector = options.selector;
-      var showTimeout = -1;
-      var hideTimeout = -1;
-      ko.utils.domData.set(element, 'visibleOnHover.override', ko.utils.unwrapObservable(options.override) || false);
-      var inside = false;
-
-      var show = function () {
-        if (options.childrenOnly) {
-          $element.children(selector).fadeTo("fast", 1);
-        } else {
-          $element.find(selector).fadeTo("fast", 1);
-        }
-        window.clearTimeout(hideTimeout);
-      };
-
-      var hide = function () {
-        if (! inside) {
-          window.clearTimeout(showTimeout);
-          hideTimeout = window.setTimeout(function () {
-            if (options.childrenOnly) {
-              $element.children(selector).fadeTo("fast", 0);
-            } else {
-              $element.find(selector).fadeTo("fast", 0);
-            }
-          }, 10);
-        }
-      };
-
-      ko.utils.domData.set(element, 'visibleOnHover.show', show);
-      ko.utils.domData.set(element, 'visibleOnHover.hide', hide);
-
-      if (ko.utils.domData.get(element, 'visibleOnHover.override')) {
-        window.setTimeout(show, 1);
-      }
-
-      $element.mouseenter(function () {
-        showTimeout = window.setTimeout(function () {
-          inside = true;
-          show();
-        }, 300);
-      });
-
-      $element.mouseleave(function () {
-        window.clearTimeout(showTimeout);
-        inside = false;
-        if (! ko.utils.domData.get(element, 'visibleOnHover.override')) {
-          hide();
-        }
-      });
-    },
-    update: function (element, valueAccessor, allBindings, viewModel, bindingContext) {
-      if (ko.utils.unwrapObservable(valueAccessor().override)) {
-        ko.utils.domData.set(element, 'visibleOnHover.override', true)
-        ko.utils.domData.get(element, 'visibleOnHover.show')()
-      } else {
-        ko.utils.domData.set(element, 'visibleOnHover.override', false)
-        ko.utils.domData.get(element, 'visibleOnHover.hide')();
-      }
-    }
-  };
-
-  /**
-   * Binding for jquery UI resizable
-   *
-   * @type {{init: ko.bindingHandlers.resizable.init}}
-   */
-  ko.bindingHandlers.resizable = {
-    init: function (element, valueAccessor, allBindings, viewModel, bindingContext) {
-      var options = valueAccessor() || {};
-      $(element).resizable(options);
-      $(element).children('.ui-resizable-handle').css('z-index', 10000);
-    }
-  };
-
-  /**
-   * This binding can be used to toggle a boolean value on click
-   *
-   * Example:
-   *
-   * <div databind="toggle: value">...</div>
-   *
-   * @type {{init: ko.bindingHandlers.toggle.init}}
-   */
-  ko.bindingHandlers.toggle = {
-    init: function (element, valueAccessor, allBindings, viewModel, bindingContext) {
-      var value = valueAccessor();
-      ko.bindingHandlers.click.init(element, function () {
-        return function () {
-          value(! value());
-        }
-      }, allBindings, viewModel, bindingContext);
-    }
-  };
-
-  ko.bindingHandlers.slideVisible = {
-    init: function (element, valueAccessor) {
-      var value = valueAccessor();
-      $(element).toggle(ko.unwrap(value));
-    },
-    update: function (element, valueAccessor, allBindings) {
-      var value = valueAccessor();
-      var onComplete = ko.unwrap(allBindings()).onComplete;
-      ko.unwrap(value) ? $(element).slideDown(100, onComplete ? onComplete() : function(){}) : $(element).slideUp(100, onComplete ? onComplete() : function(){});
-    }
-  };
-
-  ko.bindingHandlers.fadeVisible = {
-    init: function (element, valueAccessor) {
-      var value = valueAccessor();
-      var toggleValue = typeof value.value === "undefined" ? value : value.value;
-      $(element).toggle(ko.unwrap(toggleValue));
-    },
-    update: function (element, valueAccessor) {
-      var value = valueAccessor();
-      var toggleValue = typeof value.value === "undefined" ? value : value.value;
-      var speed = typeof value.speed === "undefined" ? 'normal' : value.speed;
-      var fadeOut = typeof value.fadeOut === "undefined" ? false : value.fadeOut;
-      $(element).stop();
-      if (ko.unwrap(toggleValue)) {
-        $(element).fadeIn(speed);
-      } else if (fadeOut) {
-        $(element).fadeOut(speed);
-      } else {
-        $(element).hide();
-      }
-    }
-  };
-
-  /**
-   * This binding can be used to show a custom context menu on right-click,
-   * It assumes that the context menu is nested within the bound element and
-   * the selector for the menu has to be supplied as a parameter.
-   *
-   * Example:
-   *
-   * <div data-bind="contextMenu: {
-   *   menuSelector: '.hue-context-menu',
-   *   beforeOpen: function () { ... }
-   * }">
-   *   <ul class="hue-context-menu">...</ul>
-   * </div>
-   *
-   */
-  ko.bindingHandlers.contextMenu = {
-    initContextMenu: function ($menu, $scrollContainer) {
-      var active = false;
-
-      var currentLeft = 0;
-      var currentTop = 0;
-      var openScrollTop = 0;
-      var openScrollLeft = 0;
-
-      var adjustForScroll = function () {
-        $menu.css('top', currentTop - $scrollContainer.scrollTop() + openScrollTop);
-        $menu.css('left', currentLeft - $scrollContainer.scrollLeft() + openScrollLeft);
-      }
-
-      return {
-        show: function (event) {
-          $menu.css('top', 0);
-          $menu.css('left', 0);
-          $menu.css('opacity', 0);
-          $menu.show();
-          openScrollTop = $scrollContainer.scrollTop();
-          openScrollLeft = $scrollContainer.scrollLeft();
-          var menuWidth = $menu.outerWidth(true)
-          if (event.clientX + menuWidth > $(window).width()) {
-            currentLeft = $(window).width() - menuWidth
-          } else {
-            currentLeft = event.clientX;
-          }
-          $menu.css('left', currentLeft);
-
-          var menuHeight = $menu.outerHeight(true);
-          if (event.clientY + menuHeight > $(window).height()) {
-            currentTop = $(window).height() - menuHeight;
-          } else {
-            currentTop = event.clientY;
-          }
-          $menu.css('top', currentTop);
-          $menu.css('opacity', 1);
-          active = true;
-          $scrollContainer.on('scroll', adjustForScroll);
-        },
-        hide: function () {
-          if (active) {
-            $scrollContainer.off('scroll', adjustForScroll);
-            $menu.css('opacity', 0);
-            window.setTimeout(function () {
-              $menu.hide();
-            }, 300);
-            active = false;
-          }
-        }
-      }
-    },
-    init: function (element, valueAccessor, allBindings, viewModel, bindingContext) {
-      var $element = $(element);
-      var options = valueAccessor();
-      var $menu = $element.find(options.menuSelector);
-
-      bindingContext.$altDown = ko.observable(false);
-
-      window.addEventListener("keydown", function (e) {
-        bindingContext.$altDown(e.altKey);
-      });
-
-      window.addEventListener("keyup", function (e) {
-        bindingContext.$altDown(false);
-      });
-
-      var $scrollContainer = $(options.scrollContainer).length > 0 ? $(options.scrollContainer) : $(window);
-
-      var menu = ko.bindingHandlers.contextMenu.initContextMenu($menu, $scrollContainer);
-
-      element.addEventListener("contextmenu", function(event) {
-        if(document.selection && document.selection.empty) {
-          document.selection.empty();
-        } else if(window.getSelection) {
-          var sel = window.getSelection();
-          sel.removeAllRanges();
-        }
-        if (typeof options.beforeOpen === 'function') {
-          options.beforeOpen.bind(viewModel)();
-        }
-        menu.show(event);
-        huePubSub.publish('contextmenu-active', element);
-        event.preventDefault();
-        event.stopPropagation();
-      });
-
-      huePubSub.subscribe('contextmenu-active', function (origin) {
-        if (origin !== element) {
-          menu.hide();
-        }
-      });
-      document.addEventListener("contextmenu", function (event) {
-        menu.hide();
-      });
-      $menu.click(function (e) {
-        menu.hide();
-        e.stopPropagation();
-      });
-      $(document).click(function (event) {
-        if ($element.find($(event.target)).length === 0) {
-          menu.hide();
-        }
-      });
-    }
-  };
-
-
-  ko.bindingHandlers.contextSubMenu = {
-    init: function (element, valueAccessor, allBindings, viewModel, bindingContext) {
-      var menuSelector = valueAccessor();
-      var $element = $(element);
-
-      var $menu = $element.find(menuSelector);
-      var $parentMenu = $element.parent('.hue-context-menu');
-      var open = false;
-
-      var closeSubMenu = function () {
-        open = false;
-        $menu.hide();
-        $element.removeClass('active');
-      };
-
-      var hideTimeout = -1;
-      $element.add($menu).on('mouseenter', function () {
-        $element.addClass('active');
-        if (!open) {
-          huePubSub.publish('hue.sub.menu.close');
-        }
-        open = true;
-        window.clearTimeout(hideTimeout);
-        var menuHeight = $menu.outerHeight();
-        $menu.css('top', ($element.position().top + $parentMenu.position().top + menuHeight > $(window).height()) ? $(window).height() - menuHeight - 8 : $element.position().top + $parentMenu.position().top);
-        $menu.css('left', $element.offset().left + $element.outerWidth(true));
-        $menu.css('opacity', 0);
-        $menu.show();
-        $menu.css('opacity', 1);
-        huePubSub.subscribeOnce('hue.sub.menu.close', closeSubMenu);
-      });
-
-      $element.add($menu).on('mouseleave', function () {
-        window.clearTimeout(hideTimeout);
-        hideTimeout = window.setTimeout(closeSubMenu, 300);
-      });
-    }
-  };
-
-  ko.bindingHandlers.appAwareTemplateContextMenu = {
-    init: function (element, valueAccessor, allBindings, viewModel, bindingContext) {
-      viewModel.$currentApp = ko.observable('');
-      huePubSub.subscribe('set.current.app.name', viewModel.$currentApp);
-      huePubSub.publish('get.current.app.name');
-      ko.bindingHandlers.templateContextMenu.init(element, valueAccessor, allBindings, viewModel, bindingContext);
-    }
-  };
-
-  ko.bindingHandlers.templateContextMenu = {
-    init: function (element, valueAccessor, allBindings, viewModel, bindingContext) {
-      var options = valueAccessor();
-
-      element.addEventListener("contextmenu", function(event) {
-        if(document.selection && document.selection.empty) {
-          document.selection.empty();
-        } else if(window.getSelection) {
-          var sel = window.getSelection();
-          sel.removeAllRanges();
-        }
-
-        if (typeof options.beforeOpen === 'function') {
-          options.beforeOpen.bind(viewModel)();
-        }
-        var $menu = $('#hueContextMenu_' + options.template);
-        if ($menu.length === 0) {
-          $menu = $('<ul id="hueContextMenu_' + options.template  + '" class="hue-context-menu" data-bind="template: { name: \'' + options.template + '\', data: viewModel, afterRender: afterRender }"></ul>').appendTo(HUE_CONTAINER);
-        } else {
-          ko.cleanNode($menu[0]);
-        }
-        $menu.data('active', true);
-
-        $menu.css('top', 0);
-        $menu.css('left', 0);
-        $menu.css('opacity', 0);
-        $menu.show();
-
-        var hideMenu = function () {
-          if (!$menu.data('active')) {
-            $menu.hide();
-            ko.cleanNode($menu[0]);
-          }
-        };
-
-        ko.applyBindings({
-          afterRender: function () {
-            var menuWidth = $menu.outerWidth(true);
-            var menuHeight = $menu.outerHeight(true);
-            $menu.css('left', (event.clientX + menuWidth > $(window).width()) ? $(window).width() - menuWidth : event.clientX);
-            $menu.css('top', (event.clientY + menuHeight > $(window).height()) ? $(window).height() - menuHeight : event.clientY);
-            $menu.css('opacity', 1);
-            if (options.scrollContainer) {
-              $(options.scrollContainer).one('scroll', hideMenu);
-            }
-            window.setTimeout(function () {
-              $menu.data('active', false);
-              $(document).one('click', hideMenu);
-            }, 100);
-          },
-          viewModel: options.viewModel || viewModel
-        }, $menu[0]);
-
-        ko.contextFor($menu[0]).$contextSourceElement = element;
-        event.preventDefault();
-        event.stopPropagation();
-      });
-    }
-  };
-
-  ko.bindingHandlers.multiClick = {
-    init: function (element, valueAccessor, allBindings, viewModel, bindingContext) {
-      var clickHandlerFunction = valueAccessor().click;
-      var dblClickHandlerFunction = valueAccessor().dblClick;
-      if (!dblClickHandlerFunction && !clickHandlerFunction) {
-        return;
-      }
-
-      var clickedOnce = false;
-      var singleClickTimeout = -1;
-      var dblClickTimeout = -1;
-
-      var newValueAccessor = function() {
-        return function() {
-          var clickArgs = arguments;
-          if (!dblClickHandlerFunction && clickHandlerFunction) {
-            clickHandlerFunction.apply(viewModel, clickArgs);
-            return;
-          }
-          if (clickedOnce) {
-            dblClickHandlerFunction.apply(viewModel, clickArgs);
-            clickedOnce = false;
-            clearTimeout(singleClickTimeout);
-            clearTimeout(dblClickTimeout);
-          } else if (clickHandlerFunction) {
-            clickedOnce = true;
-            singleClickTimeout = window.setTimeout(function() {
-              clickHandlerFunction.apply(viewModel, clickArgs);
-              dblClickTimeout = window.setTimeout(function() {
-                clickedOnce = false;
-              }, 100);
-            }, 225);
-          }
-        }
-      };
-
-      ko.bindingHandlers.click.init(element, newValueAccessor, allBindings, viewModel, bindingContext);
-    }
-  };
-
-  ko.bindingHandlers.logScroller = {
-    init: function (element, valueAccessor, allBindings) {
-      var $element = $(element);
-
-      $element.on("scroll", function () {
-        $element.data('lastScrollTop', $element.scrollTop());
-      });
-
-      $element.on("wheel", function () {
-        $element.data('hasUserScrolled', true);
-      });
-
-      function autoLogScroll () {
-        var elementHeight = $element.innerHeight();
-        var lastHeight = $element.data('lastHeight') || elementHeight;
-        var lastScrollTop = $element.data('lastScrollTop') || 0;
-        var hasUserScrolled = $element.data('hasUserScrolled') || false;
-        var lastScrollHeight = $element.data('lastScrollHeight') || elementHeight;
-
-        var stickToBottom = !hasUserScrolled || elementHeight !== lastHeight || (lastScrollTop + elementHeight) === lastScrollHeight;
-
-        if (stickToBottom) {
-          $element.scrollTop(element.scrollHeight - $element.height());
-          $element.data('lastScrollTop', $element.scrollTop());
-        }
-
-        $element.data('lastScrollHeight', element.scrollHeight);
-        $element.data('lastHeight', elementHeight);
-      }
-
-      var logValue = valueAccessor();
-      logValue.subscribe(function () {
-        window.setTimeout(autoLogScroll, 200);
-      });
-
-      if (typeof allBindings().logScrollerVisibilityEvent !== 'undefined'){
-        allBindings().logScrollerVisibilityEvent.subscribe(function () {
-          window.setTimeout(autoLogScroll, 0);
-        });
-      } else {
-        hueUtils.waitForRendered(element, function(el) { return el.is(':visible') }, autoLogScroll, 300);
-        ko.utils.domNodeDisposal.addDisposeCallback(element, function() {
-          window.clearTimeout($element.data('waitForRenderTimeout'));
-        });
-      }
-    }
-  };
-
-  ko.bindingHandlers.multiCheckForeachVisible = {
-    init: function (element, valueAccessor, allBindings, clickedEntry, bindingContext) {
-      var $element = $(element);
-      var parentContext = bindingContext.$parentContext;
-
-      var selectedAttr = valueAccessor().selectedAttr;
-      var entries = valueAccessor().entries;
-
-      $element.attr('unselectable', 'on').css('user-select', 'none').on('selectstart', false);
-
-      $element.on('click', function (e) {
-        if (e.shiftKey && parentContext.$multiCheckLastEntry) {
-          var lastEntry = parentContext.$multiCheckLastEntry;
-          var inside = false;
-          entries().every(function (otherEntry) {
-            if (otherEntry === lastEntry || otherEntry === clickedEntry) {
-              if (inside) {
-                return false;
-              }
-              inside = true;
-              return true;
-            }
-            if (inside && otherEntry[selectedAttr]() !== lastEntry[selectedAttr]()) {
-              otherEntry[selectedAttr](lastEntry[selectedAttr]());
-            }
-            return true;
-          });
-          if (clickedEntry[selectedAttr]() !== lastEntry[selectedAttr]()) {
-            clickedEntry[selectedAttr](lastEntry[selectedAttr]());
-          }
-        } else {
-          clickedEntry[selectedAttr](!clickedEntry[selectedAttr]());
-        }
-
-        parentContext.$multiCheckLastEntry = clickedEntry;
-        parentContext.$multiCheckLastChecked = clickedEntry[selectedAttr]();
-      });
-
-      ko.utils.domNodeDisposal.addDisposeCallback(element, function () {
-        $element.off('click');
-      });
-    },
-    update: function () {}
-  };
-
-  ko.bindingHandlers.multiCheck = {
-    init: function (element, valueAccessor) {
-      $(element).attr('unselectable', 'on').css('user-select', 'none').on('selectstart', false);
-
-      var $container = $(ko.unwrap(valueAccessor()));
-      $(element).click(function (e, shouldIgnore) {
-        var $self = $(e.target);
-        if ($self.data('noMultiCheck')) {
-          $self.data('noMultiCheck', false);
-          return;
-        }
-        var shouldCheck = $self.is(':checked') || ! $self.hasClass('fa-check');
-        if (e.shiftKey && shouldCheck === $container.data('last-clicked-checkbox-state')) {
-          var insideGroup = false;
-          var allCheckboxes = $container.find(":checkbox");
-          if (allCheckboxes.length == 0) {
-            allCheckboxes = $container.find(".hue-checkbox");
-          }
-          for (var i = 0; i < allCheckboxes.length; i++) {
-            var checkbox = allCheckboxes[i];
-            if (checkbox === e.target || checkbox === $container.data('last-clicked-checkbox')) {
-              if (insideGroup) {
-                break;
-              }
-              insideGroup = true;
-              continue;
-            }
-            if (insideGroup) {
-              var $checkbox = $(checkbox);
-              $checkbox.data('noMultiCheck', true);
-              if (($checkbox.is(':checked') || $checkbox.hasClass('fa-check')) !== shouldCheck) {
-                $checkbox.trigger("click");
-              }
-            }
-          }
-        }
-        $container.data('last-clicked-checkbox', e.target);
-        $container.data('last-clicked-checkbox-state', shouldCheck);
-      });
-    },
-    update: function() {}
-  };
-
-  ko.bindingHandlers.numericTextInput = {
-    init: function (element, valueAccessor, allBindings) {
-      var bindingOptions = ko.unwrap(valueAccessor());
-      var numericValue = ko.observable(bindingOptions.value()).extend({ numeric: { precision: bindingOptions.precision, allowEmpty: typeof bindingOptions.allowEmpty !== 'undefined' && bindingOptions.allowEmpty } });
-      numericValue.subscribe(function(newValue) { bindingOptions.value(newValue) });
-      ko.bindingHandlers.textInput.init(element, function() { return numericValue }, allBindings);
-    }
-  };
-
-  ko.bindingHandlers.templatePopover = {
-    init: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
-      var options = ko.unwrap(valueAccessor());
-
-      var clickTrigger = options.trigger === 'click';
-      var $container = $('#popover-container');
-      if (! $container.length) {
-        $container = $('<div>').attr('id', 'popover-container').appendTo(HUE_CONTAINER);
-        $('<div>').addClass('temp-content').hide().appendTo($container);
-        $('<div>').addClass('temp-title').hide().appendTo($container);
-      }
-
-      var $content = $container.find('.temp-content');
-      var $title = $container.find('.temp-title');
-
-      $.extend(options, { html: true, trigger: 'manual', container: '#popover-container' });
-
-      var $element = $(element);
-
-      var visible = options.visible || ko.observable(false);
-
-      var trackElementInterval = -1;
-
-      var hidePopover = function () {
-        if (visible()) {
-          window.clearInterval(trackElementInterval);
-          $element.popover('hide');
-          visible(false);
-          $(document).off('click', hideOnClickOutside);
-        }
-      };
-
-      var closeSub = huePubSub.subscribe('close.popover', hidePopover);
-
-      var hideOnClickOutside = function (event) {
-        if (visible() && $element.data('popover') && ! $.contains($element.data('popover').$tip[0], event.target)) {
-          hidePopover();
-        }
-      };
-
-      ko.utils.domNodeDisposal.addDisposeCallback(element, function() {
-        if (visible && $element.data('popover')) {
-          hidePopover();
-        }
-        closeSub.remove();
-      });
-
-      var afterRender = function () {
-        options.content = $content.html();
-        options.title = $title.html();
-        var triggerTitle;
-        if ($element.attr('title')) {
-          triggerTitle = $element.attr('title');
-          $element.attr('title', null);
-        }
-        $element.popover(options);
-        $element.popover('show');
-        if (triggerTitle) {
-          $element.attr('title', triggerTitle);
-        }
-        var $tip = $element.data('popover').$tip;
-        if (HUE_CONTAINER !== 'body') {
-          $tip.css({ 'position': 'fixed', 'z-index': 2000 });
-          $tip.appendTo(HUE_CONTAINER);
-
-          $tip.offset({
-            left: $element.offset().left + $element.outerWidth(true) + 10,
-            top: $element.offset().top + ($element.outerHeight(true) / 2) - ($tip.outerHeight(true) / 2)
-          });
-        }
-        ko.cleanNode($tip.get(0));
-        ko.applyBindings(viewModel, $tip.get(0));
-        $tip.find(".close-popover, .close-template-popover").click(function (event) {
-          hidePopover();
-          event.stopPropagation();
-        });
-        if (options.minWidth) {
-          var heightBefore = $tip.outerHeight(true);
-          var widthBefore = $tip.outerWidth(true);
-          $tip.css('min-width', options.minWidth);
-          // The min-width might affect the height/width in which case we reposition the popover depending on placement
-          var heightDiff = (heightBefore - $tip.outerHeight(true)) / 2;
-          var widthDiff = (widthBefore - $tip.outerWidth(true)) / 2;
-          if ((!options.placement || options.placement === 'left' || options.placement === 'right') && heightDiff !== 0) {
-            $tip.css('top', ($tip.position().top + heightDiff) + 'px');
-          } else if (options.placement && (options.placement === 'bottom' || options.placement === 'top') && widthDiff !== 0) {
-            $tip.css('left', ($tip.position().left + widthDiff) + 'px');
-          }
-        }
-        var lastWidth = $element.outerWidth(true);
-        var lastOffset = $element.offset();
-        var lastHeight = $element.outerHeight(true);
-        trackElementInterval = window.setInterval(function () {
-          var elementWidth = $element.outerWidth(true);
-          var elementHeight = $element.outerHeight(true);
-          var elementOffset = $element.offset();
-          if (lastHeight !== elementHeight || lastWidth !== $element.outerWidth(true) || lastOffset.top !== elementOffset.top || lastOffset.left !== elementOffset.left) {
-            $tip.css({ 'left': elementOffset.left + (elementWidth / 2) - ($tip.outerWidth(true) / 2) , 'top': elementOffset.top + elementHeight + 10 });
-            lastWidth = elementWidth;
-            lastOffset = elementOffset;
-            lastHeight = elementHeight;
-          }
-        }, 50);
-        $content.empty();
-        $title.empty();
-        $(document).on('click', hideOnClickOutside);
-        visible(true);
-      };
-
-      var showPopover = function (preventClose) {
-        if (!preventClose) {
-          huePubSub.publish('close.popover');
-        }
-        ko.renderTemplate(options.contentTemplate, viewModel, {
-          afterRender: function () {
-            if (options.titleTemplate) {
-              ko.renderTemplate(options.titleTemplate, viewModel, {
-                afterRender: function () {
-                  afterRender();
-                }
-              }, $title.get(0), 'replaceChildren');
-            } else {
-              afterRender();
-            }
-          }
-        }, $content.get(0), 'replaceChildren');
-      };
-
-      if (visible()) {
-        window.setTimeout(function () {
-          showPopover(true);
-        }, 0);
-      }
-
-      if (clickTrigger) {
-        $element.click(function (e) {
-          if (visible()) {
-            hidePopover();
-          } else {
-            showPopover();
-          }
-          e.stopPropagation();
-        });
-      } else {
-        $element.mouseenter(showPopover);
-        $element.mouseleave(hidePopover);
-      }
-    }
-  };
-
-  ko.bindingHandlers.freshereditor = {
-    init: function (element, valueAccessor, allBindingsAccessor, viewModel) {
-      var _el = $(element);
-      var options = $.extend(valueAccessor(), {});
-      _el.html(options.data());
-      _el.freshereditor({
-        excludes: ['strikethrough', 'removeFormat', 'insertorderedlist', 'justifyfull', 'insertheading1', 'insertheading2', 'superscript', 'subscript']
-      });
-      _el.freshereditor("edit", true);
-      _el.on("mouseup", function () {
-        storeSelection();
-        updateValues();
-      });
-
-      var sourceDelay = -1;
-      _el.on("keyup", function () {
-        clearTimeout(sourceDelay);
-        storeSelection();
-        sourceDelay = setTimeout(function () {
-          updateValues();
-        }, 100);
-      });
-
-      $(".chosen-select").chosen({
-        disable_search_threshold: 10,
-        width: "75%"
-      });
-
-      $(document).on("addFieldToVisual", function (e, field) {
-        _el.focus();
-        pasteHtmlAtCaret("{{" + field.name() + "}}");
-      });
-
-      $(document).on("addFunctionToVisual", function (e, fn) {
-        _el.focus();
-        pasteHtmlAtCaret(fn);
-      });
-
-      function updateValues() {
-        $("[data-template]")[0].editor.setValue(stripHtmlFromFunctions(_el.html()));
-        valueAccessor().data(_el.html());
-      }
-
-      function storeSelection() {
-        if (window.getSelection) {
-          // IE9 and non-IE
-          sel = window.getSelection();
-          if (sel.getRangeAt && sel.rangeCount) {
-            range = sel.getRangeAt(0);
-            _el.data("range", range);
-          }
-        }
-        else if (document.selection && document.selection.type != "Control") {
-          // IE < 9
-          _el.data("selection", document.selection);
-        }
-      }
-
-      function pasteHtmlAtCaret(html) {
-        var sel, range;
-        if (window.getSelection) {
-          // IE9 and non-IE
-          sel = window.getSelection();
-          if (sel.getRangeAt && sel.rangeCount) {
-            if (_el.data("range")) {
-              range = _el.data("range");
-            }
-            else {
-              range = sel.getRangeAt(0);
-            }
-            range.deleteContents();
-
-            // Range.createContextualFragment() would be useful here but is
-            // non-standard and not supported in all browsers (IE9, for one)
-            var el = document.createElement("div");
-            el.innerHTML = html;
-            var frag = document.createDocumentFragment(), node, lastNode;
-            while ((node = el.firstChild)) {
-              lastNode = frag.appendChild(node);
-            }
-            range.insertNode(frag);
-
-            // Preserve the selection
-            if (lastNode) {
-              range = range.cloneRange();
-              range.setStartAfter(lastNode);
-              range.collapse(true);
-              sel.removeAllRanges();
-              sel.addRange(range);
-            }
-          }
-        } else if (document.selection && document.selection.type != "Control") {
-          // IE < 9
-          if (_el.data("selection")) {
-            _el.data("selection").createRange().pasteHTML(html);
-          }
-          else {
-            document.selection.createRange().pasteHTML(html);
-          }
-        }
-      }
-    }
-  };
-
-  ko.bindingHandlers.slider = {
-    init: function (element, valueAccessor) {
-      var _el = $(element);
-      var _options = $.extend(valueAccessor(), {});
-      _el.slider({
-        min: !isNaN(parseFloat(_options.start())) ? parseFloat(_options.start()) : 0,
-        max: !isNaN(parseFloat(_options.end())) ? parseFloat(_options.end()) : 10,
-        step: !isNaN(parseFloat(_options.gap())) ? parseFloat(_options.gap()) : 1,
-        handle: _options.handle ? _options.handle : 'triangle',
-        start: parseFloat(_options.min()),
-        end: parseFloat(_options.max()),
-        tooltip_split: true,
-        tooltip: 'always',
-        labels: _options.labels
-      });
-      _el.on("slide", function (e) {
-        _options.start(e.min);
-        _options.end(e.max);
-        _options.min(e.start);
-        _options.max(e.end);
-        if (_options.min() < _options.start()){
-          _options.start(_options.min());
-        }
-        if (_options.max() > _options.end()){
-          _options.end(_options.max());
-        }
-        _options.gap(e.step);
-        if (typeof _options.properties.initial_start == "function"){
-          _options.properties.start(_options.properties.initial_start());
-          _options.properties.end(_options.properties.initial_end());
-          _options.properties.gap(_options.properties.initial_gap());
-        }
-      });
-      _el.on("slideStop", function (e) {
-        searchViewModel.search();
-      });
-    },
-    update: function (element, valueAccessor) {
-      var _options = $.extend(valueAccessor(), {});
-    }
-  }
-
-  ko.bindingHandlers.daterangepicker = {
-    INTERVAL_OPTIONS: [
-      {
-        value: "+200MILLISECONDS",
-        label: "200ms"
-      },
-      {
-        value: "+1SECONDS",
-        label: "1s"
-      },
-      {
-        value: "+5SECONDS",
-        label: "5s"
-      },
-      {
-        value: "+30SECONDS",
-        label: "30s"
-      },
-      {
-        value: "+1MINUTES",
-        label: "1m"
-      },
-      {
-        value: "+5MINUTES",
-        label: "5m"
-      },
-      {
-        value: "+10MINUTES",
-        label: "10m"
-      },
-      {
-        value: "+30MINUTES",
-        label: "30m"
-      },
-      {
-        value: "+1HOURS",
-        label: "1h"
-      },
-      {
-        value: "+3HOURS",
-        label: "3h"
-      },
-      {
-        value: "+6HOURS",
-        label: "6h"
-      },
-      {
-        value: "+12HOURS",
-        label: "12h"
-      },
-      {
-        value: "+1DAYS",
-        label: "1d"
-      },
-      {
-        value: "+7DAYS",
-        label: "7d"
-      },
-      {
-        value: "+1MONTHS",
-        label: "1M"
-      },
-      {
-        value: "+6MONTHS",
-        label: "6M"
-      },
-      {
-        value: "+1YEARS",
-        label: "1y"
-      },
-      {
-        value: "+10YEARS",
-        label: "10y"
-      }
-    ],
-    EXTRA_INTERVAL_OPTIONS: [],
-
-    init: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
-      var DATE_FORMAT = "YYYY-MM-DD";
-      var TIME_FORMAT = "HH:mm:ss";
-      var DATETIME_FORMAT = DATE_FORMAT + " " + TIME_FORMAT;
-
-      var _el = $(element);
-      var _options = $.extend(valueAccessor(), {});
-
-      var _intervalOptions = [];
-      ko.bindingHandlers.daterangepicker.INTERVAL_OPTIONS.forEach(function (interval) {
-        _intervalOptions.push('<option value="' + interval.value + '">' + interval.label + '</option>');
-      });
-
-      function enableOptions() {
-        var _opts = [];
-        var _tmp = $("<div>").html(_intervalOptions.join(""))
-        $.each(arguments, function (cnt, item) {
-          if (_tmp.find("option[value='+" + item + "']").length > 0) {
-            _opts.push('<option value="+' + item + '">' + _tmp.find("option[value='+" + item + "']").eq(0).text() + '</option>');
-          }
-        });
-        return _opts;
-      }
-
-      function renderOptions(opts) {
-        var _html = "";
-        for (var i = 0; i < opts.length; i++) {
-          _html += opts[i];
-        }
-        return _html;
-      }
-
-      var _tmpl = $('<div class="simpledaterangepicker">' +
-              '<div class="facet-field-cnt custom">' +
-              '<div class="facet-field-label facet-field-label-fixed-width"></div>' +
-              '<div class="facet-field-switch"><i class="fa fa-calendar muted"></i> <a href="javascript:void(0)">' + KO_DATERANGEPICKER_LABELS.DATE_PICKERS + '</a></div>' +
-              '</div>' +
-              '<div class="facet-field-cnt picker">' +
-              '<div class="facet-field-label facet-field-label-fixed-width"></div>' +
-              '<div class="facet-field-switch"><i class="fa fa-calendar-o muted"></i> <a href="javascript:void(0)">' + KO_DATERANGEPICKER_LABELS.CUSTOM_FORMAT + '</a></div>' +
-              '</div>' +
-              '<div class="facet-field-cnt picker">' +
-              '<div class="facet-field-label facet-field-label-fixed-width">' + KO_DATERANGEPICKER_LABELS.START + '</div>' +
-              '<div class="input-prepend input-group">' +
-              '<span class="add-on input-group-addon"><i class="fa fa-calendar"></i></span>' +
-              '<input type="text" class="input-small form-control start-date" />' +
-              '</div>' +
-              '<div class="input-prepend input-group left-margin">' +
-              '<span class="add-on input-group-addon"><i class="fa fa-clock-o"></i></span>' +
-              '<input type="text" class="input-mini form-control start-time" />' +
-              '</div>' +
-              '</div>' +
-              '<div class="facet-field-cnt picker">' +
-              '<div class="facet-field-label facet-field-label-fixed-width">' + KO_DATERANGEPICKER_LABELS.END + '</div>' +
-              '<div class="input-prepend input-group">' +
-              '<span class="add-on input-group-addon"><i class="fa fa-calendar"></i></span>' +
-              '<input type="text" class="input-small form-control end-date" />' +
-              '</div>' +
-              '<div class="input-prepend input-group left-margin">' +
-              '<span class="add-on input-group-addon"><i class="fa fa-clock-o"></i></span>' +
-              '<input type="text" class="input-mini form-control end-time" />' +
-              '</div>' +
-              '</div>' +
-              '<div class="facet-field-cnt picker">' +
-              '<div class="facet-field-label facet-field-label-fixed-width">' + KO_DATERANGEPICKER_LABELS.INTERVAL + '</div>' +
-              '<div class="input-prepend input-group"><span class="add-on input-group-addon"><i class="fa fa-repeat"></i></span></div>&nbsp;' +
-              '<select class="input-small interval-select" style="margin-right: 6px">' +
-              renderOptions(_intervalOptions) +
-              '</select>' +
-              '<input class="input interval hide" type="hidden" value="" />' +
-              '</div>' +
-              '<div class="facet-field-cnt custom">' +
-              '<div class="facet-field-label facet-field-label-fixed-width">' + KO_DATERANGEPICKER_LABELS.START + '</div>' +
-              '<div class="input-prepend input-group">' +
-              '<span class="add-on input-group-addon"><i class="fa fa-calendar-o"></i></span>' +
-              '<input type="text" class="input-large form-control start-date-custom" />' +
-              '</div>' +
-              '<span class="pointer custom-popover" data-trigger="click" data-toggle="popover" data-placement="right" rel="popover" data-html="true"' +
-              '       title="' + KO_DATERANGEPICKER_LABELS.CUSTOM_POPOVER_TITLE + '"' +
-              '       data-content="' + KO_DATERANGEPICKER_LABELS.CUSTOM_POPOVER_CONTENT + '">' +
-              '&nbsp;&nbsp;<i class="fa fa-question-circle"></i>' +
-              ' </span>' +
-              '</div>' +
-              '<div class="facet-field-cnt custom">' +
-              '<div class="facet-field-label facet-field-label-fixed-width">' + KO_DATERANGEPICKER_LABELS.END + '</div>' +
-              '<div class="input-prepend input-group">' +
-              '<span class="add-on input-group-addon"><i class="fa fa-calendar-o"></i></span>' +
-              '<input type="text" class="input-large form-control end-date-custom" />' +
-              '</div>' +
-              '</div>' +
-              '<div class="facet-field-cnt custom">' +
-              '<div class="facet-field-label facet-field-label-fixed-width">' + KO_DATERANGEPICKER_LABELS.INTERVAL + '</div>' +
-              '<div class="input-prepend input-group">' +
-              '<span class="add-on input-group-addon"><i class="fa fa-repeat"></i></span>' +
-              '<input type="text" class="input-large form-control interval-custom" />' +
-              '</div>' +
-              '</div>' +
-
-
-              '</div>'
-      );
-
-      _tmpl.insertAfter(_el);
-
-      $(".custom-popover").popover();
-
-      var _minMoment = moment(_options.min());
-      var _maxMoment = moment(_options.max());
-
-      if (_minMoment.isValid() && _maxMoment.isValid()) {
-        _tmpl.find(".facet-field-cnt.custom").hide();
-        _tmpl.find(".facet-field-cnt.picker").show();
-        _tmpl.find(".start-date").val(_minMoment.utc().format(DATE_FORMAT));
-        _tmpl.find(".start-time").val(_minMoment.utc().format(TIME_FORMAT));
-        _tmpl.find(".end-date").val(_maxMoment.utc().format(DATE_FORMAT));
-        _tmpl.find(".end-time").val(_maxMoment.utc().format(TIME_FORMAT));
-        _tmpl.find(".interval").val(_options.gap());
-        _tmpl.find(".interval-select").val(_options.gap());
-        _tmpl.find(".interval-custom").val(_options.gap());
-        if (_tmpl.find(".interval-select").val() == null || ko.bindingHandlers.daterangepicker.EXTRA_INTERVAL_OPTIONS.indexOf(_tmpl.find(".interval-select").val()) > -1) {
-          pushIntervalValue(_options.gap());
-          _tmpl.find(".facet-field-cnt.custom").show();
-          _tmpl.find(".facet-field-cnt.picker").hide();
-        }
-      }
-      else {
-        _tmpl.find(".facet-field-cnt.custom").show();
-        _tmpl.find(".facet-field-cnt.picker").hide();
-        _tmpl.find(".start-date-custom").val(_options.min());
-        _tmpl.find(".end-date-custom").val(_options.max());
-        _tmpl.find(".interval-custom").val(_options.gap());
-        pushIntervalValue(_options.gap());
-      }
-
-      if (typeof _options.relatedgap != "undefined"){
-        pushIntervalValue(_options.relatedgap());
-      }
-
-      _tmpl.find(".start-date").datepicker({
-        format: DATE_FORMAT.toLowerCase()
-      }).on("changeDate", function () {
-        rangeHandler(true);
-      });
-
-      _tmpl.find(".start-date").on("change", function () {
-        rangeHandler(true);
-      });
-
-      _tmpl.find(".start-time").timepicker({
-        minuteStep: 1,
-        showSeconds: true,
-        showMeridian: false,
-        defaultTime: false
-      });
-
-      _tmpl.find(".end-date").datepicker({
-        format: DATE_FORMAT.toLowerCase()
-      }).on("changeDate", function () {
-        rangeHandler(false);
-      });
-
-      _tmpl.find(".end-date").on("change", function () {
-        rangeHandler(true);
-      });
-
-      _tmpl.find(".end-time").timepicker({
-        minuteStep: 1,
-        showSeconds: true,
-        showMeridian: false,
-        defaultTime: false
-      });
-
-      _tmpl.find(".start-time").on("change", function () {
-        // the timepicker plugin doesn't have a change event handler
-        // so we need to wait a bit to handle in with the default field event
-        window.setTimeout(function () {
-          rangeHandler(true)
-        }, 200);
-      });
-
-      _tmpl.find(".end-time").on("change", function () {
-        window.setTimeout(function () {
-          rangeHandler(false)
-        }, 200);
-      });
-
-      if (_minMoment.isValid() && _maxMoment.isValid()) {
-        rangeHandler(true);
-      }
-
-      _tmpl.find(".facet-field-cnt.picker .facet-field-switch a").on("click", function () {
-        _tmpl.find(".facet-field-cnt.custom").show();
-        _tmpl.find(".facet-field-cnt.picker").hide();
-      });
-
-      _tmpl.find(".facet-field-cnt.custom .facet-field-switch a").on("click", function () {
-        _tmpl.find(".facet-field-cnt.custom").hide();
-        _tmpl.find(".facet-field-cnt.picker").show();
-      });
-
-      _tmpl.find(".start-date-custom").on("change", function () {
-        _options.min(_tmpl.find(".start-date-custom").val());
-        _tmpl.find(".start-date").val(moment(_options.min()).utc().format(DATE_FORMAT));
-        _tmpl.find(".start-time").val(moment(_options.min()).utc().format(TIME_FORMAT));
-        _options.start(_options.min());
-      });
-
-      _tmpl.find(".end-date-custom").on("change", function () {
-        _options.max(_tmpl.find(".end-date-custom").val());
-        _tmpl.find(".end-date").val(moment(_options.max()).utc().format(DATE_FORMAT));
-        _tmpl.find(".end-time").val(moment(_options.max()).utc().format(TIME_FORMAT));
-        _options.end(_options.max());
-      });
-
-      _tmpl.find(".interval-custom").on("change", function () {
-        _options.gap(_tmpl.find(".interval-custom").val());
-        matchIntervals(true);
-        if (typeof _options.relatedgap != "undefined"){
-          _options.relatedgap(_options.gap());
-        }
-      });
-
-      function pushIntervalValue(newValue) {
-        var _found = false;
-        ko.bindingHandlers.daterangepicker.INTERVAL_OPTIONS.forEach(function(interval) {
-          if (interval.value == newValue){
-            _found = true;
-          }
-        });
-        if (!_found){
-          ko.bindingHandlers.daterangepicker.INTERVAL_OPTIONS.push({
-            value: newValue,
-            label: newValue
-          });
-          ko.bindingHandlers.daterangepicker.EXTRA_INTERVAL_OPTIONS.push(newValue);
-          _intervalOptions.push('<option value="' + newValue + '">' + newValue + '</option>');
-        }
-      }
-
-      function matchIntervals(fromCustom) {
-        _tmpl.find(".interval-select").val(_options.gap());
-        if (_tmpl.find(".interval-select").val() == null) {
-          if (fromCustom){
-            pushIntervalValue(_options.gap());
-            if (bindingContext.$root.intervalOptions){
-              bindingContext.$root.intervalOptions(ko.bindingHandlers.daterangepicker.INTERVAL_OPTIONS);
-            }
-          }
-          else {
-            _tmpl.find(".interval-select").val(_tmpl.find(".interval-select option:first").val());
-            _options.gap(_tmpl.find(".interval-select").val());
-            if (typeof _options.relatedgap != "undefined"){
-              _options.relatedgap(_options.gap());
-            }
-            _tmpl.find(".interval-custom").val(_options.gap());
-          }
-        }
-      }
-
-      _tmpl.find(".interval-select").on("change", function () {
-        _options.gap(_tmpl.find(".interval-select").val());
-        if (typeof _options.relatedgap != "undefined"){
-          _options.relatedgap(_options.gap());
-        }
-        _tmpl.find(".interval").val(_options.gap());
-        _tmpl.find(".interval-custom").val(_options.gap());
-      });
-
-      function rangeHandler(isStart) {
-        var startDate = moment(_tmpl.find(".start-date").val() + " " + _tmpl.find(".start-time").val(), DATETIME_FORMAT);
-        var endDate = moment(_tmpl.find(".end-date").val() + " " + _tmpl.find(".end-time").val(), DATETIME_FORMAT);
-        if (startDate.valueOf() > endDate.valueOf()) {
-          if (isStart) {
-            _tmpl.find(".end-date").val(startDate.utc().format(DATE_FORMAT));
-            _tmpl.find(".end-date").datepicker('setValue', startDate.utc().format(DATE_FORMAT));
-            _tmpl.find(".end-date").data("original-val", _tmpl.find(".end-date").val());
-            _tmpl.find(".end-time").val(startDate.utc().format(TIME_FORMAT));
-          }
-          else {
-            if (_tmpl.find(".end-date").val() == _tmpl.find(".start-date").val()) {
-              _tmpl.find(".end-time").val(startDate.utc().format(TIME_FORMAT));
-              _tmpl.find(".end-time").data("timepicker").setValues(startDate.format(TIME_FORMAT));
-            }
-            else {
-              _tmpl.find(".end-date").val(_tmpl.find(".end-date").data("original-val"));
-              _tmpl.find(".end-date").datepicker("setValue", _tmpl.find(".end-date").data("original-val"));
-            }
-            // non-sticky error notification
-            $.jHueNotify.notify({
-              level: "ERROR",
-              message: "The end cannot be before the starting moment"
-            });
-          }
-        }
-        else {
-          _tmpl.find(".end-date").data("original-val", _tmpl.find(".end-date").val());
-          _tmpl.find(".start-date").datepicker("hide");
-          _tmpl.find(".end-date").datepicker("hide");
-        }
-
-        var _calculatedStartDate = moment(_tmpl.find(".start-date").val() + " " + _tmpl.find(".start-time").val(), DATETIME_FORMAT);
-        var _calculatedEndDate = moment(_tmpl.find(".end-date").val() + " " + _tmpl.find(".end-time").val(), DATETIME_FORMAT);
-
-        _options.min(_calculatedStartDate.format("YYYY-MM-DD[T]HH:mm:ss[Z]"));
-        _options.start(_options.min());
-        _options.max(_calculatedEndDate.format("YYYY-MM-DD[T]HH:mm:ss[Z]"));
-        _options.end(_options.max());
-
-        _tmpl.find(".start-date-custom").val(_options.min());
-        _tmpl.find(".end-date-custom").val(_options.max());
-
-        var _opts = [];
-        // hide not useful options from interval
-        if (_calculatedEndDate.diff(_calculatedStartDate, 'minutes') > 1 && _calculatedEndDate.diff(_calculatedStartDate, 'minutes') <= 60) {
-          _opts = enableOptions("200MILLISECONDS", "1SECONDS", "1MINUTES", "5MINUTES", "10MINUTES", "30MINUTES");
-        }
-        if (_calculatedEndDate.diff(_calculatedStartDate, 'hours') > 1 && _calculatedEndDate.diff(_calculatedStartDate, 'hours') <= 12) {
-          _opts = enableOptions("5MINUTES", "10MINUTES", "30MINUTES", "1HOURS", "3HOURS");
-        }
-        if (_calculatedEndDate.diff(_calculatedStartDate, 'hours') > 12 && _calculatedEndDate.diff(_calculatedStartDate, 'hours') < 36) {
-          _opts = enableOptions("10MINUTES", "30MINUTES", "1HOURS", "3HOURS", "6HOURS", "12HOURS");
-        }
-        if (_calculatedEndDate.diff(_calculatedStartDate, 'days') > 1 && _calculatedEndDate.diff(_calculatedStartDate, 'days') <= 7) {
-          _opts = enableOptions("30MINUTES", "1HOURS", "3HOURS", "6HOURS", "12HOURS", "1DAYS");
-        }
-        if (_calculatedEndDate.diff(_calculatedStartDate, 'days') > 7 && _calculatedEndDate.diff(_calculatedStartDate, 'days') <= 14) {
-          _opts = enableOptions("3HOURS", "6HOURS", "12HOURS", "1DAYS");
-        }
-        if (_calculatedEndDate.diff(_calculatedStartDate, 'days') > 14 && _calculatedEndDate.diff(_calculatedStartDate, 'days') <= 31) {
-          _opts = enableOptions("12HOURS", "1DAYS", "7DAYS");
-        }
-        if (_calculatedEndDate.diff(_calculatedStartDate, 'months') >= 1) {
-          _opts = enableOptions("1DAYS", "7DAYS", "1MONTHS");
-        }
-        if (_calculatedEndDate.diff(_calculatedStartDate, 'months') > 6) {
-          _opts = enableOptions("1DAYS", "7DAYS", "1MONTHS", "6MONTHS");
-        }
-        if (_calculatedEndDate.diff(_calculatedStartDate, 'months') > 12) {
-          _opts = enableOptions("7DAYS", "1MONTHS", "6MONTHS", "1YEARS", "10YEARS");
-        }
-
-        $(".interval-select").html(renderOptions(_opts));
-
-        matchIntervals(true);
-      }
-    }
-  };
-
-  ko.bindingHandlers.stretchDown = {
-    init: function (element) {
-      var $element = $(element);
-      var $parent = $element.parent();
-
-      var lastParentHeight = -1;
-      var lastTop = -1;
-
-      function stretch(force) {
-        if (lastParentHeight !== $parent.innerHeight() || lastTop !== $element.position().top || force) {
-          lastParentHeight = $parent.innerHeight();
-          lastTop = $element.position().top;
-          $element.height(lastParentHeight - lastTop - ($element.outerHeight(true) - $element.innerHeight()));
-          huePubSub.publish('assist.stretchDown', $element);
-        }
-      }
-
-      window.setInterval(stretch, 200);
-      huePubSub.subscribe('assist.forceStretchDown', function(){
-        stretch(true);
-      });
-    }
-  };
-
-  ko.bindingHandlers.assistVerticalResizer = {
-    init: function (element, valueAccessor) {
-      var $container = $(element);
-      var options = ko.unwrap(valueAccessor());
-      var panelDefinitions = options.panels;
-
-      var timeout = -1;
-      var checkForElements = function () {
-        var $allPanels = $container.children('.assist-inner-panel');
-        var $allExtras = $container.children('.assist-fixed-height');
-        if (panelDefinitions().length == $allPanels.length && ($allExtras.length > 0 || options.noFixedHeights)) {
-          ko.bindingHandlers.assistVerticalResizer.updateWhenRendered(element, valueAccessor);
-        } else {
-          timeout = window.setTimeout(checkForElements, 10);
-        }
-      };
-
-      checkForElements();
-      panelDefinitions.subscribe(function () {
-        timeout = window.setTimeout(checkForElements, 10);
-      })
-    },
-
-    updateWhenRendered: function (element, valueAccessor) {
-      var self = this;
-      var options = ko.unwrap(valueAccessor());
-      var apiHelper = options.apiHelper;
-      var panelDefinitions = options.panels;
-
-      var $container = $(element);
-      var $allPanels = $container.children('.assist-inner-panel');
-      var $allResizers = $container.children(".assist-resizer");
-      var $allExtras = $container.children('.assist-fixed-height');
-
-      var allExtrasHeight = 0;
-      $allExtras.each(function (idx, extra) {
-        allExtrasHeight += $(extra).outerHeight(true);
-      });
-
-      window.clearInterval($container.data('height_interval'));
-
-      if (panelDefinitions().length === 0) {
-        $allExtras.show();
-        return;
-      }
-      if (panelDefinitions().length === 1) {
-        var adjustHeightSingle = function () {
-          $allPanels.height($container.innerHeight() - allExtrasHeight);
-        };
-
-        var heightAdjustInterval = window.setInterval(adjustHeightSingle, 800);
-        adjustHeightSingle();
-        $container.data('height_interval', heightAdjustInterval);
-
-        $(window).resize(adjustHeightSingle);
-        huePubSub.subscribe('assist.forceRender', function () {
-          window.setTimeout(adjustHeightSingle, 200);
-        });
-        $allExtras.show();
-        $allPanels.show();
-        return;
-      }
-
-      var panelRatios = apiHelper.getFromTotalStorage('assist', 'innerPanelRatios', {});
-
-      var totalRatios = 0;
-      $.each($allPanels, function (idx, panel) {
-        var panelDef = panelDefinitions()[idx];
-        if (!panelRatios[panelDef.type]) {
-          panelRatios[panelDef.type] = 1 / panelDefinitions().length;
-        }
-        totalRatios += panelRatios[panelDef.type];
-        $(panel).data('minHeight', panelDef.minHeight);
-      });
-
-      // Normalize the ratios in case new panels were added or removed.
-      if (totalRatios !== 1) {
-        var diff = 1 / totalRatios;
-        $.each(panelDefinitions(), function (idx, panel) {
-          panelRatios[panel.type] = panelRatios[panel.type] * diff;
-        });
-      }
-
-      var totalHeight = -1;
-      var containerTop = $container.offset().top;
-
-      // Resizes all containers according to the set ratios
-      var resizeByRatio = function () {
-        if (totalHeight == $container.innerHeight()) {
-          return;
-        }
-        $allPanels = $container.children('.assist-inner-panel');
-        totalHeight = $container.innerHeight();
-        containerTop = $container.offset().top;
-
-        $.each($allPanels, function (idx, panel) {
-          var panelDef = panelDefinitions()[idx];
-          if (!panelRatios[panelDef.type] || $allPanels.length == 1) {
-            panelRatios[panelDef.type] = 1 / panelDefinitions().length;
-          }
-          totalRatios += panelRatios[panelDef.type];
-          $(panel).data('minHeight', panelDef.minHeight);
-        });
-
-        var availableForPanels = totalHeight - allExtrasHeight;
-        var leftoverSpace = 0;
-        $allPanels.each(function (idx, panel) {
-          var $panel = $(panel);
-          var desiredHeight = availableForPanels * panelRatios[panelDefinitions()[idx].type];
-          var newHeight = Math.max($panel.data('minHeight'), desiredHeight);
-          $panel.height(newHeight);
-          leftoverSpace += newHeight - desiredHeight;
-        });
-        // The minheight is greater than the ratio so we shrink where possible
-        if (leftoverSpace > 0) {
-          $allPanels.each(function (idx, panel) {
-            if (leftoverSpace === 0) {
-              return false;
-            }
-            var $panel = $(panel);
-            var currentHeight = $panel.height();
-            var possibleContribution = Math.min(currentHeight - $panel.data('minHeight'), leftoverSpace);
-            if (possibleContribution > 0) {
-              $panel.height(currentHeight - possibleContribution);
-              leftoverSpace -= possibleContribution;
-            }
-          });
-        }
-      };
-
-      resizeByRatio();
-      $(window).resize(resizeByRatio);
-
-      window.setTimeout(resizeByRatio, 1000);
-      huePubSub.subscribe('assist.forceRender', function () {
-        window.setTimeout(resizeByRatio, 200);
-      });
-
-      $allExtras.show();
-      $allPanels.show();
-
-      var fitPanelHeights = function ($panelsToResize, desiredTotalHeight) {
-        var currentHeightOfPanels = 0;
-
-        var noMoreSpace = true;
-        $panelsToResize.each(function (idx, panel) {
-          var $panel = $(panel);
-          var panelHeight = $panel.outerHeight(true);
-          noMoreSpace = noMoreSpace && panelHeight <= $panel.data('minHeight');
-          currentHeightOfPanels += panelHeight;
-        });
-
-        var distanceToGo = desiredTotalHeight - currentHeightOfPanels;
-        if (noMoreSpace && distanceToGo < 0) {
-          return;
-        }
-
-        // Add all to the first panel if expanding (distanceToGo is positive
-        if (distanceToGo >= 0) {
-          $panelsToResize.first().height($panelsToResize.first().height() + distanceToGo + 'px');
-          return;
-        }
-
-        // Remove as much as possible on each panel if shrinking (distanceToGo is negative)
-        $panelsToResize.each(function (idx, panel) {
-          var $panel = $(panel);
-          var initialHeight = $panel.height();
-          var newHeight = Math.max($panel.data('minHeight'), initialHeight + distanceToGo);
-          if (initialHeight == newHeight) {
-            return true;
-          }
-          $panel.height(newHeight);
-          distanceToGo += initialHeight - newHeight;
-          if (distanceToGo >= 0) {
-            return false;
-          }
-        });
-      };
-
-      $allResizers.each(function (idx, resizer) {
-        var $resizer = $(resizer);
-        var extrasBeforeHeight = 0;
-        $resizer.prevAll('.assist-fixed-height').each(function (idx, extra) {
-          extrasBeforeHeight += $(extra).outerHeight(true);
-        });
-        var $panelsBefore = $resizer.prevAll('.assist-inner-panel');
-        var limitBefore = extrasBeforeHeight;
-        $panelsBefore.each(function (idx, panel) {
-          limitBefore += $(panel).data('minHeight');
-        });
-
-        var extrasAfterHeight = allExtrasHeight - extrasBeforeHeight;
-        var $panelsAfter = $resizer.nextAll('.assist-inner-panel');
-        var requiredSpaceAfter = extrasAfterHeight;
-        $panelsAfter.each(function (idx, panel) {
-          requiredSpaceAfter += $(panel).data('minHeight');
-        });
-
-        $resizer.draggable({
-          axis: "y",
-          drag: function (event, ui) {
-            var limitAfter = totalHeight - requiredSpaceAfter;
-            var position = ui.offset.top - containerTop;
-            if (position > limitBefore && position < limitAfter) {
-              fitPanelHeights($panelsBefore, position - extrasBeforeHeight);
-              fitPanelHeights($panelsAfter, totalHeight - extrasAfterHeight - position);
-            } else if (position > limitAfter) {
-              fitPanelHeights($panelsBefore, limitAfter - extrasBeforeHeight);
-              fitPanelHeights($panelsAfter, totalHeight - extrasAfterHeight - limitAfter);
-            } else if (position < limitBefore) {
-              fitPanelHeights($panelsBefore, limitBefore - extrasBeforeHeight);
-              fitPanelHeights($panelsAfter, totalHeight - extrasAfterHeight - limitBefore);
-            }
-
-            ui.offset.top = 0;
-            ui.position.top = 0;
-          },
-          stop: function (event, ui) {
-            ui.offset.top = 0;
-            ui.position.top = 0;
-            var totalHeightForPanels = 0;
-            $allPanels.each(function (idx, panel) {
-              totalHeightForPanels += $(panel).outerHeight(true);
-            });
-            $allPanels.each(function (idx, panel) {
-              panelRatios[panelDefinitions()[idx].type] = $(panel).outerHeight(true) / totalHeightForPanels;
-            });
-            apiHelper.setInTotalStorage('assist', 'innerPanelRatios', panelRatios);
-          }
-        });
-      });
-    }
-  };
-
-  /**
-   * Show the Context Popover for files (HDFS, S3, ADLS, ...) when the bound element is clicked.
-   *
-   * Parameters:
-   *
-   * {string} path - the path (can include type, i.e. 'hdfs://tmp'
-   * {string} [type] - Optional type, 'hdfs', 's3' etc. Default 'hdfs'.
-   * {string} [orientation] - 'top', 'right', 'bottom', 'left'. Default 'right';
-   * {Object} [offset] - Optional offset from the element
-   * {number} [offset.top] - Offset in pixels
-   * {number} [offset.left] - Offset in pixels
-   *
-   * Examples:
-   *
-   * data-bind="storageContextPopover: { path: '/tmp/banana.csv' }"
-   * data-bind="storageContextPopover: { path: 's3:/tmp/banana.csv', orientation: 'bottom', offset: { top: 5 } }"
-   *
-   * @type {{init: ko.bindingHandlers.storageContextPopover.init}}
-   */
-  ko.bindingHandlers.storageContextPopover = {
-    init: function (element, valueAccessor, allBindings, viewModel, bindingContext) {
-      ko.bindingHandlers.click.init(element, function () {
-        return function () {
-          var options = valueAccessor();
-          AssistStorageEntry.getEntry(options.path, options.type).done(function (entry) {
-            var $source = $(element);
-            var offset = $source.offset();
-
-            if (options.offset) {
-              offset.top += options.offset.top || 0;
-              offset.left += options.offset.left || 0;
-            }
-
-            entry.open(true);
-            huePubSub.publish('context.popover.show', {
-              data: {
-                type: 'storageEntry',
-                storageEntry: entry
-              },
-              orientation: options.orientation || 'right',
-              source: {
-                element: element,
-                left: offset.left,
-                top: offset.top,
-                right: offset.left + $source.width(),
-                bottom: offset.top + $source.height()
-              }
-            });
-
-          })
-        };
-      }, allBindings, viewModel, bindingContext);
-    }
-  };
-
-  /**
-   * Show the Context Popover for SQL or Solr entities when the bound element is clicked.
-   *
-   * Parameters:
-   *
-   * {string} sourceType - 'impala', 'hive' etc.
-   * {ContextNamespace} namespace
-   * {ContextCompute} compute
-   * {string} path - the path, i.e. 'default.customers' or ['default', 'customers'
-   * {string} [orientation] - 'top', 'right', 'bottom', 'left'. Default 'right'
-   * {Object} [offset] - Optional offset from the element
-   * {number} [offset.top] - Offset in pixels
-   * {number} [offset.left] - Offset in pixels
-   *
-   * Examples:
-   *
-   * data-bind="sqlContextPopover: { sourceType: 'impala', namespace: { id: 'myNamespace' }, compute: { id: 'myCompute' }, path: 'default.customers' }"
-   * data-bind="sqlContextPopover: { sourceType: 'hive', namespace: { id: 'myNamespace' }, compute: { id: 'myCompute' }, path: 'default', orientation: 'bottom', offset: { top: 5 } }"
-   *
-   * @type {{init: ko.bindingHandlers.sqlContextPopover.init}}
-   */
-  ko.bindingHandlers.sqlContextPopover = {
-    init: function (element, valueAccessor, allBindings, viewModel, bindingContext) {
-      ko.bindingHandlers.click.init(element, function () {
-        return function () {
-          var options = valueAccessor();
-          dataCatalog.getEntry(options).done(function (entry) {
-            var $source = $(element);
-            var offset = $source.offset();
-            if (options.offset) {
-              offset.top += options.offset.top || 0;
-              offset.left += options.offset.left || 0;
-            }
-
-            huePubSub.publish('context.popover.show', {
-              data: {
-                type: 'catalogEntry',
-                catalogEntry: entry
-              },
-              showInAssistEnabled: true,
-              orientation: options.orientation || 'right',
-              source: {
-                element: element,
-                left: offset.left,
-                top: offset.top,
-                right: offset.left + $source.width(),
-                bottom: offset.top + $source.height()
-              }
-            });
-          });
-        }
-      }, allBindings, viewModel, bindingContext);
-    }
-  };
-
-  /**
-   * Show the Context Popover for Documents when the bound element is clicked.
-   *
-   * Parameters:
-   *
-   * {string} uuid - the uuid of the document
-   * {string} [orientation] - 'top', 'right', 'bottom', 'left'. Default 'right'
-   * {Object} [offset] - Optional offset from the element
-   * {number} [offset.top] - Offset in pixels
-   * {number} [offset.left] - Offset in pixels
-   *
-   * Examples:
-   *
-   * data-bind="documentContextPopover: { uuid: 'bana-na12-3456-7890' }"
-   * data-bind="documentContextPopover: { uuid: 'bana-na12-3456-7890', orientation: 'bottom', offset: { top: 5 } }"
-   *
-   * @type {{init: ko.bindingHandlers.documentContextPopover.init}}
-   */
-  ko.bindingHandlers.documentContextPopover = {
-    init: function (element, valueAccessor, allBindings, viewModel, bindingContext) {
-      ko.bindingHandlers.click.init(element, function () {
-        return function () {
-          var options = valueAccessor();
-
-          window.apiHelper.fetchDocument({
-            uuid: options.uuid,
-            fetchContents: true,
-            silenceErrors: true
-          }).done(function (response) {
-            var $source = $(element);
-            var offset = $source.offset();
-            if (options.offset) {
-              offset.top += options.offset.top || 0;
-              offset.left += options.offset.left || 0;
-            }
-
-            huePubSub.publish('context.popover.show', {
-              data: {
-                type: 'hue',
-                definition: response.document
-              },
-              showInAssistEnabled: true,
-              orientation: options.orientation || 'right',
-              source: {
-                element: element,
-                left: offset.left,
-                top: offset.top,
-                right: offset.left + $source.width(),
-                bottom: offset.top + $source.height()
-              }
-            });
-          });
-        }
-      }, allBindings, viewModel, bindingContext);
-    }
-  };
-
-  ko.bindingHandlers.aceResizer = {
-    init: function (element, valueAccessor) {
-      var options = ko.unwrap(valueAccessor());
-      var ace = options.snippet.ace;
-      var $target = $(options.target);
-      var $resizer = $(element);
-      var $contentPanel = $(".content-panel");
-      var $execStatus = $resizer.prev('.snippet-execution-status');
-      var $variables = $resizer.siblings('.snippet-row').find('.variables');
-
-      var lastEditorSize = $.totalStorage('hue.editor.editor.size') || 131;
-      var editorHeight = Math.floor(lastEditorSize / 16);
-      $target.height(lastEditorSize);
-      var autoExpand = typeof options.snippet.aceAutoExpand !== 'undefined' ? options.snippet.aceAutoExpand : true;
-      var draggedOnce = false;
-
-      function throttleChange() {
-        if (autoExpand && !draggedOnce) {
-          var maxAutoLines = Math.floor((($(window).height() - 80) / 2) / 16);
-          var resized = false;
-          if (ace().session.getLength() > editorHeight) {
-            if (ace().session.getLength() < maxAutoLines) {
-              $target.height(ace().session.getLength() * 16);
-            }
-            else {
-              $target.height(maxAutoLines * 16); // height of maxAutoLines
-            }
-            resized = true;
-          }
-          else {
-            $target.height(Math.max(ace().session.getLength() * 16, $.totalStorage('hue.editor.editor.size') || 131));
-            resized = true;
-          }
-          if (ace().session.getLength() == editorHeight) {
-            resized = false;
-          }
-          if (resized && $target.height() !== lastEditorSize) {
-            ace().resize();
-            editorHeight = Math.min(maxAutoLines, ace().session.getLength());
-            lastEditorSize = $target.height();
-            huePubSub.publish('redraw.fixed.headers');
-          }
-        }
-      }
-
-      var changeTimeout = -1;
-      ace().on('change', function () {
-        window.clearTimeout(changeTimeout);
-        changeTimeout = window.setTimeout(throttleChange, 10)
-      });
-
-      var setAutoExpandSubscription = huePubSub.subscribe('ace.set.autoexpand', function (options) {
-        if (ace().container.id === options.snippet.id()) {
-          autoExpand = options.autoExpand;
-        }
-      });
-
-      $resizer.draggable({
-        axis: "y",
-        start: options.onStart ? options.onStart : function(){},
-        drag: function (event, ui) {
-          draggedOnce = true;
-          var currentHeight = ui.offset.top + $contentPanel.scrollTop() - (125 + $execStatus.outerHeight(true) + $variables.outerHeight(true));
-          $target.css("height", currentHeight + "px");
-          ace().resize();
-          ui.offset.top = 0;
-          ui.position.top = 0;
-        },
-        stop: function (event, ui) {
-          ui.offset.top = 0;
-          ui.position.top = 0;
-          $.totalStorage('hue.editor.editor.size', $target.height());
-          huePubSub.publish('redraw.fixed.headers');
-          $(document).trigger("editorSizeChanged");
-        }
-      });
-
-      ko.utils.domNodeDisposal.addDisposeCallback(element, function () {
-        setAutoExpandSubscription.remove();
-      });
-    }
-  };
-
-  ko.bindingHandlers.logResizer = {
-    init: function (element, valueAccessor) {
-      var options = ko.unwrap(valueAccessor()),
-        $resizer = $(element),
-        $parent = $resizer.parents(options.parent),
-        $target = $parent.find(options.target),
-        onStart = options.onStart,
-        onResize = options.onResize;
-
-      var initialHeight = $.totalStorage('hue.editor.logs.size') || 80;
-
-      window.setTimeout(function () {
-        $target.css("height", initialHeight + "px");
-      }, 0);
-
-      $resizer.draggable({
-        axis: "y",
-        start: function (event, ui) {
-          if (onStart) {
-            onStart();
-          }
-        },
-        drag: function (event, ui) {
-          var currentHeight = ui.offset.top - $target.offset().top - 20;
-          if (options.minHeight && currentHeight < options.minHeight) {
-            currentHeight = options.minHeight;
-          }
-          $.totalStorage('hue.editor.logs.size', currentHeight);
-          $target.css("height", currentHeight + "px");
-          ui.offset.top = 0;
-          ui.position.top = 0;
-        },
-        stop: function (event, ui) {
-          ui.offset.top = 0;
-          ui.position.top = 0;
-          if (onResize) {
-            onResize();
-          }
-        }
-      });
-    }
-  };
-
-  ko.bindingHandlers.splitFlexDraggable = {
-    init: function (element, valueAccessor) {
-      var options = ko.unwrap(valueAccessor());
-      var sidePanelWidth = $.totalStorage(options.appName + '_' + options.orientation + '_panel_width') != null ? $.totalStorage(options.appName + '_' + options.orientation + '_panel_width') : 290;
-
-      var $resizer = $(element);
-      var $sidePanel = $(options.sidePanelSelector);
-      var $container = $(options.containerSelector);
-
-      var isLeft = options.orientation === 'left';
-
-      var onPosition = options.onPosition || function() {};
-
-      $sidePanel.css('flex-basis', sidePanelWidth + 'px');
-      $resizer.draggable({
-        axis: 'x',
-        containment: $container,
-        start: function () {
-          sidePanelWidth = $sidePanel.width();
-        },
-        drag: function (event, ui) {
-          if (isLeft) {
-            $sidePanel.css('flex-basis', Math.max(sidePanelWidth + ui.position.left, 200) + 'px');
-          } else {
-            $sidePanel.css('flex-basis', Math.max(sidePanelWidth - ui.position.left, 200) + 'px');
-          }
-          onPosition();
-          ui.position.left = 0;
-        },
-        stop: function () {
-          sidePanelWidth = $sidePanel.width();
-          $.totalStorage(options.appName + '_' + options.orientation + '_panel_width', sidePanelWidth);
-          window.setTimeout(positionPanels, 100);
-          huePubSub.publish('split.panel.resized');
-        }
-      });
-
-      var positionPanels = function () {
-        if (options.sidePanelVisible()) {
-          $sidePanel.css('flex-basis',  Math.max(sidePanelWidth, 200) + 'px');
-          onPosition();
-        }
-      };
-
-      options.sidePanelVisible.subscribe(positionPanels);
-
-      var positionTimeout = -1;
-      $(window).resize(function() {
-        window.clearTimeout(positionTimeout);
-        positionTimeout = window.setTimeout(function () {
-          positionPanels()
-        }, 1);
-      });
-
-      function initialPositioning() {
-        if(! $container.is(':visible') && ! $sidePanel.is(':visible')) {
-          window.setTimeout(initialPositioning, 50);
-        } else {
-          positionPanels();
-          // Even though the container is visible some slow browsers might not
-          // have rendered the panels
-          window.setTimeout(positionPanels, 50);
-        }
-      }
-      initialPositioning();
-    }
-  };
-
-  ko.bindingHandlers.splitDraggable = {
-    init: function (element, valueAccessor) {
-      var options = ko.unwrap(valueAccessor());
-      var leftPanelWidth = $.totalStorage(options.appName + "_left_panel_width") != null ? Math.max($.totalStorage(options.appName + "_left_panel_width"), 250) : 250;
-      var rightPanelWidth = $.totalStorage(options.appName + "_right_panel_width") != null ? Math.max($.totalStorage(options.appName + "_right_panel_width"), 250) : 290;
-
-      var containerSelector = options.containerSelector || ".panel-container";
-      var contentPanelSelector = options.contentPanelSelector || ".content-panel";
-
-      var onPosition = options.onPosition || function() {};
-
-      var hasLeftPanel = !!options.leftPanelVisible;
-      var hasRightPanel = !!options.rightPanelVisible;
-
-      var isRightPanel = !!options.isRightPanel;
-
-      var $resizer = $(element);
-      var $leftPanel = $('.left-panel');
-      var $rightPanel = $('.right-panel');
-      var $contentPanel = $(contentPanelSelector);
-      var $container = $(containerSelector);
-
-      var positionPanels = function () {
-        if (isRightPanel) {
-
-          var oppositeWidth = hasLeftPanel && ko.unwrap(options.leftPanelVisible) ? $leftPanel.width() + $resizer.width() : 0;
-          var totalWidth = $container.width() - oppositeWidth;
-          if (ko.unwrap(options.rightPanelVisible) && ko.unwrap(options.rightPanelAvailable)) {
-            $resizer.show();
-            rightPanelWidth = Math.min(rightPanelWidth, $container.width() - 100);
-            var contentPanelWidth = totalWidth - rightPanelWidth - $resizer.width();
-            $rightPanel.css("width", rightPanelWidth + "px");
-            $contentPanel.css("width", contentPanelWidth + "px");
-            $resizer.css("left", $container.width() - rightPanelWidth - $resizer.width() + "px");
-            $contentPanel.css("right", rightPanelWidth + $resizer.width() + "px");
-          } else {
-            if (oppositeWidth === 0) {
-              $contentPanel.css("width", "100%");
-            } else {
-              $contentPanel.css("width", totalWidth);
-            }
-            $contentPanel.css("right", "0");
-            $resizer.hide();
-          }
-        } else {
-          var oppositeWidth = hasRightPanel && ko.unwrap(options.rightPanelVisible) && ko.unwrap(options.rightPanelAvailable) ? $rightPanel.width() + $resizer.width() : 0;
-          var totalWidth = $container.width() - oppositeWidth;
-          if (ko.unwrap(options.leftPanelVisible)) {
-            $resizer.show();
-            leftPanelWidth = Math.min(leftPanelWidth, totalWidth - 100);
-            var contentPanelWidth = totalWidth - leftPanelWidth - $resizer.width();
-            $leftPanel.css("width", leftPanelWidth + "px");
-            $contentPanel.css("width", contentPanelWidth + "px");
-            $resizer.css("left", leftPanelWidth + "px");
-            $contentPanel.css("left", leftPanelWidth + $resizer.width() + "px");
-          } else {
-            if (oppositeWidth === 0) {
-              $contentPanel.css("width", "100%");
-            } else {
-              $contentPanel.css("width", totalWidth);
-            }
-            $contentPanel.css("left", "0");
-            $resizer.hide();
-          }
-        }
-        onPosition();
-      };
-
-      if (ko.isObservable(options.leftPanelVisible)) {
-        options.leftPanelVisible.subscribe(positionPanels);
-      }
-
-      if (ko.isObservable(options.rightPanelVisible)) {
-        options.rightPanelVisible.subscribe(positionPanels);
-      }
-
-      if (ko.isObservable(options.rightPanelAvailable)) {
-        options.rightPanelAvailable.subscribe(positionPanels);
-      }
-
-      var dragTimeout = -1;
-      $resizer.draggable({
-        axis: "x",
-        containment: $container,
-        drag: function (event, ui) {
-          if (isRightPanel) {
-            ui.position.left = Math.min($container.width() - 200, ui.position.left);
-          } else {
-            ui.position.left = Math.min($container.width() - $container.position().left - 200, Math.max(250, ui.position.left));
-          }
-
-          dragTimeout = window.setTimeout(function () {
-            if (isRightPanel) {
-              var oppositeWidth = hasLeftPanel && ko.unwrap(options.leftPanelVisible) ? $leftPanel.width() + $resizer.width() : 0;
-              var totalWidth = $container.width() - oppositeWidth;
-              rightPanelWidth = $container.width() - ui.position.left;
-              $rightPanel.css("width", rightPanelWidth + "px");
-              $contentPanel.css("width", totalWidth - rightPanelWidth + "px");
-              // $contentPanel.css("right", rightPanelWidth + $resizer.width());
-            } else {
-              var oppositeWidth = hasRightPanel && ko.unwrap(options.rightPanelVisible) ? $rightPanel.width() + $resizer.width() : 0;
-              var totalWidth = $container.width() - oppositeWidth;
-              leftPanelWidth = ui.position.left;
-              $leftPanel.css("width", leftPanelWidth + "px");
-              $contentPanel.css("width", totalWidth - leftPanelWidth - $resizer.width() + "px");
-              $contentPanel.css("left", leftPanelWidth + $resizer.width());
-            }
-            onPosition();
-          }, 10);
-
-        },
-        stop: function () {
-          if (isRightPanel) {
-            $.totalStorage(options.appName + "_right_panel_width", rightPanelWidth);
-          } else {
-            $.totalStorage(options.appName + "_left_panel_width", leftPanelWidth);
-          }
-          window.setTimeout(positionPanels, 100);
-          huePubSub.publish('split.panel.resized');
-        }
-      });
-
-
-      var positionTimeout = -1;
-      $(window).resize(function() {
-        window.clearTimeout(positionTimeout);
-        positionTimeout = window.setTimeout(function () {
-          positionPanels()
-        }, 1);
-      });
-
-      function initialPositioning() {
-        if(! $container.is(":visible")) {
-          window.setTimeout(initialPositioning, 50);
-        } else {
-          positionPanels();
-          // Even though the container is visible some slow browsers might not
-          // have rendered the panels
-          window.setTimeout(positionPanels, 100);
-        }
-      }
-      initialPositioning();
-    }
-  };
-
-  ko.bindingHandlers.oneClickSelect = {
-    init: function (element) {
-      $(element).click(function() {
-        if (document.selection) {
-          var range = document.body.createTextRange();
-          range.moveToElementText(element);
-          range.select();
-        } else if (window.getSelection) {
-          var range = document.createRange();
-          range.selectNode(element);
-          window.getSelection().addRange(range);
-        }
-      });
-    }
-  };
-
-  ko.bindingHandlers.augmenthtml = {
-    render: function (element, valueAccessor, allBindingsAccessor, viewModel) {
-      var _val = ko.unwrap(valueAccessor());
-      var _enc = $("<span>").html(_val);
-      if (_enc.find("style").length > 0) {
-        var parser = new less.Parser();
-        $(_enc.find("style")).each(function (cnt, item) {
-          var _less = ".result-container {" + $(item).text() + "}";
-          try {
-            parser.parse(_less, function (err, tree) {
-              $(item).text(tree.toCSS());
-            });
-          }
-          catch (e) {
-          }
-        });
-        $(element).html(_enc.html());
-      }
-      else {
-        $(element).html(_val);
-      }
-    },
-    init: function (element, valueAccessor, allBindingsAccessor, viewModel) {
-      ko.bindingHandlers.augmenthtml.render(element, valueAccessor, allBindingsAccessor, viewModel);
-    },
-    update: function (element, valueAccessor, allBindingsAccessor, viewModel) {
-      ko.bindingHandlers.augmenthtml.render(element, valueAccessor, allBindingsAccessor, viewModel);
-    }
-  };
-
-  ko.bindingHandlers.clearable = {
-    after: ['textInput', 'value', 'valueUpdate'],
-    init: function (element, valueAccessor, allBindingsAccessor, viewModel) {
-      var $element = $(element);
-
-      var params = valueAccessor();
-      var valueObservable = ko.isObservable(params) ? params : params.value;
-
-      function tog(v) {
-        return v ? "addClass" : "removeClass";
-      }
-
-      $element.addClass("clearable");
-      $element[tog(valueObservable())]("x");
-
-      $element.on("input", function () {
-        $element[tog(this.value)]("x");
-      }).on("mousemove", function (e) {
-        $element[tog(this.offsetWidth - 18 < e.clientX - this.getBoundingClientRect().left)]("onX");
-      })
-      .on("click", function (e) {
-        if (this.offsetWidth - 18 < e.clientX - this.getBoundingClientRect().left) {
-          $element.removeClass("x onX").val("");
-          valueObservable("");
-          if (typeof params.onClear === 'function') {
-            params.onClear();
-          }
-        }
-      });
-
-      if (!allBindingsAccessor()['textInput'] || !allBindingsAccessor()['value']) {
-        $element.on("change", function () {
-          valueObservable($element.val());
-        }).on("blur", function () {
-          valueObservable($element.val());
-        });
-
-        if (allBindingsAccessor()['valueUpdate'] != null && allBindingsAccessor()['valueUpdate'] == "afterkeydown") {
-          $element.on("keyup", function () {
-            valueObservable($element.val());
-          });
-        }
-
-        if (allBindingsAccessor()['valueUpdateDelay'] != null) {
-          var _timeout = -1;
-          $element.on("keyup", function (e) {
-            if (!([13, 37, 38, 39, 40].indexOf(e.keyCode) > -1)) {
-              window.clearTimeout(_timeout);
-              _timeout = window.setTimeout(function () {
-                valueObservable($element.val());
-              }, allBindingsAccessor()['valueUpdateDelay']);
-            }
-          });
-        }
-      }
-
-    },
-    update: function (element, valueAccessor, allBindingsAccessor) {
-      var $element = $(element);
-      var params = valueAccessor();
-      var valueObservable = ko.isObservable(params) ? params : params.value;
-
-      if (!$element.is(':focus') || valueObservable() !== $element.val()) {
-        $element.val(valueObservable());
-      }
-      if ($element.val() === '') {
-        $element.removeClass('x');
-      }
-    }
-  };
-
-  ko.bindingHandlers.onClickOutside = {
-    update: function (element, valueAccessor, allBindingsAccessor, viewModel) {
-      var options = valueAccessor();
-      var func = (typeof options === 'function') ? options : options.onOutside;
-
-      var onDocumentClick = function (event) {
-        if ($.contains(document, event.target) && !$.contains(element, event.target)) {
-          var result = func.bind(viewModel)();
-          if (typeof result === 'undefined' || result) {
-            $(document).off('click', onDocumentClick);
-          }
-        }
-      };
-
-      $(document).off('click', onDocumentClick);
-      $(document).on('click', onDocumentClick);
-
-      ko.utils.domNodeDisposal.addDisposeCallback(element, function() {
-        $(document).off('click', onDocumentClick);
-      });
-    }
-  };
-
-  ko.bindingHandlers.blurHide = {
-    init: function (element, valueAccessor) {
-      var $el = $(element);
-      var prop = valueAccessor();
-      $el.on('blur', function () {
-        if ($.trim($el.val()) === '') {
-          if (ko.isObservable(prop)) {
-            prop(false);
-          }
-        }
-      });
-    },
-    update: function (element, valueAccessor) {
-      var $el = $(element);
-      var prop = valueAccessor();
-      if (ko.isObservable(prop) && prop()) {
-        $el.focus();
-      }
-    }
-  }
-
-  ko.bindingHandlers.spinedit = {
-    init: function (element, valueAccessor, allBindingsAccessor, viewModel) {
-      var options = $.extend({
-        minimum: 0,
-        maximum: 10000,
-        step: 5,
-        value: ko.unwrap(valueAccessor()),
-        numberOfDecimals: 0
-      }, allBindingsAccessor().override);
-      $(element).spinedit(options);
-      $(element).on("valueChanged", function (e) {
-        valueAccessor()(e.value);
-      });
-    },
-    update: function (element, valueAccessor, allBindingsAccessor) {
-      $(element).spinedit("setValue", ko.unwrap(valueAccessor()));
-    }
-  }
-
-  ko.bindingHandlers.codemirror = {
-    init: function (element, valueAccessor, allBindingsAccessor, viewModel) {
-      var options = $.extend(valueAccessor(), {});
-      var editor = CodeMirror.fromTextArea(element, options);
-      element.editor = editor;
-      editor.setValue(options.data());
-      editor.refresh();
-      var wrapperElement = $(editor.getWrapperElement());
-
-      $(document).on("refreshCodemirror", function () {
-        editor.setSize("100%", 300);
-        editor.refresh();
-      });
-
-      $(document).on("addFieldToSource", function (e, field) {
-        if ($(element).data("template")) {
-          editor.replaceSelection("{{" + field.name() + "}}");
-        }
-      });
-
-      $(document).on("addFunctionToSource", function (e, fn) {
-        if ($(element).data("template")) {
-          editor.replaceSelection(fn);
-        }
-      });
-
-      $(".chosen-select").chosen({
-        disable_search_threshold: 10,
-        width: "75%"
-      });
-      $('.chosen-select').trigger('chosen:updated');
-
-      var sourceDelay = -1;
-      editor.on("change", function (cm) {
-        clearTimeout(sourceDelay);
-        var _cm = cm;
-        sourceDelay = setTimeout(function () {
-          var _value = _cm.getValue();
-          if (options.stripScript){
-            _value = _value.replace(/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi, "");
-          }
-          valueAccessor().data(_value);
-          if ($(".widget-html-pill").parent().hasClass("active")) {
-            $("[contenteditable=true]").html(stripHtmlFromFunctions(valueAccessor().data()));
-          }
-        }, 100);
-      });
-
-      ko.utils.domNodeDisposal.addDisposeCallback(element, function () {
-        wrapperElement.remove();
-      });
-    },
-    update: function (element, valueAccessor, allBindingsAccessor) {
-      var editor = element.editor;
-      editor.refresh();
-    }
-  };
-
-  ko.bindingHandlers.chosen = {
-    init: function(element, valueAccessor, allBindings, viewModel, bindingContext){
-      var $element = $(element);
-      var options = ko.unwrap(valueAccessor());
-
-      if (typeof options === 'object') {
-        $element.chosen(options);
-      } else {
-        $element.chosen();
-      }
-
-      ['options', 'selectedOptions', 'value'].forEach(function(propName){
-        if (allBindings.has(propName)){
-          var prop = allBindings.get(propName);
-          if (ko.isObservable(prop)) {
-            prop.subscribe(function(){
-              $element.trigger('chosen:updated');
-            });
-          }
-        }
-      });
-    }
-  };
-
-  ko.bindingHandlers.tooltip = {
-    after: ['attr'],
-    update: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
-      var local = ko.utils.unwrapObservable(valueAccessor());
-      var options = {
-        container: HUE_CONTAINER
-      };
-
-      $(element).tooltip("destroy");
-
-      ko.utils.extend(options, local);
-
-      if (options.title) {
-        var title = ko.unwrap(options.title); // Not always an observable
-        if (typeof title === 'string' && !options.html) {
-          options.title = hueUtils.escapeOutput(title);
-        }
-      }
-
-      $(element).tooltip(options);
-
-      ko.utils.domNodeDisposal.addDisposeCallback(element, function () {
-        $(element).tooltip("destroy");
-      });
-    }
-  };
-
-  ko.bindingHandlers.typeahead = {
-    init: function (element, valueAccessor) {
-      var binding = this;
-      var elem = $(element);
-      var valueAccessor = valueAccessor();
-
-      var source = valueAccessor.nonBindableSource ? valueAccessor.nonBindableSource : function () {
-        var _source = ko.utils.unwrapObservable(valueAccessor.source);
-        if (valueAccessor.extraKeywords) {
-          _source = _source.concat(valueAccessor.extraKeywords.split(" "))
-        }
-
-        if (valueAccessor.sourceSuffix && _source) {
-          var _tmp = [];
-          _source.forEach(function (item) {
-            _tmp.push(item + valueAccessor.sourceSuffix);
-          });
-          _source = _tmp;
-        }
-        return _source;
-      }
-
-      if (valueAccessor.nonBindableSource && valueAccessor.displayProperty) {
-        source = ko.utils.arrayMap(valueAccessor.nonBindableSource(), function(item) {
-          return item[valueAccessor.displayProperty]();
-        });
-      }
-
-      var _options = {
-        source: source,
-        onselect: function (val) {
-          if (typeof valueAccessor.target == "function") {
-            valueAccessor.target(val);
-          }
-          else {
-            valueAccessor.target = val;
-          }
-        }
-      }
-
-      function extractor(query, extractorSeparator) {
-        var result = /([^ ]+)$/.exec(query);
-        if (extractorSeparator) {
-          result = new RegExp("([^\\" + extractorSeparator + "]+)$").exec(query);
-        }
-        if (result && result[1])
-          return result[1].trim();
-        return "";
-      }
-
-      if (valueAccessor.multipleValues) {
-        var _extractorFound = null;
-
-        function updateExtractors() {
-          var _val = elem.val();
-          _extractorFound = null;
-          var _extractors = (typeof valueAccessor.multipleValuesExtractors == "undefined" || valueAccessor.multipleValuesExtractors == null ? [" "] : valueAccessor.multipleValuesExtractors);
-          var _extractorFoundLastIndex = -1;
-          _extractors.forEach(function (extractor) {
-            if (_val.indexOf(extractor) > -1) {
-              if (_val.indexOf(extractor) >= _extractorFoundLastIndex) {
-                _extractorFound = extractor;
-                _extractorFoundLastIndex = _val.indexOf(extractor);
-              }
-            }
-          });
-        }
-
-        _options.updater = function (item) {
-          var _val = this.$element.val();
-          var _separator = (typeof valueAccessor.multipleValuesSeparator == "undefined" || valueAccessor.multipleValuesSeparator == null ? ":" : valueAccessor.multipleValuesSeparator);
-          if (valueAccessor.extraKeywords && valueAccessor.extraKeywords.split(" ").indexOf(item) > -1) {
-            _separator = "";
-          }
-          var isSpecialResult = false;
-          if (item.indexOf("<i ") > -1) {
-            _separator = "";
-            isSpecialResult = true;
-          }
-          updateExtractors();
-          if (_extractorFound != null) {
-            return (isSpecialResult ? '"' : '') + _val.substring(0, _val.lastIndexOf(_extractorFound)) + _extractorFound + $.trim(item.replace(/<[^>]*>/gi, "")) + (isSpecialResult ? '"' : '') + _separator;
-          }
-          else {
-            return (isSpecialResult ? '"' : '') + $.trim(item.replace(/<[^>]*>/gi, "")) + (isSpecialResult ? '"' : '') + _separator;
-          }
-        }
-        _options.matcher = function (item) {
-          updateExtractors();
-          var _tquery = extractor(this.query, _extractorFound);
-          if (!_tquery) return false;
-          return ~item.toLowerCase().indexOf(_tquery.toLowerCase());
-        },
-            _options.highlighter = function (item) {
-              updateExtractors();
-              var _query = extractor(this.query, _extractorFound).replace(/[\-\[\]{}()*+?.:\\\^$|#\s]/g, '\\$&');
-              var _result = $.trim(item.replace(/<[^>]*>/gi, "")).replace(new RegExp('(' + _query + ')', 'ig'), function ($1, match) {
-                return '<strong>' + match + '</strong>'
-              });
-              if (item.indexOf("<i ") > -1) {
-                _result += " " + item.substr(item.indexOf("<i "));
-              }
-              return _result;
-            }
-      }
-
-      if (valueAccessor.completeSolrRanges) {
-        elem.on("keyup", function (e) {
-          if (e.keyCode != 8 && e.which != 8 && elem.val() && (elem.val().slice(-1) == "[" || elem.val().slice(-1) == "{")) {
-            var _index = elem.val().length;
-            elem.val(elem.val() + " TO " + (elem.val().slice(-1) == "[" ? "]" : "}"));
-
-            if (element.createTextRange) {
-              var range = element.createTextRange();
-              range.move("character", _index);
-              range.select();
-            } else if (element.selectionStart != null) {
-              element.focus();
-              element.setSelectionRange(_index, _index);
-            }
-
-          }
-        });
-      }
-
-      if (valueAccessor.triggerOnFocus) {
-        _options.minLength = 0;
-      }
-
-      element.typeahead = elem.typeahead(_options);
-
-      if (valueAccessor.triggerOnFocus) {
-        elem.on('focus', function () {
-          elem.trigger("keyup");
-        });
-      }
-
-      elem.blur(function () {
-        if (typeof valueAccessor.target == "function") {
-          valueAccessor.target(elem.val());
-        }
-        else {
-          valueAccessor.target = elem.val();
-        }
-      });
-    },
-    update: function (element, valueAccessor) {
-      var elem = $(element);
-      var valueAccessor = valueAccessor();
-      if (typeof valueAccessor.completeSolrRanges === 'undefined') {
-        if (typeof valueAccessor.target == "function") {
-          elem.val(valueAccessor.target());
-        }
-        else {
-          elem.val(valueAccessor.target);
-        }
-      }
-      if (valueAccessor.forceUpdateSource) {
-        element.typeahead.data('typeahead').source = function () {
-          var _source = ko.utils.unwrapObservable(valueAccessor.source);
-          if (valueAccessor.extraKeywords) {
-            _source = _source.concat(valueAccessor.extraKeywords.split(" "))
-          }
-
-          if (valueAccessor.sourceSuffix && _source) {
-            var _tmp = [];
-            _source.forEach(function (item) {
-              _tmp.push(item + valueAccessor.sourceSuffix);
-            });
-            _source = _tmp;
-          }
-          return _source;
-        }
-      }
-
-    }
-  };
-
-
-  ko.bindingHandlers.select2 = {
-    init: function (element, valueAccessor, allBindingsAccessor, viewModel) {
-      var options = ko.toJS(valueAccessor()) || {};
-      var $element = $(element);
-
-      // When the options are in the binding value accessor the data attribute will be used instead of any <select>
-      // tag it's attached to.
-      if (ko.isObservable(valueAccessor().options) && ko.isObservable(valueAccessor().value)) {
-        var optionsObservable = valueAccessor().options;
-        var valueObservable = valueAccessor().value;
-        options.data = $.map(optionsObservable(), function (value) {
-          return { id: value, text: value }
-        });
-        options.val = valueObservable();
-
-        var refreshSelect2Data = function () {
-          $element.select2("data", $.map(optionsObservable(), function (value) {
-            return { id: value, text: value }
-          }));
-          $element.select2("val", valueObservable());
-        };
-
-        valueObservable.subscribe(function (newValue) {
-          if (newValue !== $element.select2("val")) {
-            refreshSelect2Data();
-          }
-        });
-
-        optionsObservable.subscribe(refreshSelect2Data);
-
-        window.setTimeout(function () {
-          refreshSelect2Data();
-        }, 10)
-      }
-
-      if (typeof valueAccessor().vm != "undefined") {
-        viewModel = valueAccessor().vm;
-      }
-
-      if (typeof valueAccessor().update != "undefined") {
-        if (options.type == "user" && viewModel.selectableHadoopUsers().indexOf(options.update) == -1) {
-          viewModel.availableHadoopUsers.push({
-            username: options.update
-          });
-        }
-        if (options.type == "group") {
-          if (options.update instanceof Array) {
-            options.update.forEach(function (opt) {
-              if (viewModel.selectableHadoopGroups().indexOf(opt) == -1) {
-                viewModel.availableHadoopGroups.push({
-                  name: opt
-                });
-              }
-            });
-          }
-          else if (viewModel.selectableHadoopGroups().indexOf(options.update) == -1) {
-            viewModel.availableHadoopGroups.push({
-              name: options.update
-            });
-          }
-        }
-        if (options.type == "action" && viewModel.availableActions().indexOf(options.update) == -1) {
-          viewModel.availableActions.push(options.update);
-        }
-        if (options.type == "scope" && viewModel.availablePrivileges().indexOf(options.update) == -1) {
-          viewModel.availablePrivileges.push(options.update);
-        }
-        if (options.type == "parameter" && options.update != "") {
-          var _found = false;
-          allBindingsAccessor().options().forEach(function(opt){
-            var _option = opt[allBindingsAccessor().optionsValue];
-            if (ko.isObservable(_option)){
-              _option = _option();
-            }
-            if (_option == options.update){
-              _found = true;
-            }
-          });
-          if (!_found){
-            allBindingsAccessor().options.push({
-              name: ko.observable(options.update),
-              value: ko.observable(options.update)
-            });
-          }
-        }
-      }
-      $element
-          .select2(options)
-          .on("change", function (e) {
-            if (typeof e.val != "undefined") {
-              if (typeof valueAccessor().update != "undefined") {
-                valueAccessor().update(e.val);
-              }
-              if (typeof valueAccessor().value != "undefined") {
-                valueAccessor().value(e.val);
-              }
-            }
-          })
-          .on("select2-focus", function (e) {
-            if (typeof options.onFocus != "undefined") {
-              options.onFocus();
-            }
-          })
-          .on("select2-blur", function (e) {
-            if (typeof options.onBlur != "undefined") {
-              options.onBlur();
-            }
-          })
-          .on("select2-open", function () {
-            $(".select2-input").off("keyup").data("type", options.type).on("keyup", function (e) {
-              if (e.keyCode === 13) {
-                var _isArray = options.update instanceof Array;
-                var _newVal = $(this).val();
-                var _type = $(this).data("type");
-                if ($.trim(_newVal) != "") {
-                  if (_type == "user") {
-                    viewModel.availableHadoopUsers.push({
-                      username: _newVal
-                    });
-                  }
-                  if (_type == "group") {
-                    viewModel.availableHadoopGroups.push({
-                      name: _newVal
-                    });
-                  }
-                  if (_type == "action") {
-                    viewModel.availableActions.push(_newVal);
-                  }
-                  if (_type == "scope") {
-                    viewModel.availablePrivileges.push(_newVal);
-                  }
-                  if (_type == "role") {
-                    var _r = new Role(viewModel, { name: _newVal });
-                    viewModel.tempRoles.push(_r);
-                    viewModel.roles.push(_r);
-                  }
-                  if (_type == "parameter") {
-                    var _found = false;
-                    allBindingsAccessor().options().forEach(function(opt){
-                      if (opt[allBindingsAccessor().optionsValue]() == _newVal){
-                        _found = true;
-                      }
-                    });
-                    if (!_found){
-                      allBindingsAccessor().options.push({
-                        name: ko.observable(_newVal),
-                        value: ko.observable(_newVal)
-                      });
-                    }
-                  }
-                  if (_isArray) {
-                    var _vals = $(element).select2("val");
-                    _vals.push(_newVal);
-                    $(element).select2("val", _vals, true);
-                  }
-                  else {
-                    $(element).select2("val", _newVal, true);
-                  }
-                  $(element).select2("close");
-                }
-              }
-            });
-          })
-    },
-    update: function (element, valueAccessor, allBindingsAccessor, vm) {
-      if (typeof allBindingsAccessor().visible != "undefined"){
-        if ((typeof allBindingsAccessor().visible == "boolean" && allBindingsAccessor().visible) || (typeof allBindingsAccessor().visible == "function" && allBindingsAccessor().visible())) {
-          $(element).select2("container").show();
-        }
-        else {
-          $(element).select2("container").hide();
-        }
-      }
-      if (typeof valueAccessor().update != "undefined") {
-        $(element).select2("val", valueAccessor().update());
-      }
-      if (typeof valueAccessor().readonly != "undefined") {
-        $(element).select2("readonly", valueAccessor().readonly);
-        if (typeof valueAccessor().readonlySetTo != "undefined") {
-          valueAccessor().readonlySetTo();
-        }
-      }
-    }
-  };
-
-  ko.bindingHandlers.hivechooser = {
-    init: function (element, valueAccessor, allBindingsAccessor, vm) {
-      var self = $(element);
-      var options = ko.unwrap(valueAccessor());
-      var complexConfiguration = false;
-      if (typeof options === 'function'){
-        self.val(options());
-      } else {
-        if (options && options.data){
-          self.val(options.data);
-          complexConfiguration = true;
-        } else {
-          self.val(options);
-        }
-      }
-
-      if (complexConfiguration) {
-        self.jHueGenericAutocomplete({
-          showOnFocus: true,
-          skipColumns: ko.unwrap(options.skipColumns),
-          skipTables: ko.unwrap(options.skipTables),
-          startingPath: options.database + '.',
-          rewriteVal: true,
-          onPathChange: options.onChange,
-          namespace: ko.unwrap(options.namespace),
-          compute: ko.unwrap(options.compute),
-          searchEverywhere : ko.unwrap(options.searchEverywhere) || false,
-          apiHelperUser: ko.unwrap(options.apiHelperUser) || '',
-          apiHelperType: ko.unwrap(options.apiHelperType) || '',
-          mainScrollable: ko.unwrap(options.mainScrollable) || $(window)
-        });
-      } else {
-        options = allBindingsAccessor();
-        function setPathFromAutocomplete(path) {
-          self.val(path);
-          valueAccessor()(path);
-          self.blur();
-        }
-        self.on("blur", function () {
-          if (!options.skipInvalids) {
-            valueAccessor()(self.val());
-          }
-        });
-        if (allBindingsAccessor().valueUpdate != null && allBindingsAccessor().valueUpdate == "afterkeydown") {
-          self.on("keyup", function () {
-            valueAccessor()(self.val());
-          });
-        }
-        self.jHueGenericAutocomplete({
-          showOnFocus: true,
-          home: "/",
-          skipColumns: ko.unwrap(options.skipColumns) || false,
-          skipTables: ko.unwrap(options.skipTables) || false,
-          namespace: ko.unwrap(options.namespace),
-          compute: ko.unwrap(options.compute),
-          pathChangeLevel: ko.unwrap(options.pathChangeLevel) || '',
-          apiHelperUser: ko.unwrap(options.apiHelperUser) || '',
-          apiHelperType: ko.unwrap(options.apiHelperType) || '',
-          mainScrollable: ko.unwrap(options.mainScrollable) || $(window),
-          onPathChange: function (path) {
-            setPathFromAutocomplete(path);
-          },
-          onEnter: function (el) {
-            if (!options.skipInvalids) {
-              setPathFromAutocomplete(el.val());
-            }
-          },
-          onBlur: function () {
-            if (self.val().lastIndexOf(".") == self.val().length - 1) {
-              self.val(self.val().substr(0, self.val().length - 1));
-            }
-            if (!options.skipInvalids) {
-              valueAccessor()(self.val());
-            }
-          }
-        });
-      }
-
-    }
-  }
-
-  ko.bindingHandlers.solrchooser = {
-    init: function (element, valueAccessor, allBindingsAccessor, vm) {
-      var self = $(element);
-      self.val(valueAccessor()());
-
-      function setPathFromAutocomplete(path) {
-        self.val(path);
-        valueAccessor()(path);
-        self.blur();
-      }
-
-      self.on("blur", function () {
-        valueAccessor()(self.val());
-      });
-
-      self.jHueGenericAutocomplete({
-        showOnFocus: true,
-        home: "/",
-        serverType: "SOLR",
-        skipTables: true, // No notion of DB actually
-        onPathChange: function (path) {
-          setPathFromAutocomplete(path);
-        },
-        onEnter: function (el) {
-          setPathFromAutocomplete(el.val());
-        },
-        onBlur: function () {
-          if (self.val().lastIndexOf(".") == self.val().length - 1) {
-            self.val(self.val().substr(0, self.val().length - 1));
-          }
-          valueAccessor()(self.val());
-        }
-      });
-    }
-  }
-
-  ko.bindingHandlers.hdfsAutocomplete = {
-    init: function (element, valueAccessor, allBindingsAccessor, vm) {
-      var stripHashes = function (str) {
-        return str.replace(/#/gi, encodeURIComponent("#"));
-      };
-
-      var self = $(element);
-      self.attr("autocomplete", "off");
-      self.jHueHdfsAutocomplete({
-        skipKeydownEvents: true,
-        skipScrollEvent: true
-      });
-    }
-  };
-
-  ko.bindingHandlers.filechooser = {
-    init: function (element, valueAccessor, allBindingsAccessor, vm) {
-      var $element = $(element);
-      var options = ko.unwrap(allBindingsAccessor());
-      $element.attr("autocomplete", "off");
-      if (typeof valueAccessor() == "function" || typeof valueAccessor().value == "function") {
-        $element.val(valueAccessor().value ? valueAccessor().value(): valueAccessor()());
-        $element.data("fullPath", $element.val());
-        $element.attr("data-original-title", $element.val());
-        if (valueAccessor().displayJustLastBit){
-          var _val = $element.val();
-          $element.val(_val.split("/")[_val.split("/").length - 1]);
-        }
-        $element.on("blur", function () {
-          if (valueAccessor().value){
-            if (valueAccessor().displayJustLastBit){
-              var _val = $element.data("fullPath");
-              valueAccessor().value(_val.substr(0, _val.lastIndexOf("/")) + "/" + $element.val());
-            } else {
-              valueAccessor().value($element.val());
-            }
-            $element.data("fullPath", valueAccessor().value());
-          } else {
-            valueAccessor()($element.val());
-            $element.data("fullPath", valueAccessor()());
-          }
-          $element.attr("data-original-title", $element.data("fullPath"));
-        });
-
-        if (options.valueUpdate && options.valueUpdate === 'afterkeydown') {
-          $element.on('keyup', function () {
-            if (valueAccessor().value){
-              valueAccessor().value($element.val());
-            } else {
-              valueAccessor()($element.val());
-            }
-          });
-        }
-      } else {
-        $element.val(valueAccessor());
-        $element.on("blur", function () {
-          valueAccessor($element.val());
-        });
-        if (options.valueUpdate && options.valueUpdate === 'afterkeydown') {
-          $element.on('keyup', function () {
-            valueAccessor($element.val());
-          });
-        }
-      }
-
-      $element.after(getFileBrowseButton($element, true, valueAccessor, true, allBindingsAccessor, valueAccessor().isAddon, valueAccessor().isNestedModal, allBindingsAccessor && allBindingsAccessor().filechooserOptions && allBindingsAccessor().filechooserOptions.linkMarkup));
-
-      if (allBindingsAccessor && allBindingsAccessor().filechooserOptions && allBindingsAccessor().filechooserOptions.openOnFocus) {
-        $element.on('focus', function () {
-          if ($element.val() === '') {
-            $element.siblings('.filechooser-clickable').click();
-          }
-        });
-      }
-    }
-  };
-
-
-  function getFileBrowseButton(inputElement, selectFolder, valueAccessor, stripHdfsPrefix, allBindingsAccessor, isAddon, isNestedModal, linkMarkup) {
-    var _btn;
-    if (isAddon) {
-      _btn = $("<span>").addClass("add-on muted pointer filechooser-clickable").text("..");
-    } else if (linkMarkup) {
-      _btn = $("<a>").addClass("btn").addClass("fileChooserBtn filechooser-clickable").text("..");
-    } else {
-      _btn = $("<button>").addClass("btn").addClass("fileChooserBtn filechooser-clickable").text("..");
-    }
-    _btn.click(function (e) {
-      e.preventDefault();
-      if (!isNestedModal) {
-        $(HUE_CONTAINER).addClass("modal-open");
-      }
-      // check if it's a relative path
-      callFileChooser();
-
-      function callFileChooser() {
-        var _initialPath = $.trim(inputElement.val()) != "" ? inputElement.val() : "/";
-        if ((allBindingsAccessor && allBindingsAccessor().filechooserOptions && allBindingsAccessor().filechooserOptions.skipInitialPathIfEmpty && inputElement.val() == "") || (allBindingsAccessor && allBindingsAccessor().filechooserPrefixSeparator)) {
-          _initialPath = "";
-        }
-        if (inputElement.data("fullPath")) {
-          _initialPath = inputElement.data("fullPath");
-        }
-        if (_initialPath.indexOf("hdfs://") > -1) {
-          _initialPath = _initialPath.substring(7);
-        }
-
-        var supportSelectFolder = !!selectFolder;
-        if (allBindingsAccessor && typeof allBindingsAccessor().filechooserOptions !== 'undefined' && typeof allBindingsAccessor().filechooserOptions.selectFolder !== 'undefined') {
-          supportSelectFolder = allBindingsAccessor().filechooserOptions.selectFolder;
-        }
-
-        $("#filechooser").jHueFileChooser({
-          suppressErrors: true,
-          selectFolder: supportSelectFolder,
-          onFolderChoose: function (filePath) {
-            handleChoice(filePath, stripHdfsPrefix);
-            if (selectFolder) {
-              $("#chooseFile").modal("hide");
-              if (!isNestedModal) {
-                $(".modal-backdrop").remove();
-              }
-            }
-          },
-          onFileChoose: function (filePath) {
-            handleChoice(filePath, stripHdfsPrefix);
-            $("#chooseFile").modal("hide");
-            if (!isNestedModal) {
-              $(".modal-backdrop").remove();
-            }
-          },
-          createFolder: allBindingsAccessor && allBindingsAccessor().filechooserOptions && allBindingsAccessor().filechooserOptions.createFolder,
-          uploadFile: allBindingsAccessor && allBindingsAccessor().filechooserOptions && allBindingsAccessor().filechooserOptions.uploadFile,
-          initialPath: _initialPath,
-          errorRedirectPath: "",
-          forceRefresh: true,
-          showExtraHome: allBindingsAccessor && allBindingsAccessor().filechooserOptions && allBindingsAccessor().filechooserOptions.showExtraHome,
-          extraHomeProperties: allBindingsAccessor && allBindingsAccessor().filechooserOptions && allBindingsAccessor().filechooserOptions.extraHomeProperties ? allBindingsAccessor().filechooserOptions.extraHomeProperties : {},
-          filterExtensions: allBindingsAccessor && allBindingsAccessor().filechooserFilter ? allBindingsAccessor().filechooserFilter : "",
-          displayOnlyFolders: allBindingsAccessor && allBindingsAccessor().filechooserOptions && allBindingsAccessor().filechooserOptions.displayOnlyFolders
-        });
-        if (isIE11) {
-          var oldFocus = jQuery().modal.Constructor.prototype.enforceFocus;
-          jQuery().modal.Constructor.prototype.enforceFocus = function() {};
-          $("#chooseFile").modal("show");
-          window.setTimeout(function () {
-            jQuery().modal.Constructor.prototype.enforceFocus = oldFocus;
-          }, 5000);
-        } else {
-          $("#chooseFile").modal("show");
-        }
-        if (!isNestedModal) {
-          $("#chooseFile").on("hidden", function () {
-            $(HUE_CONTAINER).removeClass("modal-open");
-            $(".modal-backdrop").remove();
-          });
-        }
-      }
-
-      function handleChoice(filePath, stripHdfsPrefix) {
-        if (allBindingsAccessor && allBindingsAccessor().filechooserPrefixSeparator) {
-          filePath = inputElement.val().split(allBindingsAccessor().filechooserPrefixSeparator)[0] + '=' + filePath;
-        }
-        if (allBindingsAccessor && allBindingsAccessor().filechooserOptions && allBindingsAccessor().filechooserOptions.deploymentDir) {
-          inputElement.data("fullPath", filePath);
-          inputElement.attr("data-original-title", filePath);
-          if (filePath.indexOf(allBindingsAccessor().filechooserOptions.deploymentDir) == 0) {
-            filePath = filePath.substr(allBindingsAccessor().filechooserOptions.deploymentDir.length + 1);
-          }
-        }
-        if (stripHdfsPrefix) {
-          inputElement.val(filePath);
-        }
-        else {
-          inputElement.val("hdfs://" + filePath);
-        }
-        inputElement.change();
-        if (valueAccessor) {
-          if (typeof valueAccessor() == "function" || typeof valueAccessor().value == "function") {
-            if (valueAccessor().value) {
-              valueAccessor().value(inputElement.val());
-              if (valueAccessor().displayJustLastBit) {
-                inputElement.data("fullPath", inputElement.val());
-                inputElement.attr("data-original-title", inputElement.val());
-                var _val = inputElement.val();
-                inputElement.val(_val.split("/")[_val.split("/").length - 1])
-              }
-            }
-            else {
-              valueAccessor()(inputElement.val());
-            }
-          }
-          else {
-            valueAccessor(inputElement.val());
-          }
-        }
-      }
-    });
-    if (allBindingsAccessor && allBindingsAccessor().filechooserDisabled) {
-      _btn.addClass("disabled").attr("disabled", "disabled");
-    }
-    return _btn;
-  }
-
-  window.getFileBrowseButton = getFileBrowseButton;
-
-  ko.bindingHandlers.datepicker = {
-    init: function (element, valueAccessor, allBindings, viewModel, bindingContext) {
-      var _el = $(element);
-      var _options = ko.unwrap(valueAccessor());
-      _el.datepicker({
-        format: "yyyy-mm-dd"
-      }).on("show", function (e) {
-        if (_options.momentFormat) {
-          var m = moment.utc(_el.val());
-          _el.datepicker("setValue", m.format("YYYY-MM-DD"));
-          _el.val(m.format(_options.momentFormat)); // Set value again as datepicker clears the time component
-        }
-      }).on("changeDate", function (e) {
-        setDate(e.date);
-      }).on("hide", function (e) {
-        setDate(e.date);
-      });
-
-      function setDate(d) {
-        if (_options.momentFormat) {
-          var m = moment(d);
-          // Keep time intact
-          var previous = moment.utc(allBindings().value());
-          previous.date(m.date());
-          previous.month(m.month());
-          previous.year(m.year());
-
-          _el.val(previous.format(_options.momentFormat));
-        }
-        allBindings().value(_el.val());
-      }
-    }
-  }
-
-
-  ko.bindingHandlers.timepicker = {
-    init: function (element, valueAccessor, allBindings, viewModel, bindingContext) {
-      var _el = $(element);
-      _el.timepicker({
-        minuteStep: 1,
-        showSeconds: false,
-        showMeridian: false,
-        defaultTime: false
-      });
-    }
-  };
-
-
-  ko.bindingHandlers.textSqueezer = {
-    init: function (element, valueAccessor) {
-      var value = valueAccessor();
-      $(element).text(ko.unwrap(value));
-      $(element).textSqueezer({
-        decimalPrecision: 2
-      });
-    },
-    update: function (element, valueAccessor) {
-      var value = valueAccessor();
-      $(element).text(ko.unwrap(value));
-      $(element).trigger("redraw");
-    }
-  };
-
-
-  ko.toJSONObject = function (koObj) {
-    return JSON.parse(ko.toJSON(koObj));
-  };
-
-  ko.toCleanJSON = function (koObj) {
-    return ko.toJSON(koObj, function (key, value) {
-      if (key == "__ko_mapping__") {
-        return;
-      }
-      else {
-        return value;
-      }
-    });
-  };
-
-
-  ko.bindingHandlers.delayedOverflow = {
-    init: function (element, valueAccessor) {
-      var $element = $(element);
-
-      $element.css("overflow", "hidden");
-
-      var isTouch = false;
-      $element.on('touchstart', function () {
-        isTouch = true;
-      });
-
-      var scrollTimeout = -1;
-      $element.hover(function () {
-        scrollTimeout = window.setTimeout(function () {
-          $element.css("overflow", "auto");
-        }, valueAccessor && valueAccessor() === 'slow' ? 500 : 30);
-      }, function () {
-        if (!isTouch) {
-          clearTimeout(scrollTimeout);
-          $element.css("overflow", "hidden");
-        }
-      });
-    }
-  };
-
-  ko.bindingHandlers.clickForAceFocus = {
-    init: function (element, valueAccessor) {
-      var editor = valueAccessor();
-      $(element).on("click", function(e) {
-        if (e.target === element) {
-          editor().focus();
-          editor().execCommand("gotolineend");
-        }
-      });
-    }
-  };
-
-  // TODO: Move worker logic and location handling out of hue-bindings
-  window.WorkerHandler = (function () {
-    var registered = false;
-
-    var attachEntryResolver = function (location, sourceType, namespace, compute) {
-      location.resolveCatalogEntry = function(options) {
-        if (!options) {
-          options = {};
-        }
-        if (location.resolvePathPromise && !location.resolvePathPromise.cancelled) {
-          dataCatalog.applyCancellable(location.resolvePathPromise, options);
-          return location.resolvePathPromise;
-        }
-
-        if (!location.identifierChain && !location.colRef && !location.colRef.identifierChain) {
-          if (!location.resolvePathPromise) {
-            location.resolvePathPromise = $.Deferred().reject().promise();
-          }
-          return location.resolvePathPromise;
-        }
-
-        var promise = sqlUtils.resolveCatalogEntry({
-          sourceType: sourceType,
-          namespace: namespace,
-          compute: compute,
-          temporaryOnly: options.temporaryOnly,
-          cancellable: options.cancellable,
-          cachedOnly: options.cachedOnly,
-          identifierChain: location.identifierChain || location.colRef.identifierChain,
-          tables: location.tables || (location.colRef && location.colRef.tables)
-        });
-
-        if (!options.cachedOnly) {
-          location.resolvePathPromise = promise;
-        }
-        return promise;
-      }
-    };
-
-    return {
-      registerWorkers: function () {
-        if (!window.IS_EMBEDDED && !registered && window.Worker) {
-          // It can take a while before the worker is active
-          var whenWorkerIsReady = function (worker, message) {
-            if (!worker.isReady) {
-              window.clearTimeout(worker.pingTimeout);
-              worker.postMessage({ ping: true });
-              worker.pingTimeout = window.setTimeout(function () {
-                whenWorkerIsReady(worker, message);
-              }, 500);
-            } else {
-              worker.postMessage(message);
-            }
-          };
-
-          // For syntax checking
-          var aceSqlSyntaxWorker = new Worker('/desktop/workers/aceSqlSyntaxWorker.js?v=' + HUE_VERSION);
-          aceSqlSyntaxWorker.onmessage = function (e) {
-            if (e.data.ping) {
-              aceSqlSyntaxWorker.isReady = true;
-            } else {
-              huePubSub.publish('ace.sql.syntax.worker.message', e);
-            }
-          };
-
-          huePubSub.subscribe('ace.sql.syntax.worker.post', function (message) {
-            whenWorkerIsReady(aceSqlSyntaxWorker, message);
-          });
-
-          // For location marking
-          var aceSqlLocationWorker = new Worker('/desktop/workers/aceSqlLocationWorker.js?v=' + HUE_VERSION);
-          aceSqlLocationWorker.onmessage = function (e) {
-            if (e.data.ping) {
-              aceSqlLocationWorker.isReady = true;
-            } else {
-              if (e.data.locations) {
-                e.data.locations.forEach(function (location) {
-                  attachEntryResolver(location, e.data.sourceType, e.data.namespace, e.data.compute);
-                })
-              }
-              huePubSub.publish('ace.sql.location.worker.message', e);
-            }
-          };
-
-          huePubSub.subscribe('ace.sql.location.worker.post', function (message) {
-            whenWorkerIsReady(aceSqlLocationWorker, message);
-          });
-
-          registered = true;
-        }
-      }
-    }
-
-  })();
-
-
-  window.AceLocationHandler = (function () {
-
-    var STATEMENT_COUNT_AROUND_ACTIVE = 10;
-
-    function AceLocationHandler (options) {
-      var self = this;
-      self.editor = options.editor;
-      self.editorId = options.editorId;
-      self.snippet = options.snippet;
-      self.expandStar = (options.i18n && options.i18n.expandStar) || 'Right-click to expand with columns';
-      self.contextTooltip = (options.i18n && options.i18n.contextTooltip) || 'Right-click for details';
-
-      self.sqlSyntaxWorkerSub = null;
-      self.disposeFunctions = [];
-      self.databaseIndex = {};
-
-      self.attachStatementLocator();
-      self.attachSqlWorker();
-      self.attachGutterHandler();
-      self.attachMouseListeners();
-
-      var updateDatabaseIndex = function (databaseList) {
-        self.databaseIndex = {};
-        databaseList.forEach(function (database) {
-          self.databaseIndex[database.toLowerCase()] = true;
-        })
-      };
-
-      var databaseSub = self.snippet.availableDatabases.subscribe(updateDatabaseIndex);
-
-      self.disposeFunctions.push(function () {
-        databaseSub.dispose();
-      });
-
-      updateDatabaseIndex(self.snippet.availableDatabases());
-    }
-
-    AceLocationHandler.prototype.attachMouseListeners = function () {
-      var self = this;
-
-      var Tooltip = ace.require("ace/tooltip").Tooltip;
-      var AceRange = ace.require('ace/range').Range;
-
-      var contextTooltip = new Tooltip(self.editor.container);
-      var tooltipTimeout = -1;
-      var disableTooltip = false;
-      var lastHoveredToken = null;
-      var activeMarkers = [];
-      var keepLastMarker = false;
-
-      var hideContextTooltip = function () {
-        clearTimeout(tooltipTimeout);
-        contextTooltip.hide();
-      };
-
-      var clearActiveMarkers = function () {
-        hideContextTooltip();
-        while (activeMarkers.length > keepLastMarker ? 1 : 0) {
-          self.editor.session.removeMarker(activeMarkers.shift());
-        }
-      };
-
-      var markLocation = function (parseLocation) {
-        var range;
-        if (parseLocation.type === 'function') {
-          // Todo: Figure out why functions need an extra char at the end
-          range = new AceRange(parseLocation.location.first_line - 1, parseLocation.location.first_column - 1, parseLocation.location.last_line - 1, parseLocation.location.last_column);
-        } else {
-          range = new AceRange(parseLocation.location.first_line - 1, parseLocation.location.first_column - 1, parseLocation.location.last_line - 1, parseLocation.location.last_column - 1);
-        }
-        activeMarkers.push(self.editor.session.addMarker(range, 'hue-ace-location'));
-        return range;
-      };
-
-      var popoverShownSub = huePubSub.subscribe('context.popover.shown', function () {
-        hideContextTooltip();
-        keepLastMarker = true;
-        disableTooltip = true;
-      });
-
-      self.disposeFunctions.push(function () {
-        popoverShownSub.remove();
-      });
-
-      var popoverHiddenSub = huePubSub.subscribe('context.popover.hidden', function () {
-        disableTooltip = false;
-        clearActiveMarkers();
-        keepLastMarker = false;
-      });
-
-      self.disposeFunctions.push(function () {
-        popoverHiddenSub.remove();
-      });
-
-      var mousemoveListener = self.editor.on('mousemove', function (e) {
-        clearTimeout(tooltipTimeout);
-        var selectionRange = self.editor.selection.getRange();
-        if (selectionRange.isEmpty()) {
-          var pointerPosition = self.editor.renderer.screenToTextCoordinates(e.clientX + 5, e.clientY);
-          var endTestPosition = self.editor.renderer.screenToTextCoordinates(e.clientX + 15, e.clientY);
-          if (endTestPosition.column !== pointerPosition.column) {
-            var token = self.editor.session.getTokenAt(pointerPosition.row, pointerPosition.column);
-            if (token !== null && !token.notFound && token.parseLocation && !disableTooltip && token.parseLocation.type !== 'alias') {
-              tooltipTimeout = window.setTimeout(function () {
-                if (token.parseLocation) {
-                  var endCoordinates = self.editor.renderer.textToScreenCoordinates(pointerPosition.row, token.start);
-
-                  var tooltipText = token.parseLocation.type === 'asterisk' ? self.expandStar : self.contextTooltip;
-                  var colType;
-                  if (token.parseLocation.type === 'column') {
-                    var tableChain = token.parseLocation.identifierChain.concat();
-                    var lastIdentifier = tableChain.pop();
-                    if (tableChain.length > 0 && lastIdentifier && lastIdentifier.name) {
-                      var colName = lastIdentifier.name.toLowerCase();
-                      // Note, as cachedOnly is set to true it will call the successCallback right away (or not at all)
-                      dataCatalog.getEntry({
-                        sourceType: self.snippet.type(),
-                        namespace: self.snippet.namespace(),
-                        compute: self.snippet.compute(),
-                        temporaryOnly: self.snippet.autocompleteSettings.temporaryOnly,
-                        path: $.map(tableChain, function (identifier) { return identifier.name })
-                      }).done(function (entry) {
-                        entry.getSourceMeta({ cachedOnly: true, silenceErrors: true }).done(function (sourceMeta) {
-                          if (sourceMeta && sourceMeta.extended_columns) {
-                            sourceMeta.extended_columns.every(function (col) {
-                              if (col.name.toLowerCase() === colName) {
-                                colType = col.type.match(/^[^<]*/g)[0];
-                                return false;
-                              }
-                              return true;
-                            })
-                          }
-                        });
-                      });
-                    }
-                  }
-                  if (token.parseLocation.identifierChain) {
-                    var sqlIdentifier = $.map(token.parseLocation.identifierChain, function (identifier) {
-                      return identifier.name
-                    }).join('.');
-                    if (colType) {
-                      sqlIdentifier += ' (' + colType + ')';
-                    }
-                    tooltipText = sqlIdentifier + ' - ' + tooltipText;
-                  } else if (token.parseLocation.function) {
-                    tooltipText = token.parseLocation.function + ' - ' + tooltipText;
-                  }
-                  contextTooltip.show(tooltipText, endCoordinates.pageX, endCoordinates.pageY + self.editor.renderer.lineHeight + 3);
-                }
-              }, 500);
-            } else if (token !== null && token.notFound) {
-              tooltipTimeout = window.setTimeout(function () {
-                // TODO: i18n
-                if (token.notFound && token.syntaxError) {
-                  var tooltipText;
-                  if (token.syntaxError.expected.length > 0) {
-                    tooltipText = HUE_I18n.syntaxChecker.didYouMean + ' "' + token.syntaxError.expected[0].text + '"?';
-                  } else {
-                    tooltipText = HUE_I18n.syntaxChecker.couldNotFind + ' "' + (token.qualifiedIdentifier || token.value) + '"';
-                  }
-                  var endCoordinates = self.editor.renderer.textToScreenCoordinates(pointerPosition.row, token.start);
-                  contextTooltip.show(tooltipText, endCoordinates.pageX, endCoordinates.pageY + self.editor.renderer.lineHeight + 3);
-                }
-              }, 500);
-            } else if (token !== null && token.syntaxError) {
-              tooltipTimeout = window.setTimeout(function () {
-                if (token.syntaxError) {
-                  var tooltipText;
-                  if (token.syntaxError.expected.length > 0) {
-                    tooltipText = HUE_I18n.syntaxChecker.didYouMean + ' "' + token.syntaxError.expected[0].text + '"?';
-                  } else if (token.syntaxError.expectedStatementEnd) {
-                    tooltipText = HUE_I18n.syntaxChecker.expectedStatementEnd;
-                  }
-                  if (tooltipText) {
-                    var endCoordinates = self.editor.renderer.textToScreenCoordinates(pointerPosition.row, token.start);
-                    contextTooltip.show(tooltipText, endCoordinates.pageX, endCoordinates.pageY + self.editor.renderer.lineHeight + 3);
-                  }
-                }
-              }, 500);
-            } else {
-              hideContextTooltip();
-            }
-            if (lastHoveredToken !== token) {
-              clearActiveMarkers();
-              if (token !== null && !token.notFound && token.parseLocation && ['alias', 'whereClause', 'limitClause', 'selectList'].indexOf(token.parseLocation.type) === -1) {
-                markLocation(token.parseLocation);
-              }
-              lastHoveredToken = token;
-            }
-          } else {
-            clearActiveMarkers();
-            lastHoveredToken = null;
-          }
-        }
-      });
-
-      self.disposeFunctions.push(function () {
-        self.editor.off('mousemove', mousemoveListener);
-      });
-
-      var inputListener = self.editor.on('input', function (e) {
-        clearActiveMarkers();
-        lastHoveredToken = null;
-      });
-
-      self.disposeFunctions.push(function () {
-        self.editor.off('input', inputListener);
-      });
-
-      var mouseoutListener = function (e) {
-        clearActiveMarkers();
-        clearTimeout(tooltipTimeout);
-        contextTooltip.hide();
-        lastHoveredToken = null;
-      };
-
-      self.editor.container.addEventListener('mouseout', mouseoutListener);
-
-      self.disposeFunctions.push(function () {
-        self.editor.container.removeEventListener('mouseout', mouseoutListener);
-      });
-
-      var onContextMenu = function (e) {
-        var selectionRange = self.editor.selection.getRange();
-        huePubSub.publish('context.popover.hide');
-        huePubSub.publish('sql.syntax.dropdown.hide');
-        if (selectionRange.isEmpty()) {
-          var pointerPosition = self.editor.renderer.screenToTextCoordinates(e.clientX + 5, e.clientY);
-          var token = self.editor.session.getTokenAt(pointerPosition.row, pointerPosition.column);
-          if (token && ((token.parseLocation && ['alias', 'whereClause', 'limitClause', 'selectList'].indexOf(token.parseLocation.type) === -1) || token.syntaxError)) {
-            var range = token.parseLocation ? markLocation(token.parseLocation) : new AceRange(token.syntaxError.loc.first_line - 1, token.syntaxError.loc.first_column, token.syntaxError.loc.last_line - 1, token.syntaxError.loc.first_column + token.syntaxError.text.length);
-            var startCoordinates = self.editor.renderer.textToScreenCoordinates(range.start.row, range.start.column);
-            var endCoordinates = self.editor.renderer.textToScreenCoordinates(range.end.row, range.end.column);
-            var source = {
-              // TODO: add element likely in the event
-              left: startCoordinates.pageX - 3,
-              top: startCoordinates.pageY,
-              right: endCoordinates.pageX - 3,
-              bottom: endCoordinates.pageY + self.editor.renderer.lineHeight
-            };
-
-            if (token.parseLocation && token.parseLocation.identifierChain && !token.notFound) {
-              token.parseLocation.resolveCatalogEntry({
-                temporaryOnly: self.snippet.autocompleteSettings.temporaryOnly
-              }).done(function (entry) {
-                huePubSub.publish('context.popover.show', {
-                  data: {
-                    type: 'catalogEntry',
-                    catalogEntry: entry
-                  },
-                  pinEnabled: true,
-                  source: source
-                });
-              }).fail(function () {
-                token.notFound = true;
-              });
-            } else if (token.parseLocation && !token.notFound) {
-              // Asterisk, function etc.
-              if (token.parseLocation.type === 'file') {
-                AssistStorageEntry.getEntry(token.parseLocation.path).done(function (entry) {
-                  entry.open(true);
-                  huePubSub.publish('context.popover.show', {
-                    data: {
-                      type: 'storageEntry',
-                      storageEntry: entry,
-                      editorLocation: token.parseLocation.location
-                    },
-                    pinEnabled: true,
-                    source: source
-                  });
-                });
-              } else {
-                huePubSub.publish('context.popover.show', {
-                  data: token.parseLocation,
-                  sourceType: self.snippet.type(),
-                  namespace: self.snippet.namespace(),
-                  compute: self.snippet.compute(),
-                  defaultDatabase: self.snippet.database(),
-                  pinEnabled: true,
-                  source: source
-                });
-              }
-            } else if (token.syntaxError) {
-              huePubSub.publish('sql.syntax.dropdown.show', {
-                snippet: self.snippet,
-                data: token.syntaxError,
-                editor: self.editor,
-                range: range,
-                sourceType: self.snippet.type(),
-                defaultDatabase: self.snippet.database(),
-                source: source
-              });
-            }
-            e.preventDefault();
-            return false;
-          }
-        }
-      };
-
-      var contextmenuListener = self.editor.container.addEventListener('contextmenu', onContextMenu);
-
-      self.disposeFunctions.push(function () {
-        self.editor.container.removeEventListener('contextmenu', contextmenuListener);
-      });
-    };
-
-    AceLocationHandler.prototype.attachGutterHandler = function () {
-      var self = this;
-      var lastMarkedGutterLines = [];
-
-      var changedSubscription = huePubSub.subscribe('editor.active.statement.changed', function (statementDetails) {
-        if (statementDetails.id !== self.editorId || !statementDetails.activeStatement) {
-          return;
-        }
-        var leadingEmptyLineCount = 0;
-        var leadingWhiteSpace = statementDetails.activeStatement.statement.match(/^\s+/);
-        if (leadingWhiteSpace) {
-          var lineBreakMatch = leadingWhiteSpace[0].match(/(\r\n)|(\n)|(\r)/g);
-          if (lineBreakMatch) {
-            leadingEmptyLineCount = lineBreakMatch.length;
-          }
-        }
-
-        while(lastMarkedGutterLines.length) {
-          self.editor.getSession().removeGutterDecoration(lastMarkedGutterLines.shift(), 'ace-active-gutter-decoration');
-        }
-        for (var line = statementDetails.activeStatement.location.first_line - 1 + leadingEmptyLineCount; line < statementDetails.activeStatement.location.last_line; line++) {
-          lastMarkedGutterLines.push(line);
-          self.editor.getSession().addGutterDecoration(line, 'ace-active-gutter-decoration');
-        }
-      });
-
-      self.disposeFunctions.push(function () {
-        changedSubscription.remove();
-      });
-    };
-
-    AceLocationHandler.prototype.attachStatementLocator = function () {
-      var self = this;
-      var lastKnownStatements = [];
-      var activeStatement;
-
-      var isPointInside = function (parseLocation, editorPosition) {
-        var row = editorPosition.row + 1; // ace positioning has 0 based rows while the parser has 1
-        var column = editorPosition.column;
-        return (parseLocation.first_line < row && row < parseLocation.last_line) ||
-          (parseLocation.first_line === row && row === parseLocation.last_line && parseLocation.first_column <= column && column < parseLocation.last_column) ||
-          (parseLocation.first_line === row && row < parseLocation.last_line && column >= parseLocation.first_column) ||
-          (parseLocation.first_line < row && row === parseLocation.last_line && column < parseLocation.last_column);
-      };
-
-      var lastExecutingStatement = null;
-      var updateActiveStatement = function (cursorChange) {
-        if (!self.snippet.isSqlDialect()) {
-          return;
-        }
-        var selectionRange = self.editor.getSelectionRange();
-        var editorLocation = selectionRange.start;
-        if (selectionRange.start.row !== selectionRange.end.row || selectionRange.start.column !== selectionRange.end.column) {
-          if (!cursorChange && self.snippet.result && self.snippet.result.statement_range()) {
-            var executingStatement = self.snippet.result.statement_range();
-            // Row and col are 0 for both start and end on execute, so if the selection hasn't changed we'll use last known executed statement
-            if (executingStatement.start.row === 0 && executingStatement.start.column === 0 && executingStatement.end.row === 0 && executingStatement.end.column === 0 && lastExecutingStatement) {
-              executingStatement = lastExecutingStatement;
-            }
-            if (executingStatement.start.row === 0) {
-              editorLocation.column += executingStatement.start.column;
-            } else if (executingStatement.start.row !== 0 || executingStatement.start.column !== 0) {
-              editorLocation.row += executingStatement.start.row;
-              editorLocation.column = executingStatement.start.column;
-            }
-            lastExecutingStatement = executingStatement;
-          } else  {
-            lastExecutingStatement = null;
-          }
-        }
-
-        if (cursorChange && activeStatement) {
-          // Don't update when cursor stays in the same statement
-          if (isPointInside(activeStatement.location, editorLocation)) {
-            return;
-          }
-        }
-        var precedingStatements = [];
-        var followingStatements = [];
-        activeStatement = null;
-
-        var found = false;
-        var statementIndex = 0;
-        if (lastKnownStatements.length === 1) {
-          activeStatement = lastKnownStatements[0];
-        } else {
-          lastKnownStatements.forEach(function (statement) {
-            if (isPointInside(statement.location, editorLocation)) {
-              statementIndex++;
-              found = true;
-              activeStatement = statement;
-            } else if (!found) {
-              statementIndex++;
-              if (precedingStatements.length === STATEMENT_COUNT_AROUND_ACTIVE) {
-                precedingStatements.shift();
-              }
-              precedingStatements.push(statement);
-            } else if (found && followingStatements.length < STATEMENT_COUNT_AROUND_ACTIVE) {
-              followingStatements.push(statement);
-            }
-          });
-
-          // Can happen if multiple statements and the cursor is after the last one
-          if (!found) {
-            precedingStatements.pop();
-            activeStatement = lastKnownStatements[lastKnownStatements.length - 1];
-          }
-        }
-
-        huePubSub.publish('editor.active.statement.changed', {
-          id: self.editorId,
-          editorChangeTime: lastKnownStatements.editorChangeTime,
-          activeStatementIndex: statementIndex,
-          totalStatementCount: lastKnownStatements.length,
-          precedingStatements: precedingStatements,
-          activeStatement: activeStatement,
-          followingStatements: followingStatements
-        });
-
-        if (activeStatement) {
-          self.checkForSyntaxErrors(activeStatement.location, editorLocation);
-        }
-      };
-
-      var parseForStatements = function () {
-        if (self.snippet.isSqlDialect()) {
-          try {
-            var lastChangeTime = self.editor.lastChangeTime;
-            lastKnownStatements = sqlStatementsParser.parse(self.editor.getValue());
-            lastKnownStatements.editorChangeTime = lastChangeTime;
-
-            if (typeof hueDebug !== 'undefined' && hueDebug.logStatementLocations) {
-              console.log(lastKnownStatements);
-            }
-          } catch (error) {
-            console.warn('Could not parse statements!');
-            console.warn(error);
-          }
-        }
-      };
-
-      var changeThrottle = window.setTimeout(parseForStatements, 0);
-      var updateThrottle = window.setTimeout(updateActiveStatement, 0);
-      var cursorChangePaused = false; // On change the cursor is also moved, this limits the calls while typing
-
-      var lastStart;
-      var lastCursorPosition;
-      var changeSelectionListener = self.editor.on('changeSelection', function () {
-        if (cursorChangePaused) {
-          return;
-        }
-        window.clearTimeout(changeThrottle);
-        changeThrottle = window.setTimeout(function () {
-          var newCursorPosition = self.editor.getCursorPosition();
-          if (!lastCursorPosition || lastCursorPosition.row !== newCursorPosition.row || lastCursorPosition.column !== newCursorPosition.column) {
-            self.snippet.aceCursorPosition(newCursorPosition);
-            lastCursorPosition = newCursorPosition;
-          }
-
-          // The active statement is initially the top one in the selection, batch execution updates this.
-          var newStart = self.editor.getSelectionRange().start;
-          if (self.snippet.isSqlDialect() && (!lastStart || lastStart.row !== newStart.row || lastStart.column !== newStart.column)) {
-            window.clearTimeout(updateThrottle);
-            updateActiveStatement(true);
-            lastStart = newStart;
-          }
-        }, 100);
-      });
-
-      var changeListener = self.editor.on('change', function () {
-        if (self.snippet.isSqlDialect()) {
-          window.clearTimeout(changeThrottle);
-          cursorChangePaused = true;
-          changeThrottle = window.setTimeout(function () {
-            window.clearTimeout(updateThrottle);
-            parseForStatements();
-            updateActiveStatement();
-            cursorChangePaused = false;
-          }, 500);
-          self.editor.lastChangeTime = Date.now();
-        }
-      });
-
-      var locateSubscription = huePubSub.subscribe('editor.refresh.statement.locations', function (snippet) {
-        if (snippet === self.snippet) {
-          cursorChangePaused = true;
-          window.clearTimeout(changeThrottle);
-          window.clearTimeout(updateThrottle);
-          parseForStatements();
-          updateActiveStatement();
-          cursorChangePaused = false;
-        }
-      });
-
-      self.disposeFunctions.push(function () {
-        window.clearTimeout(changeThrottle);
-        window.clearTimeout(updateThrottle);
-        self.editor.off('changeSelection', changeSelectionListener);
-        self.editor.off('change', changeListener);
-        locateSubscription.remove();
-      });
-    };
-
-    AceLocationHandler.prototype.clearMarkedErrors = function (type) {
-      var self = this;
-      for (var marker in self.editor.getSession().$backMarkers) {
-        if (self.editor.getSession().$backMarkers[marker].clazz.indexOf('hue-ace-syntax-' + (type || '')) === 0) {
-          self.editor.getSession().$backMarkers[marker].dispose()
-        }
-      }
-    };
-
-    AceLocationHandler.prototype.checkForSyntaxErrors = function (statementLocation, cursorPosition) {
-      var self = this;
-      if (self.sqlSyntaxWorkerSub !== null && (self.snippet.type() === 'impala' || self.snippet.type() === 'hive'))  {
-        var AceRange = ace.require('ace/range').Range;
-        var editorChangeTime = self.editor.lastChangeTime;
-        var beforeCursor = self.editor.getSession().getTextRange(new AceRange(statementLocation.first_line - 1, statementLocation.first_column, cursorPosition.row, cursorPosition.column));
-        var afterCursor = self.editor.getSession().getTextRange(new AceRange(cursorPosition.row, cursorPosition.column, statementLocation.last_line - 1, statementLocation.last_column));
-        huePubSub.publish('ace.sql.syntax.worker.post', {
-          id: self.snippet.id(),
-          editorChangeTime: editorChangeTime,
-          beforeCursor: beforeCursor,
-          afterCursor: afterCursor,
-          statementLocation: statementLocation,
-          type: self.snippet.type()
-        });
-      }
-    };
-
-    AceLocationHandler.prototype.addAnchoredMarker = function (range, token, clazz) {
-      var self = this;
-      range.start = self.editor.getSession().doc.createAnchor(range.start);
-      range.end = self.editor.getSession().doc.createAnchor(range.end);
-      var markerId = self.editor.getSession().addMarker(range, clazz);
-      var marker = self.editor.getSession().$backMarkers[markerId];
-      marker.token = token;
-      marker.dispose = function () {
-        range.start.detach();
-        range.end.detach();
-        delete marker.token.syntaxError;
-        delete marker.token.notFound;
-        self.editor.getSession().removeMarker(markerId);
-      }
-    };
-
-    AceLocationHandler.prototype.attachSqlSyntaxWorker = function () {
-      var self = this;
-
-      if (self.sqlSyntaxWorkerSub !== null) {
-        return;
-      }
-
-      self.sqlSyntaxWorkerSub = huePubSub.subscribe('ace.sql.syntax.worker.message', function (e) {
-        if (e.data.id !== self.snippet.id() || e.data.editorChangeTime !== self.editor.lastChangeTime) {
-          return;
-        }
-        self.clearMarkedErrors('error');
-
-        if (!e.data.syntaxError || !e.data.syntaxError.expected || e.data.syntaxError.expected.length === 0) {
-          // Only show errors that we have suggestions for
-          return;
-        }
-
-        var suppressedRules = window.apiHelper.getFromTotalStorage('hue.syntax.checker', 'suppressedRules', {});
-        if (e.data.syntaxError && e.data.syntaxError.ruleId && !suppressedRules[e.data.syntaxError.ruleId.toString() + e.data.syntaxError.text.toLowerCase()]) {
-          if (self.snippet.positionStatement() && sqlUtils.locationEquals(e.data.statementLocation, self.snippet.positionStatement().location)) {
-            self.snippet.positionStatement().syntaxError = true;
-          }
-          if (hueDebug.showSyntaxParseResult) {
-            console.log(e.data.syntaxError);
-          }
-
-          var token = self.editor.getSession().getTokenAt(e.data.syntaxError.loc.first_line - 1, e.data.syntaxError.loc.first_column + 1);
-
-          // Don't mark the current edited word as an error if the cursor is at the end of the word
-          // For now [a-z] is fine as we only check syntax for keywords
-          if (/[a-z]$/i.test(self.editor.getTextBeforeCursor()) && !/^[a-z]/i.test(self.editor.getTextAfterCursor())) {
-            var cursorPos = self.editor.getCursorPosition();
-            var cursorToken = self.editor.getSession().getTokenAt(cursorPos.row, cursorPos.column);
-            if (cursorToken === token) {
-              return;
-            }
-          }
-
-          // If no token is found it likely means that the parser response came back after the text was changed,
-          // at which point it will trigger another parse so we can ignore this.
-          if (token) {
-            token.syntaxError = e.data.syntaxError;
-            var AceRange = ace.require('ace/range').Range;
-            var range = new AceRange(e.data.syntaxError.loc.first_line - 1, e.data.syntaxError.loc.first_column, e.data.syntaxError.loc.last_line - 1, e.data.syntaxError.loc.first_column + e.data.syntaxError.text.length);
-            self.addAnchoredMarker(range,  token, 'hue-ace-syntax-error');
-          }
-        }
-      });
-
-      huePubSub.publish('editor.refresh.statement.locations', self.snippet);
-    };
-
-    AceLocationHandler.prototype.detachSqlSyntaxWorker = function () {
-      var self = this;
-      if (self.sqlSyntaxWorkerSub !== null) {
-        self.sqlSyntaxWorkerSub.remove();
-        self.sqlSyntaxWorkerSub = null;
-      }
-      self.clearMarkedErrors();
-    };
-
-    AceLocationHandler.prototype.fetchChildren = function (identifierChain) {
-      var self = this;
-      var deferred = $.Deferred();
-      dataCatalog.getChildren({
-        sourceType: self.snippet.type(),
-        namespace: self.snippet.namespace(),
-        compute: self.snippet.compute(),
-        temporaryOnly: self.snippet.autocompleteSettings.temporaryOnly,
-        path: $.map(identifierChain, function (identifier) { return identifier.name }),
-        silenceErrors: true,
-        cachedOnly: true
-      }).done(deferred.resolve).fail(function () {
-        deferred.reject([]);
-      });
-      return deferred;
-    };
-
-    AceLocationHandler.prototype.fetchPossibleValues = function (token) {
-      var self = this;
-      var promise = $.Deferred();
-      if (token.parseLocation.tables && token.parseLocation.tables.length > 0) {
-        var tablePromises = [];
-        token.parseLocation.tables.forEach(function (table) {
-          if (table.identifierChain) {
-            tablePromises.push(self.fetchChildren(table.identifierChain));
-          }
-        });
-        $.when.apply($, tablePromises).done(function () {
-          var joined = [];
-          for (var i = 0; i < arguments.length; i++) {
-            joined = joined.concat(arguments[i]);
-          }
-          if (token.parseLocation.type === 'column') {
-            // Could be a table reference
-            token.parseLocation.tables.forEach(function (table) {
-              if (!table.alias) {
-                // Aliases are added later
-                joined.push(table.identifierChain[table.identifierChain.length - 1]);
-              }
-            });
-          }
-          promise.resolve(joined);
-        }).fail(promise.reject);
-      } else if (token.parseLocation.identifierChain && token.parseLocation.identifierChain.length > 0) {
-        // fetch the parent
-        return self.fetchChildren(token.parseLocation.identifierChain.slice(0, token.parseLocation.identifierChain.length - 1));
-      } else {
-        promise.reject([]);
-      }
-      return promise;
-    };
-
-    var VERIFY_LIMIT = 50;
-    var VERIFY_DELAY = 50;
-
-    var verifyThrottle = -1;
-
-    AceLocationHandler.prototype.verifyExists = function (tokens, allLocations) {
-      var self = this;
-      window.clearInterval(verifyThrottle);
-      self.clearMarkedErrors('warning');
-
-      if (self.sqlSyntaxWorkerSub === null) {
-        return;
-      }
-
-      var cursorPos = self.editor.getCursorPosition();
-
-      var tokensToVerify = tokens.filter(function (token) {
-        return token && token.parseLocation
-          && (token.parseLocation.type === 'table' || token.parseLocation.type === 'column')
-          && (token.parseLocation.identifierChain || token.parseLocation.tables)
-          && !(cursorPos.row + 1 === token.parseLocation.location.last_line && cursorPos.column + 1 === token.parseLocation.location.first_column + token.value.length)
-      }).slice(0, VERIFY_LIMIT);
-
-      if (tokensToVerify.length === 0) {
-        return;
-      }
-
-      var aliasIndex = {};
-      var aliases = [];
-
-      allLocations.forEach(function (location) {
-        if (location.type === 'alias' && (location.source === 'column' || location.source === 'table' || location.source === 'subquery' || location.source === 'cte')) {
-          aliasIndex[location.alias.toLowerCase()] = location;
-          aliases.push({ name: location.alias.toLowerCase() })
-        }
-      });
-
-      var resolvePathFromTables = function (location) {
-        var promise = $.Deferred();
-        if (location.type === 'column' && typeof location.tables !== 'undefined' && location.identifierChain.length === 1) {
-          var findIdentifierChainInTable = function (tablesToGo) {
-            var nextTable = tablesToGo.shift();
-            if (typeof nextTable.subQuery === 'undefined') {
-              dataCatalog.getChildren({
-                sourceType: self.snippet.type(),
-                namespace: self.snippet.namespace(),
-                compute: self.snippet.compute(),
-                temporaryOnly: self.snippet.autocompleteSettings.temporaryOnly,
-                path: $.map(nextTable.identifierChain, function (identifier) { return identifier.name }),
-                cachedOnly: true,
-                silenceErrors: true
-              }).done(function (entries) {
-                var containsColumn = entries.some(function (entry) {
-                  return sqlUtils.identifierEquals(entry.name, location.identifierChain[0].name);
-                });
-
-                if (containsColumn) {
-                  location.identifierChain = nextTable.identifierChain.concat(location.identifierChain);
-                  delete location.tables;
-                  promise.resolve();
-                } else if (tablesToGo.length > 0) {
-                  findIdentifierChainInTable(tablesToGo);
-                } else {
-                  promise.resolve();
-                }
-              }).fail(promise.resolve);
-            } else if (tablesToGo.length > 0) {
-              findIdentifierChainInTable(tablesToGo);
-            } else {
-              promise.resolve();
-            }
-          };
-          if (location.tables.length > 1) {
-            findIdentifierChainInTable(location.tables.concat());
-          } else if (location.tables.length === 1 && location.tables[0].identifierChain) {
-            location.identifierChain = location.tables[0].identifierChain.concat(location.identifierChain);
-            delete location.tables;
-            promise.resolve();
-          }
-        } else {
-          promise.resolve();
-        }
-        return promise;
-      };
-
-      var verify = function () {
-        if (tokensToVerify.length === 0) {
-          return;
-        }
-        var token = tokensToVerify.shift();
-        var location = token.parseLocation;
-
-        // TODO: Verify columns in subqueries, i.e. 'code' in 'select code from (select * from web_logs) wl, customers c;'
-        if ((location.type === 'column' || location.type === 'complex') && location.tables) {
-          var hasSubQueries = location.tables.some(function (table) {
-            return typeof table.subQuery !== 'undefined';
-          });
-          if (hasSubQueries) {
-            verifyThrottle = window.setTimeout(verify, VERIFY_DELAY);
-            return;
-          }
-        }
-
-        resolvePathFromTables(location).done(function () {
-          if (location.type === 'column') {
-            var possibleAlias;
-            if (!location.tables && location.identifierChain && location.identifierChain.length > 1) {
-              possibleAlias = aliasIndex[token.parseLocation.identifierChain[0].name.toLowerCase()];
-            } else if (location.tables) {
-              location.tables.some(function (table) {
-                if (table.identifierChain && table.identifierChain.length === 1 && table.identifierChain[0].name) {
-                  possibleAlias = aliasIndex[table.identifierChain[0].name.toLowerCase()];
-                  return possibleAlias;
-                }
-                return false;
-              });
-            }
-            if (possibleAlias && possibleAlias.source === 'cte') {
-              // We currently don't discover the columns from a CTE so we can't say if a column exists or not
-              verifyThrottle = window.setTimeout(verify, VERIFY_DELAY);
-              return;
-            }
-          }
-
-          self.fetchPossibleValues(token).done(function (possibleValues) {
-            // Tokens might change while making api calls
-            if (!token.parseLocation) {
-              verifyThrottle = window.setTimeout(verify, VERIFY_DELAY);
-              return;
-            }
-
-            // Append aliases unless qualified i.e.for 'b' in SELECT a.b we shouldn't suggest aliases
-            if ((token.parseLocation.type !== 'column' && token.parseLocation.type !== 'complex') || !token.parseLocation.qualified) {
-              possibleValues = possibleValues.concat(aliases);
-            }
-
-            var tokenValLower = token.actualValue.toLowerCase();
-            var uniqueIndex = {};
-            var uniqueValues = [];
-            for (var i = 0; i < possibleValues.length; i++) {
-              possibleValues[i].name = sqlUtils.backTickIfNeeded(self.snippet.type(), possibleValues[i].name);
-              var nameLower = possibleValues[i].name.toLowerCase();
-              if ((nameLower === tokenValLower) || (tokenValLower.indexOf('`') === 0 && tokenValLower.replace(/`/g, '') === nameLower)) {
-                // Break if found
-                verifyThrottle = window.setTimeout(verify, VERIFY_DELAY);
-                return;
-              }
-              if (!uniqueIndex[nameLower]) {
-                uniqueValues.push(possibleValues[i]);
-                uniqueIndex[nameLower] = true;
-              }
-            }
-            possibleValues = uniqueValues;
-
-            var isLowerCase = tokenValLower === token.value;
-
-            var weightedExpected = $.map(possibleValues, function (val) {
-              return {
-                text: isLowerCase ? val.name.toLowerCase() : val.name,
-                distance: SqlParseSupport.stringDistance(token.value, val.name)
-              }
-            });
-            weightedExpected.sort(function (a, b) {
-              if (a.distance === b.distance) {
-                return a.text.localeCompare(b.text);
-              }
-              return a.distance - b.distance
-            });
-            token.syntaxError = {
-              expected: weightedExpected.slice(0, 50)
-            };
-            token.notFound = true;
-
-            if (token.parseLocation && token.parseLocation.type === 'table') {
-              var path = $.map(token.parseLocation.identifierChain, function (identifier) { return identifier.name; });
-              token.qualifiedIdentifier = path.join('.');
-            }
-
-            if (token.parseLocation && weightedExpected.length > 0) {
-              var AceRange = ace.require('ace/range').Range;
-              var range = new AceRange(token.parseLocation.location.first_line - 1, token.parseLocation.location.first_column - 1, token.parseLocation.location.last_line - 1, token.parseLocation.location.last_column - 1);
-              self.addAnchoredMarker(range,  token, 'hue-ace-syntax-warning');
-            }
-            verifyThrottle = window.setTimeout(verify, VERIFY_DELAY);
-          }).fail(function () {
-            // Can happen when tables aren't cached etc.
-            verifyThrottle = window.setTimeout(verify, VERIFY_DELAY);
-          });
-        }).fail(function () {
-          // Can happen when tables aren't cached etc.
-          verifyThrottle = window.setTimeout(verify, VERIFY_DELAY);
-        });
-      };
-
-      verifyThrottle = window.setTimeout(verify, VERIFY_DELAY);
-    };
-
-    AceLocationHandler.prototype.isDatabase = function (databaseIdentifier) {
-      var self = this;
-      if (!databaseIdentifier) {
-        return false;
-      }
-      var cleanIdentifier = databaseIdentifier.replace(/^\s*`/, '').replace(/`\s*$/, '').toLowerCase();
-      return self.databaseIndex[cleanIdentifier];
-    };
-
-    AceLocationHandler.prototype.attachSqlWorker = function () {
-      var self = this;
-
-      var activeTokens = [];
-
-      var lastKnownLocations = {};
-
-      var getLocationsSub = huePubSub.subscribe('get.active.editor.locations', function (callback, snippet) {
-        if (self.snippet === snippet && (self.snippet.inFocus() || self.snippet.editorMode())) {
-          callback(lastKnownLocations);
-        }
-      });
-
-      self.disposeFunctions.push(function () {
-        getLocationsSub.remove();
-      });
-
-      var locationWorkerSub = huePubSub.subscribe('ace.sql.location.worker.message', function (e) {
-        if (e.data.id !== self.snippet.id() || e.data.editorChangeTime !== self.editor.lastChangeTime || !self.snippet.isSqlDialect()) {
-          return;
-        }
-
-        lastKnownLocations = {
-          id: self.editorId,
-          type: self.snippet.type(),
-          namespace: self.snippet.namespace(),
-          compute: self.snippet.compute(),
-          defaultDatabase: self.snippet.database(),
-          locations: e.data.locations,
-          editorChangeTime: e.data.editorChangeTime,
-          activeStatementLocations: e.data.activeStatementLocations,
-          totalStatementCount: e.data.totalStatementCount,
-          activeStatementIndex: e.data.activeStatementIndex
-        };
-
-        // Clear out old parse locations to prevent them from being shown when there's a syntax error in the statement
-        while (activeTokens.length > 0) {
-          delete activeTokens.pop().parseLocation;
-        }
-
-        var tokensToVerify = [];
-
-        e.data.locations.forEach(function (location) {
-          if (['statement', 'selectList', 'whereClause', 'limitClause'].indexOf(location.type) !== -1
-            || ((location.type === 'table' || location.type === 'column') && typeof location.identifierChain === 'undefined')) {
-            return;
-          }
-
-          if (location.identifierChain && location.identifierChain.length && location.identifierChain[0].name) {
-            // The parser isn't aware of the DDL so sometimes it marks complex columns as tables
-            // I.e. "Impala SELECT a FROM b.c" Is 'b' a database or a table? If table then 'c' is complex
-            if (self.snippet.type() === 'impala' &&
-              location.identifierChain.length > 2 &&
-              (location.type === 'table' || location.type === 'column') &&
-              self.isDatabase(location.identifierChain[0].name)) {
-              location.type = 'complex';
-            }
-          }
-
-          var token = self.editor.getSession().getTokenAt(location.location.first_line - 1, location.location.first_column);
-
-          // Find open UDFs and prevent them from being marked as missing columns, i.e. cos in "SELECT * FROM foo where cos(a|"
-          var rowTokens = self.editor.getSession().getTokens(location.location.first_line - 1);
-          if (location.type === 'column' && token && rowTokens) {
-            var tokenFound = false;
-            var isFunction = false;
-            rowTokens.some(function (rowToken) {
-              if (tokenFound && /\s+/.test(rowToken.value)) {
-                return false;
-              }
-              if (tokenFound) {
-                isFunction = rowToken.value === '(';
-                return true;
-              }
-              if (rowToken === token) {
-                tokenFound = true;
-              }
-            });
-            if (isFunction) {
-              location.type = 'function';
-              delete location.identifierChain;
-              location.function = token.value;
-              token = null;
-            }
-          }
-
-          if (token && token.value && /`$/.test(token.value)) {
-            // Ace getTokenAt() thinks the first ` is a token, column +1 will include the first and last.
-            token = self.editor.getSession().getTokenAt(location.location.first_line - 1, location.location.first_column + 1);
-          }
-          if (token && token.value && /^\s*\$\{\s*$/.test(token.value)) {
-            token = null;
-          }
-          if (token && token.value) {
-            var AceRange = ace.require('ace/range').Range;
-            // The Ace tokenizer also splits on '{', '(' etc. hence the actual value;
-            token.actualValue = self.editor.getSession().getTextRange(new AceRange(location.location.first_line - 1, location.location.first_column - 1, location.location.last_line - 1, location.location.last_column - 1));
-          }
-
-          if (token !== null) {
-            token.parseLocation = location;
-            activeTokens.push(token);
-            delete token.notFound;
-            delete token.syntaxError;
-            if (location.active) {
-              tokensToVerify.push(token);
-            }
-          }
-        });
-
-        if (self.snippet.type() === 'impala' || self.snippet.type() === 'hive') {
-          self.verifyExists(tokensToVerify, e.data.activeStatementLocations);
-        }
-        huePubSub.publish('editor.active.locations', lastKnownLocations);
-
-      });
-
-      self.disposeFunctions.push(function () {
-        locationWorkerSub.remove();
-      });
-
-      var lastContextRequest;
-      var statementSubscription = huePubSub.subscribe('editor.active.statement.changed', function (statementDetails) {
-        if (statementDetails.id !== self.editorId) {
-          return;
-        }
-        if (self.snippet.type() === 'hive' || self.snippet.type() === 'impala') {
-          if (lastContextRequest) {
-            lastContextRequest.dispose();
-          }
-          lastContextRequest = self.snippet.whenContextSet().done(function () {
-            huePubSub.publish('ace.sql.location.worker.post', {
-              id: self.snippet.id(),
-              statementDetails: statementDetails,
-              type: self.snippet.type(),
-              namespace: self.snippet.namespace(),
-              compute: self.snippet.compute(),
-              defaultDatabase: self.snippet.database()
-            })
-          });
-        }
-      });
-
-      self.disposeFunctions.push(function () {
-        statementSubscription.remove();
-      });
-    };
-
-    AceLocationHandler.prototype.dispose = function () {
-      var self = this;
-      if (self.sqlSyntaxWorkerSub !== null) {
-        self.sqlSyntaxWorkerSub.remove();
-        self.sqlSyntaxWorkerSub = null;
-      }
-
-      self.disposeFunctions.forEach(function (dispose) {
-        dispose();
-      })
-    };
-
-    return AceLocationHandler;
-  })();
-
-  ko.bindingHandlers.aceEditor = {
-    init: function (element, valueAccessor) {
-
-      var $el = $(element);
-      var options = ko.unwrap(valueAccessor());
-      var snippet = options.snippet;
-      var aceOptions = options.aceOptions || {};
-
-      var disposeFunctions = [];
-
-      var dispose = function () {
-        disposeFunctions.forEach(function (dispose) {
-          dispose();
-        })
-      };
-
-      ko.utils.domNodeDisposal.addDisposeCallback(element, dispose);
-
-      $el.text(snippet.statement_raw());
-
-      var editor = ace.edit($el.attr("id"));
-      var AceRange = ace.require('ace/range').Range;
-
-      var resizeAce = function () {
-        window.setTimeout(function () {
-          try {
-            editor.resize(true);
-          } catch (e) {
-            // Can happen when the editor hasn't been initialized
-          }
-        }, 0);
-      };
-
-      var assistToggleSub = huePubSub.subscribe('assist.set.manual.visibility', resizeAce);
-      var resizePubSub = huePubSub.subscribe('split.panel.resized', resizeAce);
-      disposeFunctions.push(function () {
-        assistToggleSub.remove();
-        resizePubSub.remove();
-      });
-
-      var aceLocationHandler = new AceLocationHandler({ editor: editor, editorId: $el.attr("id"), snippet: snippet, i18n: { expandStar: options.expandStar, contextTooltip: options.contextTooltip }});
-      disposeFunctions.push(function () {
-        aceLocationHandler.dispose();
-      });
-
-      editor.session.setMode(snippet.getAceMode());
-      editor.setOptions({ fontSize: snippet.getApiHelper().getFromTotalStorage('hue.ace', 'fontSize', navigator.platform && navigator.platform.toLowerCase().indexOf("linux") > -1 ? '14px' : '12px')});
-
-      function processErrorsAndWarnings(type, list) {
-        editor.clearErrorsAndWarnings(type);
-        var offset = 0;
-        if (snippet.isSqlDialect() && editor.getSelectedText()) {
-          var selectionRange = editor.getSelectionRange();
-          offset = Math.min(selectionRange.start.row, selectionRange.end.row);
-        }
-        if (list.length > 0) {
-          list.forEach(function (item, cnt) {
-            if (item.line !== null) {
-              if (type === 'error') {
-                editor.addError(item.message, item.line + offset);
-              } else {
-                editor.addWarning(item.message, item.line + offset);
-              }
-              if (cnt == 0) {
-                editor.scrollToLine(item.line + offset, true, true, function () {
-                });
-                if (item.col !== null) {
-                  editor.renderer.scrollCursorIntoView({row: item.line + offset, column: item.col + 10}, 0.5)
-                }
-              }
-            }
-          });
-        }
-      }
-
-      var errorsSub = snippet.errors.subscribe(function (newErrors) {
-        processErrorsAndWarnings('error', newErrors);
-      });
-
-      var aceWarningsSub = snippet.aceWarnings.subscribe(function (newWarnings) {
-        processErrorsAndWarnings('warning', newWarnings);
-      });
-
-      var aceErrorsSub = snippet.aceErrors.subscribe(function (newErrors) {
-        processErrorsAndWarnings('error', newErrors);
-      });
-
-      disposeFunctions.push(function () {
-        errorsSub.dispose();
-        aceWarningsSub.dispose();
-        aceErrorsSub.dispose();
-      });
-
-      var darkThemeEnabled = window.apiHelper.getFromTotalStorage('ace', 'dark.theme.enabled', false);
-      editor.setTheme(darkThemeEnabled ? 'ace/theme/hue_dark' : 'ace/theme/hue');
-
-      var editorOptions = {
-        enableSnippets: true,
-        showGutter: false,
-        showLineNumbers: false,
-        showPrintMargin: false,
-        scrollPastEnd: 0.1,
-        minLines: 1,
-        maxLines: 25
-      };
-
-      editor.enabledMenuOptions = {
-        setShowInvisibles: true,
-        setTabSize: true,
-        setShowGutter: true
-      };
-
-      editor.customMenuOptions = {
-        setEnableDarkTheme: function (enabled) {
-          darkThemeEnabled = enabled;
-          window.apiHelper.setInTotalStorage('ace', 'dark.theme.enabled', darkThemeEnabled);
-          editor.setTheme(darkThemeEnabled ? 'ace/theme/hue_dark' : 'ace/theme/hue');
-        },
-        getEnableDarkTheme: function () {
-          return darkThemeEnabled;
-        },
-        setEnableAutocompleter: function (enabled) {
-          editor.setOption('enableBasicAutocompletion', enabled);
-          snippet.getApiHelper().setInTotalStorage('hue.ace', 'enableBasicAutocompletion', enabled);
-          if (enabled && $('#setEnableLiveAutocompletion:checked').length === 0) {
-            $('#setEnableLiveAutocompletion').trigger('click');
-          } else if (!enabled && $('#setEnableLiveAutocompletion:checked').length !== 0) {
-            $('#setEnableLiveAutocompletion').trigger('click');
-          }
-        },
-        getEnableAutocompleter: function () {
-          return editor.getOption('enableBasicAutocompletion');
-        },
-        setEnableLiveAutocompletion: function (enabled) {
-          editor.setOption('enableLiveAutocompletion', enabled);
-          snippet.getApiHelper().setInTotalStorage('hue.ace', 'enableLiveAutocompletion', enabled);
-          if (enabled && $('#setEnableAutocompleter:checked').length === 0) {
-            $('#setEnableAutocompleter').trigger('click');
-          }
-        },
-        getEnableLiveAutocompletion: function () {
-          return editor.getOption('enableLiveAutocompletion');
-        },
-        setFontSize: function (size) {
-          if (size.toLowerCase().indexOf('px') === -1 && size.toLowerCase().indexOf('em') === -1) {
-            size += 'px';
-          }
-          editor.setOption('fontSize', size);
-          snippet.getApiHelper().setInTotalStorage('hue.ace', 'fontSize', size);
-        },
-        getFontSize: function () {
-          var size = editor.getOption('fontSize');
-          if (size.toLowerCase().indexOf('px') === -1 && size.toLowerCase().indexOf('em') === -1) {
-            size += 'px';
-          }
-          return size;
-        }
-      };
-
-      if (ENABLE_SQL_SYNTAX_CHECK && window.Worker) {
-        var errorHighlightingEnabled = snippet.getApiHelper().getFromTotalStorage('hue.ace', 'errorHighlightingEnabled', true);
-
-        if (errorHighlightingEnabled) {
-          aceLocationHandler.attachSqlSyntaxWorker();
-        }
-
-        editor.customMenuOptions.setErrorHighlighting = function (enabled) {
-          errorHighlightingEnabled = enabled;
-          snippet.getApiHelper().setInTotalStorage('hue.ace', 'errorHighlightingEnabled', enabled);
-          if (enabled) {
-            aceLocationHandler.attachSqlSyntaxWorker();
-          } else {
-            aceLocationHandler.detachSqlSyntaxWorker();
-          }
-        };
-        editor.customMenuOptions.getErrorHighlighting = function () {
-          return errorHighlightingEnabled;
-        };
-        editor.customMenuOptions.setClearIgnoredSyntaxChecks = function (flag) {
-          window.apiHelper.setInTotalStorage('hue.syntax.checker', 'suppressedRules', {});
-          $('#setClearIgnoredSyntaxChecks').hide();
-          $('#setClearIgnoredSyntaxChecks').before('<div style="margin-top:5px;float:right;">done</div>');
-        };
-        editor.customMenuOptions.getClearIgnoredSyntaxChecks = function () {
-          return false;
-        }
-      }
-
-      $.extend(editorOptions, aceOptions);
-
-      editorOptions['enableBasicAutocompletion'] = snippet.getApiHelper().getFromTotalStorage('hue.ace', 'enableBasicAutocompletion', true);
-      if (editorOptions['enableBasicAutocompletion']) {
-        editorOptions['enableLiveAutocompletion'] = snippet.getApiHelper().getFromTotalStorage('hue.ace', 'enableLiveAutocompletion', true);
-      }
-
-      editor.setOptions(editorOptions);
-
-      var AceAutocomplete = ace.require("ace/autocomplete").Autocomplete;
-
-      if (!editor.completer) {
-        editor.completer = new AceAutocomplete();
-      }
-      editor.completer.exactMatch = ! snippet.isSqlDialect();
-
-      var initAutocompleters = function () {
-        if (editor.completers) {
-          editor.completers.length = 0;
-          if (snippet.type() === 'hive' || snippet.type() === 'impala') {
-            if (options.useNewAutocompleter) {
-              editor.useHueAutocompleter = true;
-            } else {
-              editor.completers.push(snippet.autocompleter);
-            }
-          } else {
-            editor.completers.push(langTools.snippetCompleter);
-            editor.completers.push(langTools.textCompleter);
-            editor.completers.push(langTools.keyWordCompleter);
-            editor.completers.push(snippet.autocompleter);
-          }
-        }
-      };
-
-      var langTools = ace.require("ace/ext/language_tools");
-      langTools.textCompleter.setSqlMode(snippet.isSqlDialect());
-
-      initAutocompleters();
-
-      var UNICODES_TO_REMOVE = /[\u1680\u180E\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200A\u200B\u202F\u205F\u3000\uFEFF]/ig;  //taken from https://www.cs.tut.fi/~jkorpela/chars/spaces.html
-
-      var removeUnicodes = function (value) {
-        return value.replace(UNICODES_TO_REMOVE, ' ');
-      };
-
-      var placeHolderElement = null;
-      var placeHolderVisible = false;
-      var placeHolderText = snippet.getPlaceHolder();
-      if (placeHolderText) {
-        placeHolderElement = $("<div>")
-          .text(placeHolderText)
-          .css("margin-left", "6px")
-          .addClass("ace_invisible ace_emptyMessage");
-        if (editor.getValue().length == 0) {
-          placeHolderElement.appendTo(editor.renderer.scroller);
-          placeHolderVisible = true;
-        }
-      }
-
-      var pasteListener = editor.on('paste', function (e) {
-        e.text = removeUnicodes(e.text);
-      });
-
-      disposeFunctions.push(function () {
-        editor.off('paste', pasteListener);
-      });
-
-      var inputListener = editor.on('input', function () {
-        if (editor.getValue().length == 0) {
-          if (!placeHolderVisible && placeHolderElement) {
-            placeHolderElement.appendTo(editor.renderer.scroller);
-            placeHolderVisible = true;
-          }
-        } else {
-          placeHolderElement.remove();
-          placeHolderVisible = false;
-        }
-        if (options.updateOnInput) {
-          snippet.statement_raw(removeUnicodes(editor.getValue()));
-        }
-      });
-
-      disposeFunctions.push(function () {
-        editor.off('input', inputListener);
-      });
-
-      if (snippet.aceCursorPosition()) {
-        editor.moveCursorToPosition(snippet.aceCursorPosition());
-        window.setTimeout(function () {
-          editor.centerSelection();
-        }, 0);
-      }
-
-      var focusListener = editor.on('focus', function () {
-        initAutocompleters();
-        snippet.inFocus(true);
-        $(".ace-editor").data("last-active-editor", false);
-        $el.data("last-active-editor", true);
-        if (editor.session.$backMarkers) {
-          for (var marker in editor.session.$backMarkers) {
-            if (editor.session.$backMarkers[marker].clazz === 'highlighted') {
-              editor.session.removeMarker(editor.session.$backMarkers[marker].id);
-            }
-          }
-        }
-      });
-
-      disposeFunctions.push(function () {
-        editor.off('focus', focusListener);
-      });
-
-      var changeSelectionListener = editor.selection.on('changeSelection', function () {
-        snippet.selectedStatement(editor.getSelectedText());
-      });
-
-      disposeFunctions.push(function () {
-        editor.selection.off('changeSelection', changeSelectionListener);
-      });
-
-      var blurListener = editor.on('blur', function () {
-        snippet.inFocus(false);
-        snippet.statement_raw(removeUnicodes(editor.getValue()));
-        if (options.onBlur) {
-          options.onBlur($el, removeUnicodes(editor.getValue()));
-        }
-      });
-
-      disposeFunctions.push(function () {
-        editor.off('blur', blurListener);
-      });
-
-      editor.previousSize = 0;
-
-      // TODO: Get rid of this
-      var idInterval = window.setInterval(function(){
-        editor.session.getMode().$id = snippet.getAceMode(); // forces the id again because of Ace command internals
-      }, 100);
-
-      disposeFunctions.push(function () {
-        window.clearInterval(idInterval);
-      });
-
-      editor.middleClick = false;
-      var mousedownListener = editor.on('mousedown', function (e) {
-        if (e.domEvent.which == 2) { // middle click
-          editor.middleClick = true;
-          var tempText = editor.getSelectedText();
-          if (e.$pos) {
-            editor.session.insert(e.$pos, tempText);
-          }
-          window.setTimeout(function () {
-            editor.middleClick = false;
-            if (e.$pos) {
-              editor.moveCursorTo(e.$pos.row, e.$pos.column + tempText.length);
-            }
-          }, 200);
-        }
-      });
-
-      disposeFunctions.push(function () {
-        editor.off('mousedown', mousedownListener);
-      });
-
-      var aceReplaceSub = huePubSub.subscribe('ace.replace', function (data) {
-        var Range = ace.require('ace/range').Range;
-        var range = new Range(data.location.first_line - 1, data.location.first_column - 1, data.location.last_line - 1, data.location.last_column - 1);
-        editor.getSession().getDocument().replace(range, data.text);
-      });
-
-      disposeFunctions.push(function () {
-        aceReplaceSub.remove();
-      });
-
-      var clickListener = editor.on('click', function (e) {
-        editor.clearErrorsAndWarnings();
-      });
-
-      disposeFunctions.push(function () {
-        editor.off('click', clickListener);
-      });
-
-      var changeListener = editor.on("change", function (e) {
-        snippet.statement_raw(removeUnicodes(editor.getValue()));
-        editor.session.getMode().$id = snippet.getAceMode();
-        var currentSize = editor.session.getLength();
-        if (currentSize != editor.previousSize && currentSize >= editorOptions.minLines && currentSize <= editorOptions.maxLines){
-          editor.previousSize = editor.session.getLength();
-          $(document).trigger("editorSizeChanged");
-        }
-        // automagically change snippet type
-        var firstLine = editor.session.getLine(0);
-        if (firstLine.indexOf("%") == 0 && firstLine.charAt(firstLine.length - 1) == " ") {
-          var availableSnippets = snippet.availableSnippets;
-          var removeFirstLine = false;
-          for (var i = 0; i < availableSnippets.length; i++) {
-            if ($.trim(firstLine.substr(1)) == availableSnippets[i].type()) {
-              snippet.type(availableSnippets[i].type());
-              removeFirstLine = true;
-              break;
-            }
-          }
-          if (removeFirstLine) {
-            editor.session.remove(new AceRange(0, 0, 0, 200));
-          }
-        }
-      });
-
-      disposeFunctions.push(function () {
-        editor.off("change", changeListener);
-      });
-
-      editor.commands.addCommand({
-        name: "execute",
-        bindKey: {win: "Ctrl-Enter", mac: "Command-Enter|Ctrl-Enter"},
-        exec: function () {
-          snippet.statement_raw(removeUnicodes(editor.getValue()));
-          snippet.execute();
-        }
-      });
-
-      editor.commands.addCommand({
-        name: 'switchTheme',
-        bindKey: { win: 'Ctrl-Alt-t', mac: 'Command-Alt-t' },
-        exec: function () {
-          darkThemeEnabled = !darkThemeEnabled;
-          window.apiHelper.setInTotalStorage('ace', 'dark.theme.enabled', darkThemeEnabled);
-          editor.setTheme(darkThemeEnabled ? 'ace/theme/hue_dark' : 'ace/theme/hue');
-        }
-      });
-
-      editor.commands.addCommand({
-        name: "new",
-        bindKey: {win: "Ctrl-e", mac: "Command-e"},
-        exec: function () {
-          huePubSub.publish('editor.create.new');
-        }
-      });
-
-      editor.commands.addCommand({
-        name: "save",
-        bindKey: {win: "Ctrl-s", mac: "Command-s|Ctrl-s"},
-        exec: function () {
-          huePubSub.publish('editor.save');
-        }
-      });
-
-      editor.commands.addCommand({
-        name: "esc",
-        bindKey: {win: "Ctrl-Shift-p", mac: "Ctrl-Shift-p|Command-Shift-p"},
-        exec: function () {
-          huePubSub.publish('editor.presentation.toggle');
-        }
-      });
-
-      editor.commands.bindKey("Ctrl-P", "golineup");
-
-      editor.commands.addCommand({
-        name: "format",
-        bindKey: {win: "Ctrl-i|Ctrl-Shift-f|Ctrl-Alt-l", mac: "Command-i|Ctrl-i|Ctrl-Shift-f|Command-Shift-f|Ctrl-Shift-l|Cmd-Shift-l"},
-        exec: function () {
-          if (['ace/mode/hive', 'ace/mode/impala', 'ace/mode/sql', 'ace/mode/mysql', 'ace/mode/pgsql', 'ace/mode/sqlite', 'ace/mode/oracle'].indexOf(snippet.getAceMode()) > -1) {
-            $.post("/notebook/api/format", {
-              statements: editor.getSelectedText() != '' ? editor.getSelectedText() : editor.getValue()
-            }, function(data) {
-              if (data.status == 0) {
-                 if (editor.getSelectedText() != '') {
-                  editor.session.replace(editor.session.selection.getRange(), data.formatted_statements);
-                } else {
-                  editor.setValue(data.formatted_statements);
-                  snippet.statement_raw(removeUnicodes(editor.getValue()));
-                }
-              }
-            });
-          }
-        }
-      });
-
-      editor.commands.addCommand({
-        name: "gotolinealternative",
-        bindKey: {win: "Ctrl-j", mac: "Command-j|Ctrl-j"},
-        exec: editor.commands.commands['gotoline'].exec
-      });
-
-
-      var isNewStatement = function () {
-        return /^\s*$/.test(editor.getValue()) || /^.*;\s*$/.test(editor.getTextBeforeCursor());
-      };
-
-      var insertSqlAtCursor = function (text, cursorEndAdjust, menu) {
-        var before = editor.getTextBeforeCursor();
-        if (/\S+$/.test(before)) {
-          text = " " + text;
-        }
-        if (menu) {
-          menu.hide();
-        }
-        editor.session.insert(editor.getCursorPosition(), text);
-        if (cursorEndAdjust !== 0) {
-          var cursor = editor.getCursorPosition();
-          editor.moveCursorToPosition({ row: cursor.row, column: cursor.column + cursorEndAdjust });
-        }
-        editor.clearSelection();
-        editor.focus();
-      };
-
-      var insertTableAtCursorSub = huePubSub.subscribe('editor.insert.table.at.cursor', function(details) {
-        if ($el.data('last-active-editor')) {
-          var qualifiedName = snippet.database() == details.database ? details.name : details.database + '.' + details.name;
-          if (isNewStatement()) {
-            insertSqlAtCursor('SELECT * FROM ' + qualifiedName + ' LIMIT 100;', -1);
-          } else {
-            insertSqlAtCursor(qualifiedName + ' ', 0);
-          }
-        }
-      });
-
-      var insertColumnAtCursorSub = huePubSub.subscribe('editor.insert.column.at.cursor', function(details) {
-        if ($el.data('last-active-editor')) {
-          if (isNewStatement()) {
-            var qualifiedFromName = snippet.database() == details.database ? details.table : details.database + '.' + details.table;
-            insertSqlAtCursor('SELECT '  + details.name + ' FROM ' + qualifiedFromName + ' LIMIT 100;', -1);
-          } else {
-            insertSqlAtCursor(details.name + ' ', 0);
-          }
-        }
-      });
-
-      var insertAtCursorSub = huePubSub.subscribe('editor.insert.at.cursor', function(text) {
-        if ($el.data('last-active-editor')) {
-          insertSqlAtCursor(text + ' ', 0);
-        }
-      });
-
-      disposeFunctions.push(function () {
-        insertTableAtCursorSub.remove();
-        insertColumnAtCursorSub.remove();
-        insertAtCursorSub.remove();
-
-      });
-
-      var dblClickHdfsItemSub = huePubSub.subscribe("assist.dblClickHdfsItem", function(assistHdfsEntry) {
-        if ($el.data("last-active-editor")) {
-          editor.session.insert(editor.getCursorPosition(), "'" + assistHdfsEntry.path + "'");
-        }
-      });
-
-      disposeFunctions.push(function () {
-        dblClickHdfsItemSub.remove();
-      });
-
-      var dblClickAdlsItemSub = huePubSub.subscribe("assist.dblClickAdlsItem", function(assistHdfsEntry) {
-        if ($el.data("last-active-editor")) {
-          editor.session.insert(editor.getCursorPosition(), "adl:/" + assistHdfsEntry.path + "'");
-        }
-      });
-
-      disposeFunctions.push(function () {
-        dblClickAdlsItemSub.remove();
-      });
-
-
-      var dblClickGitItemSub = huePubSub.subscribe("assist.dblClickGitItem", function(assistGitEntry) {
-        if ($el.data("last-active-editor")) {
-          editor.session.setValue(assistGitEntry.fileContent());
-        }
-      });
-
-      disposeFunctions.push(function () {
-        dblClickGitItemSub.remove();
-      });
-
-      var dblClickS3ItemSub = huePubSub.subscribe("assist.dblClickS3Item", function(assistS3Entry) {
-        if ($el.data("last-active-editor")) {
-          editor.session.insert(editor.getCursorPosition(), "'S3A://" + assistS3Entry.path + "'");
-        }
-      });
-
-      disposeFunctions.push(function () {
-        dblClickS3ItemSub.remove();
-      });
-
-      var sampleErrorInsertSub = huePubSub.subscribe('sample.error.insert.click', function(popoverEntry) {
-        var table = popoverEntry.identifierChain[popoverEntry.identifierChain.length - 1]['name'];
-        var text = "SELECT * FROM " + table + " LIMIT 100;";
-        insertSqlAtCursor(text, -1);
-      });
-
-      disposeFunctions.push(function () {
-        sampleErrorInsertSub.remove();
-      });
-
-      var $tableDropMenu = $el.next('.table-drop-menu');
-      var $identifierDropMenu = $tableDropMenu.find('.editor-drop-identifier');
-
-
-      var hideDropMenu = function () {
-        $tableDropMenu.css('opacity', 0);
-        window.setTimeout(function () {
-          $tableDropMenu.hide();
-        }, 300);
-      };
-
-      var documentClickListener = function (event) {
-        if ($tableDropMenu.find($(event.target)).length === 0) {
-          hideDropMenu();
-        }
-      };
-
-      $(document).on('click', documentClickListener);
-
-      disposeFunctions.push(function () {
-        $(document).off('click', documentClickListener);
-      });
-
-
-      var lastMeta = {};
-      var draggableTextSub = huePubSub.subscribe('draggable.text.meta', function (meta) {
-        lastMeta = meta;
-        if (meta.isView) {
-          $tableDropMenu.find('.editor-drop-update').hide();
-          $tableDropMenu.find('.editor-drop-insert').hide();
-          $tableDropMenu.find('.editor-drop-drop').hide();
-          $tableDropMenu.find('.editor-drop-view').show();
-        } else {
-          $tableDropMenu.find('.editor-drop-update').show();
-          $tableDropMenu.find('.editor-drop-insert').show();
-          $tableDropMenu.find('.editor-drop-drop').show();
-          $tableDropMenu.find('.editor-drop-view').hide();
-        }
-        if (typeof meta !== 'undefined' && typeof meta.database !== 'undefined' && typeof meta.table !== 'undefined') {
-          $identifierDropMenu.text(meta.database + '.' + meta.table)
-        }
-      });
-
-      disposeFunctions.push(function () {
-        draggableTextSub.remove();
-      });
-
-      var menu = ko.bindingHandlers.contextMenu.initContextMenu($tableDropMenu, $('.content-panel'));
-
-      $tableDropMenu.find('.editor-drop-value').click(function () {
-        insertSqlAtCursor(sqlUtils.backTickIfNeeded(lastMeta.type, lastMeta.database) + '.' + sqlUtils.backTickIfNeeded(lastMeta.type, lastMeta.table) + ' ', 0, menu);
-      });
-
-      $tableDropMenu.find('.editor-drop-select').click(function () {
-        insertSqlAtCursor('SELECT * FROM ' + sqlUtils.backTickIfNeeded(lastMeta.type, lastMeta.database) + '.' + sqlUtils.backTickIfNeeded(lastMeta.type, lastMeta.table) + ' LIMIT 100;', -1, menu);
-        $tableDropMenu.hide();
-      });
-
-      $tableDropMenu.find('.editor-drop-insert').click(function () {
-        insertSqlAtCursor('INSERT INTO ' + sqlUtils.backTickIfNeeded(lastMeta.type, lastMeta.database) + '.' + sqlUtils.backTickIfNeeded(lastMeta.type, lastMeta.table) + ' VALUES ();', -2, menu);
-      });
-
-      $tableDropMenu.find('.editor-drop-update').click(function () {
-        insertSqlAtCursor('UPDATE ' + sqlUtils.backTickIfNeeded(lastMeta.type, lastMeta.database) + '.' + sqlUtils.backTickIfNeeded(lastMeta.type, lastMeta.table) + ' SET ', 0, menu);
-      });
-
-      $tableDropMenu.find('.editor-drop-view').click(function () {
-        insertSqlAtCursor('DROP VIEW ' + sqlUtils.backTickIfNeeded(lastMeta.type, lastMeta.database) + '.' + sqlUtils.backTickIfNeeded(lastMeta.type, lastMeta.table) + ';', -1, menu);
-      });
-
-      $tableDropMenu.find('.editor-drop-drop').click(function () {
-        insertSqlAtCursor('DROP TABLE ' + sqlUtils.backTickIfNeeded(lastMeta.type, lastMeta.database) + '.' + sqlUtils.backTickIfNeeded(lastMeta.type, lastMeta.table) + ';', -1, menu);
-      });
-
-      $el.droppable({
-        accept: ".draggableText",
-        drop: function (e, ui) {
-          var position = editor.renderer.screenToTextCoordinates(e.clientX, e.clientY);
-          var text = ui.helper.text();
-          if (lastMeta.type === 's3' || lastMeta.type === 'hdfs' || lastMeta.type === 'adls'){
-            text = "'" + lastMeta.definition.path + "'";
-          }
-          editor.moveCursorToPosition(position);
-          var before = editor.getTextBeforeCursor();
-          if (lastMeta.database && lastMeta.table && ! lastMeta.column && /.*;|^\s*$/.test(before)) {
-            menu.show(e);
-          } else {
-            if (/\S+$/.test(before) && before.charAt(before.length - 1) !== '.') {
-              text = " " + text;
-            }
-            var after = editor.getTextAfterCursor();
-            if (after.length > 0 && after.charAt(0) !== ' ' && text.charAt(text.length - 1) !== ' ') {
-              text += " ";
-            }
-            editor.session.insert(position, text);
-            position.column += text.length;
-            editor.clearSelection();
-          }
-        }
-      });
-
-      var autocompleteTemporarilyDisabled = false;
-      var autocompleteThrottle = -1;
-      var afterExecListener = editor.commands.on('afterExec', function (e) {
-        if (editor.getOption('enableLiveAutocompletion') && e.command.name === "insertstring") {
-          if (/\S+\(\)$/.test(e.args)) {
-            editor.moveCursorTo(editor.getCursorPosition().row, editor.getCursorPosition().column - 1);
-            return;
-          }
-          window.clearTimeout(autocompleteThrottle);
-          autocompleteThrottle = window.setTimeout(function () {
-            var textBeforeCursor = editor.getTextBeforeCursor();
-            var questionMarkMatch;
-            if ($('.hue-ace-autocompleter').length > 0) {
-              questionMarkMatch = textBeforeCursor.match(/select\s+(\? from \S+[^.]\s$)/i);
-            } else {
-              questionMarkMatch = textBeforeCursor.match(/select\s+(\? from \S+[^.]$)/i);
-            }
-            if (questionMarkMatch && $('.ace_autocomplete:visible').length === 0) {
-              editor.moveCursorTo(editor.getCursorPosition().row, editor.getCursorPosition().column - (questionMarkMatch[1].length - 1));
-              editor.removeTextBeforeCursor(1);
-              huePubSub.publish('editor.refresh.statement.locations', snippet);
-              window.setTimeout(function () {
-                editor.execCommand("startAutocomplete");
-              }, 1);
-            } else if (/\.$/.test(textBeforeCursor)) {
-              huePubSub.publish('editor.refresh.statement.locations', snippet);
-              window.setTimeout(function () {
-                editor.execCommand("startAutocomplete");
-              }, 1);
-            }
-          }, 400);
-        }
-        editor.session.getMode().$id = snippet.getAceMode(); // forces the id again because of Ace command internals
-        // if it's pig and before it's LOAD ' we disable the autocomplete and show a filechooser btn
-        if (editor.session.getMode().$id === "ace/mode/pig" && e.args) {
-          var textBefore = editor.getTextBeforeCursor();
-          if ((e.args == "'" && textBefore.toUpperCase().indexOf("LOAD ") > -1 && textBefore.toUpperCase().indexOf("LOAD ") == textBefore.toUpperCase().length - 5)
-              || textBefore.toUpperCase().indexOf("LOAD '") > -1 && textBefore.toUpperCase().indexOf("LOAD '") == textBefore.toUpperCase().length - 6) {
-            if (editor.getOption('enableBasicAutocompletion')) {
-              editor.disableAutocomplete();
-              autocompleteTemporarilyDisabled = true;
-            }
-            var btn = editor.showFileButton();
-            btn.on("click", function (ie) {
-              ie.preventDefault();
-              // TODO: Turn the ace file chooser into a component and remove css class references
-              if (!$($(".ace-filechooser-content")).data('jHueFileChooser')) {
-                if ($(".ace-filechooser-content").data("spinner") == null) {
-                  $(".ace-filechooser-content").data("spinner", $(".ace-filechooser-content").html());
-                } else {
-                  $(".ace-filechooser-content").html($(".ace-filechooser-content").data("spinner"));
-                }
-                $(".ace-filechooser-content").jHueFileChooser({
-                  onFileChoose: function (filePath) {
-                    editor.session.insert(editor.getCursorPosition(), filePath + "'");
-                    editor.hideFileButton();
-                    if (autocompleteTemporarilyDisabled) {
-                      editor.enableAutocomplete();
-                      autocompleteTemporarilyDisabled = false;
-                    }
-                    $(".ace-filechooser").hide();
-                  },
-                  selectFolder: false,
-                  createFolder: false
-                });
-              }
-              $(".ace-filechooser").css({ "top": $(ie.currentTarget).position().top, "left": $(ie.currentTarget).position().left}).show();
-            });
-          } else {
-            editor.hideFileButton();
-            if (autocompleteTemporarilyDisabled) {
-              editor.enableAutocomplete();
-              autocompleteTemporarilyDisabled = false;
-            }
-          }
-          if (e.args != "'" && textBefore.toUpperCase().indexOf("LOAD '") > -1 && textBefore.toUpperCase().indexOf("LOAD '") == textBefore.toUpperCase().length - 6) {
-            editor.hideFileButton();
-            if (autocompleteTemporarilyDisabled) {
-              editor.enableAutocomplete();
-              autocompleteTemporarilyDisabled = false;
-            }
-          }
-        }
-      });
-
-      disposeFunctions.push(function () {
-        editor.commands.off('afterExec', afterExecListener);
-      });
-      editor.$blockScrolling = Infinity;
-
-      var range = options.highlightedRange ? options.highlightedRange() : null;
-      if (range && snippet.lastAceSelectionRowOffset()) {
-        var offset = snippet.lastAceSelectionRowOffset();
-        editor.selection.moveTo(range.start.row + offset, range.start.column);
-      }
-      snippet.ace(editor);
-    },
-
-    update: function (element, valueAccessor) {
-      var options = ko.unwrap(valueAccessor());
-      var snippet = options.snippet;
-      if (snippet.ace()) {
-        var editor = snippet.ace();
-        if (typeof options.readOnly !== 'undefined'){
-          editor.setReadOnly(options.readOnly);
-        }
-        var range = options.highlightedRange ? options.highlightedRange() : null;
-        if (editor.session.$backMarkers) {
-          for (var marker in editor.session.$backMarkers) {
-            if (editor.session.$backMarkers[marker].clazz === 'highlighted') {
-              editor.session.removeMarker(editor.session.$backMarkers[marker].id);
-            }
-          }
-        }
-        editor.session.setMode(snippet.getAceMode());
-        if (range && JSON.stringify(range.start) !== JSON.stringify(range.end)) {
-          var conflictingWithErrorMarkers = false;
-          if (editor.session.$backMarkers) {
-            for (var marker in editor.session.$backMarkers) {
-              if (editor.session.$backMarkers[marker].clazz === 'ace_error-line') {
-                var errorRange = editor.session.$backMarkers[marker].range;
-                if (range.start.row <= errorRange.end.row && range.end.row >= errorRange.start.row) {
-                  conflictingWithErrorMarkers = true;
-                }
-              }
-            }
-          }
-          if (!conflictingWithErrorMarkers) {
-            var lineOffset = snippet.lastAceSelectionRowOffset();
-            window.setTimeout(function () {
-              editor.session.addMarker(new AceRange(range.start.row + lineOffset, range.start.column, range.end.row + lineOffset, range.end.column), 'highlighted', 'line');
-              ace.require('ace/lib/dom').importCssString('.highlighted {\
-                  background-color: #E3F7FF;\
-                  position: absolute;\
-              }');
-              editor.scrollToLine(range.start.row + lineOffset, true, true, function () {});
-            }, 0);
-          }
-        }
-        try {
-          editor._emit('change')
-        }
-        catch (e){}
-      }
-    }
-  };
-
-  ko.bindingHandlers.medium = {
-    init: function (element, valueAccessor, allBindings) {
-      var editor = new MediumEditor($(element), {
-        buttons: ['header1', 'header2', 'bold', 'italic', 'underline', 'quote', 'anchor', 'orderedlist', 'unorderedlist', 'pre', 'outdent', 'indent'],
-        buttonLabels: 'fontawesome',
-        anchorTarget: true,
-        anchorInputPlaceholder: '${ _("Paste or type a link") }',
-        anchorInputCheckboxLabel: '${ _("Open in new window") }',
-        firstHeader: 'h2',
-        secondHeader: 'h3'
-      });
-      $(element).on('blur', function () {
-        allBindings().value($(element).html())
-      });
-    }
-  };
-
-  ko.bindingHandlers.verticalSlide = {
-    init: function(element, valueAccessor) {
-      if (ko.utils.unwrapObservable(valueAccessor())) {
-        $(element).show();
-      } else {
-        $(element).hide();
-      }
-    },
-    update: function(element, valueAccessor) {
-      if (ko.utils.unwrapObservable(valueAccessor())) {
-        $(element).slideDown('fast');
-      } else {
-        $(element).slideUp('fast');
-      }
-    }
-  };
-
-  ko.bindingHandlers.dblclick = {
-    init: function (element, valueAccessor, allBindingsAccessor, viewModel) {
-      var fn = valueAccessor();
-      $(element).dblclick(function () {
-        var data = ko.dataFor(this);
-        fn.call(viewModel, data);
-      });
-    }
-  };
-
-  ko.bindingHandlers.hueChecked = {
-    after: ['value', 'attr'],
-    init: function (element, valueAccessor, allBindings, viewModel, bindingContext) {
-      var selectedValues = valueAccessor();
-
-      if (allBindings().checkedValue) {
-        viewModel = ko.unwrap(allBindings().checkedValue);
-      }
-
-      var updateCheckedState = function () {
-        ko.utils.toggleDomNodeCssClass(element, 'fa-check', selectedValues.indexOf(viewModel) > -1);
-      };
-
-      ko.utils.registerEventHandler(element, 'click', function () {
-        var currentIndex = selectedValues.indexOf(viewModel);
-        if (currentIndex === -1) {
-          selectedValues.push(viewModel);
-        } else if (currentIndex > -1) {
-          selectedValues.splice(currentIndex, 1);
-        }
-      });
-
-      selectedValues.subscribe(updateCheckedState);
-      updateCheckedState();
-    }
-  };
-
-  ko.bindingHandlers.hueCheckbox = {
-    after: ['value', 'attr'],
-    init: function (element, valueAccessor, allBindings, viewModel, bindingContext) {
-      var value = valueAccessor();
-      $(element).addClass('hue-checkbox fa');
-
-      var updateCheckedState = function () {
-        ko.utils.toggleDomNodeCssClass(element, 'fa-check', value());
-      };
-
-      ko.utils.registerEventHandler(element, 'click', function () {
-        value(!value());
-      });
-
-      value.subscribe(updateCheckedState);
-      updateCheckedState();
-    }
-  };
-
-  ko.bindingHandlers.hueCheckAll = {
-    init: function (element, valueAccessor, allBindings) {
-      var allValues = ko.utils.unwrapObservable(valueAccessor()).allValues;
-      var selectedValues = ko.utils.unwrapObservable(valueAccessor()).selectedValues;
-
-      var updateCheckedState = function () {
-        ko.utils.toggleDomNodeCssClass(element, 'fa-check', allValues().length > 0 && selectedValues().length === allValues().length);
-        ko.utils.toggleDomNodeCssClass(element, 'fa-minus hue-uncheck', selectedValues().length > 0 && selectedValues().length !== allValues().length);
-      };
-
-      ko.utils.registerEventHandler(element, 'click', function () {
-        if (selectedValues().length == 0) {
-          selectedValues(allValues().slice(0));
-        } else {
-          selectedValues([]);
-        }
-      });
-
-      selectedValues.subscribe(updateCheckedState);
-      allValues.subscribe(updateCheckedState);
-      updateCheckedState();
-    }
-  };
-
-  /**
-   * This binding limits the rendered items based on what is visible within a scrollable container. It supports
-   * multiple any amount of nested children with foreachVisible bindings
-   *
-   * The minHeight parameter is the initial expected rendered height of each entry, once rendered the real
-   * height is used. It keeps a number of elements above and below the visible elements to make slow scrolling
-   * smooth.
-   *
-   * The height of the container element has to be less than or equal to the inner height of the window.
-   *
-   * Example:
-   *
-   * <div class="container" style="overflow-y: scroll; height: 100px">
-   *  <ul data-bind="foreachVisible: { data: items, minHeight: 20, container: '.container' }">
-   *    <li>...</li>
-   *  </ul>
-   * </div>
-   *
-   * For tables the binding has to be attached to the tbody element:
-   *
-   * <div class="container" style="overflow-y: scroll; height: 100px">
-   *  <table>
-   *    <thead>...</thead>
-   *    <tbody data-bind="foreachVisible: { data: items, minHeight: 20, container: '.container' }>
-   *      <tr>...</tr>
-   *    </tbody>
-   *  </ul>
-   * </div>
-   *
-   * Currently the binding only supports one element inside the bound element otherwise the height
-   * calculations will be off. In other words this will make it go bonkers:
-   *
-   * <div class="container" style="overflow-y: scroll; height: 100px">
-   *  <ul data-bind="foreachVisible: { data: items, minHeight: 20, container: '.container' }">
-   *    <li>...</li>
-   *    <li style="display: none;">...</li>
-   *  </ul>
-   * </div>
-   *
-   */
-  ko.bindingHandlers.foreachVisible = {
-    init: function (element, valueAccessor, allBindings, viewModel, bindingContext) {
-      return ko.bindingHandlers.template.init(element, function () {
-        return {
-          'foreach': [],
-          'templateEngine': ko.nativeTemplateEngine.instance
-        };
-      }, allBindings, viewModel, bindingContext);
-    },
-
-    update: function (element, valueAccessor, allBindings, viewModel, bindingContext) {
-      var options = valueAccessor();
-      var $element = $(element);
-      var isTable = false;
-
-      if ($element.parent().is('table')) {
-        $element = $element.parent();
-        isTable = true;
-      }
-
-      var $container = $element.closest(options.container);
-
-      var id = Math.random();
-
-      // This is possibly a parent element that has the foreachVisible binding
-      var $parentFVElement = bindingContext.$parentForeachVisible || null;
-      var parentId = bindingContext.$parentForeachVisibleId || -1;
-      // This is the element from the parent foreachVisible rendered element that contains
-      // this one or container for root
-      var $parentFVOwnerElement = $container;
-      $element.data('parentForeachVisible', $parentFVElement);
-
-      var depth = bindingContext.$depth || 0;
-
-      // Locate the owning element if within another foreach visible binding
-      if ($parentFVElement) {
-        var myOffset = $element.offset().top;
-        $parentFVElement.children().each(function (idx, child) {
-          var $child = $(child);
-          if (myOffset > $child.offset().top) {
-            $parentFVOwnerElement = $child;
-          } else {
-            return false;
-          }
-        });
-      }
-
-      if ($parentFVOwnerElement.data('disposalFunction')) {
-        $parentFVOwnerElement.data('disposalFunction')();
-        $parentFVOwnerElement.data('lastKnownHeights', null);
-      }
-
-      var entryMinHeight = options.minHeight;
-      var allEntries = ko.utils.unwrapObservable(options.data);
-
-      var visibleEntryCount = 0;
-      var incrementLimit = 0; // The diff required to re-render, set to visibleCount below
-      var elementIncrement = 0; // Elements to add on either side of the visible elements, set to 3x visibleCount
-
-      var updateVisibleEntryCount = function () {
-        // TODO: Drop the window innerHeight limitation.
-        // Sometimes after resizeWrapper() is called the reported innerHeight of the $container is the same as
-        // the wrapper causing the binding to render all the items. This limits the visibleEntryCount to the
-        // window height.
-        var newEntryCount = Math.ceil(Math.min($(window).innerHeight(), $container.innerHeight()) / entryMinHeight);
-        if (newEntryCount !== visibleEntryCount) {
-          var diff = newEntryCount - visibleEntryCount;
-          elementIncrement = options.elementIncrement || 25;
-          incrementLimit = options.incrementLimit || 5;
-          visibleEntryCount = newEntryCount;
-          endIndex += diff;
-          huePubSub.publish('foreach.visible.update', id);
-        }
-      };
-
-      // TODO: Move intervals to webworker
-      var updateCountInterval = setInterval(updateVisibleEntryCount, 300);
-      updateVisibleEntryCount();
-
-      // In case this element was rendered before use the last known indices
-      var startIndex = Math.max($parentFVOwnerElement.data('startIndex') || 0, 0);
-      var endIndex = Math.min($parentFVOwnerElement.data('endIndex') || (visibleEntryCount + elementIncrement), allEntries.length - 1);
-
-      var huePubSubs = [];
-
-      var scrollToIndex = function (idx, offset, instant, callback) {
-        var lastKnownHeights = $parentFVOwnerElement.data('lastKnownHeights');
-        if (! lastKnownHeights || lastKnownHeights.length <= idx) {
-          return;
-        }
-        var top = 0;
-        for (var i = 0; i < idx; i++) {
-          top += lastKnownHeights[i];
-        }
-        var bottom = top + lastKnownHeights[idx];
-        window.setTimeout(function () {
-          var newScrollTop = top + offset;
-          if (instant) {
-            if (newScrollTop >= $container.height() + $container.scrollTop()) {
-              $container.scrollTop(bottom - $container.height());
-            } else if (newScrollTop <= $container.scrollTop()) {
-              $container.scrollTop(newScrollTop);
-            }
-          } else {
-            $container.stop().animate({ scrollTop: newScrollTop }, '500', 'swing', function () {
-              if (callback) {
-                callback();
-              }
-            });
-          }
-        }, 0);
-
-      };
-
-      if (!options.skipScrollEvent) {
-        huePubSubs.push(huePubSub.subscribe('assist.db.scrollTo', function (targetEntry) {
-          var foundIndex = -1;
-          $.each(allEntries, function (idx, entry) {
-            if (targetEntry === entry) {
-              foundIndex = idx;
-              return false;
-            }
-          });
-          if (foundIndex !== -1) {
-            var offset = depth > 0 ? $parentFVOwnerElement.position().top : 0;
-            scrollToIndex(foundIndex, offset, false, function () {
-              huePubSub.publish('assist.db.scrollToComplete', targetEntry);
-            });
-          }
-        }));
-      }
-
-      if (ko.isObservable(viewModel.foreachVisible)) {
-        viewModel.foreachVisible({
-          scrollToIndex: function (index) {
-            var offset = depth > 0 ? $parentFVOwnerElement.position().top : 0;
-            scrollToIndex(index, offset, true);
-          }
-        })
-      }
-
-      var childBindingContext = bindingContext.createChildContext(
-          bindingContext.$rawData,
-          null,
-          function(context) {
-            ko.utils.extend(context, {
-              $parentForeachVisible: $element,
-              $parentForeachVisibleId: id,
-              $depth: depth + 1,
-              $indexOffset: function() {
-                return startIndex;
-              }
-            });
-          });
-
-      var $wrapper = $element.parent();
-      if (!$wrapper.hasClass('foreach-wrapper')) {
-        $wrapper = $('<div>').css({
-          'position': 'relative',
-          'width': '100%'
-        }).addClass('foreach-wrapper').insertBefore($element);
-        if (options.usePreloadBackground) {
-          $wrapper.addClass('assist-preloader-wrapper');
-          $element.addClass('assist-preloader');
-        }
-        $element.css({
-          'position': 'absolute',
-          'top': 0,
-          'width': '100%'
-        }).appendTo($wrapper);
-      }
-
-      // This is kept up to date with the currently rendered elements, it's used to keep track of any
-      // height changes of the elements.
-      var renderedElements = [];
-
-      if (! $parentFVOwnerElement.data('lastKnownHeights') || $parentFVOwnerElement.data('lastKnownHeights').length !== allEntries.length) {
-        var lastKnownHeights = [];
-        $.each(allEntries, function () {
-          lastKnownHeights.push(entryMinHeight);
-        });
-        $parentFVOwnerElement.data('lastKnownHeights', lastKnownHeights);
-      }
-
-      var resizeWrapper = function () {
-        var totalHeight = 0;
-        var lastKnownHeights = $parentFVOwnerElement.data('lastKnownHeights');
-        if (!lastKnownHeights) {
-          return;
-        }
-        $.each(lastKnownHeights, function(idx, height) {
-          totalHeight += height;
-        });
-        $wrapper.height(totalHeight + 'px');
-      };
-      resizeWrapper();
-
-      var updateLastKnownHeights = function () {
-        if ($container.data('busyRendering')) {
-          return;
-        }
-        var lastKnownHeights = $parentFVOwnerElement.data('lastKnownHeights');
-        // Happens when closing first level and the third level is open, disposal tells the parents
-        // to update their heights...
-        if (!lastKnownHeights) {
-          return;
-        }
-        var diff = false;
-        var updateEntryCount = false;
-        $.each(renderedElements, function (idx, renderedElement) {
-          // TODO: Figure out why it goes over index at the end scroll position
-          if (startIndex + idx < lastKnownHeights.length) {
-            var renderedHeight = $(renderedElement).outerHeight(true);
-            if (renderedHeight > 5 && lastKnownHeights[startIndex + idx] !== renderedHeight) {
-              if (renderedHeight < entryMinHeight) {
-                entryMinHeight = renderedHeight;
-                updateEntryCount = true;
-              }
-              lastKnownHeights[startIndex + idx] = renderedHeight;
-              diff = true;
-            }
-          }
-        });
-
-        if (updateEntryCount) {
-          updateVisibleEntryCount();
-        }
-        // Only resize if a difference in height was noticed.
-        if (diff) {
-          $parentFVOwnerElement.data('lastKnownHeights', lastKnownHeights);
-          resizeWrapper();
-        }
-      };
-
-      var updateHeightsInterval = window.setInterval(updateLastKnownHeights, 600);
-
-      huePubSubs.push(huePubSub.subscribe('foreach.visible.update.heights', function (targetId) {
-        if (targetId === id) {
-          clearInterval(updateHeightsInterval);
-          updateLastKnownHeights();
-          huePubSub.publish('foreach.visible.update.heights', parentId);
-          updateHeightsInterval = window.setInterval(updateLastKnownHeights, 600);
-        }
-      }));
-
-      updateLastKnownHeights();
-
-      var positionList = function () {
-        var lastKnownHeights = $parentFVOwnerElement.data('lastKnownHeights');
-        if (! lastKnownHeights) {
-          return;
-        }
-        var top = 0;
-        for (var i = 0; i < startIndex; i++) {
-          top += lastKnownHeights[i];
-        }
-        $element.css('top', top + 'px');
-      };
-
-      var afterRender = function () {
-        renderedElements = isTable ? $element.children('tbody').children() : $element.children();
-        $container.data('busyRendering', false);
-        if (typeof options.fetchMore !== 'undefined' && endIndex === allEntries.length - 1) {
-          options.fetchMore();
-        }
-        huePubSub.publish('foreach.visible.update.heights', id);
-      };
-
-      var render = function () {
-        if (endIndex === 0 && allEntries.length > 1 || endIndex < 0) {
-          ko.bindingHandlers.template.update(element, function () {
-            return {
-              'foreach': [],
-              'templateEngine': ko.nativeTemplateEngine.instance,
-              'afterRender': function () {
-                // This is called once for each added element (not when elements are removed)
-                clearTimeout(throttle);
-                throttle = setTimeout(afterRender, 0);
-              }
-            };
-          }, allBindings, viewModel, childBindingContext);
-          return;
-        }
-        $container.data('busyRendering', true);
-        // Save the start and end index for when the list is removed and is shown again.
-        $parentFVOwnerElement.data('startIndex', startIndex);
-        $parentFVOwnerElement.data('endIndex', endIndex);
-        positionList();
-
-
-        // This is to ensure that our afterRender is called (the afterRender of KO below isn't called
-        // when only elements are removed)
-        var throttle = setTimeout(afterRender, 0);
-
-        ko.bindingHandlers.template.update(element, function () {
-          return {
-            'foreach': allEntries.slice(startIndex, endIndex + 1),
-            'templateEngine': ko.nativeTemplateEngine.instance,
-            'afterRender': function () {
-              // This is called once for each added element (not when elements are removed)
-              clearTimeout(throttle);
-              throttle = setTimeout(afterRender, 0);
-            }
-          };
-        }, allBindings, viewModel, childBindingContext);
-      };
-
-      var setStartAndEndFromScrollTop = function () {
-        var lastKnownHeights = $parentFVOwnerElement.data('lastKnownHeights');
-        if (!lastKnownHeights) {
-          return;
-        }
-
-        var parentSpace = 0;
-
-        var $lastParent = $parentFVElement;
-        var $lastRef = $element;
-        var $parentOwner;
-
-        while ($lastParent) {
-          // Include the header, parent() is .foreach-wrapper, parent().parent() is the container (ul or div)
-          var lastRefOffset = $lastRef.parent().parent().offset().top;
-          var lastAddedSpace = 0;
-          $lastParent.children().each(function (idx, child) {
-            var $child = $(child);
-            if (lastRefOffset > $child.offset().top) {
-              lastAddedSpace = $child.outerHeight(true);
-              parentSpace += lastAddedSpace;
-              if ($lastParent === $parentFVElement) {
-                $parentOwner = $child;
-              }
-            } else {
-              // Remove the height of the child which is the parent of this
-              parentSpace -= lastAddedSpace;
-              return false;
-            }
-          });
-          parentSpace += $lastParent.position().top;
-          $lastRef = $lastParent;
-          $lastParent = $lastParent.data('parentForeachVisible');
-        }
-        var position = Math.min($container.scrollTop() - parentSpace, $wrapper.height());
-
-        for (var i = 0; i < lastKnownHeights.length; i++) {
-          position -= lastKnownHeights[i];
-          if (position <= 0) {
-            startIndex = Math.max(i - elementIncrement, 0);
-            endIndex = Math.min(allEntries.length - 1, i + elementIncrement + visibleEntryCount);
-            break;
-          }
-        }
-      };
-
-      var renderThrottle = -1;
-      var preloadGhostThrottle = -1;
-      var lastScrollTop = -1;
-      var onScroll = function () {
-        if (startIndex > incrementLimit && Math.abs(lastScrollTop - $container.scrollTop()) < (incrementLimit * options.minHeight)) {
-          return;
-        }
-        lastScrollTop = $container.scrollTop();
-
-        setStartAndEndFromScrollTop();
-
-        // adds a preload ghost image just on scroll and removes it 200ms after the scroll stops
-        if (options.usePreloadBackground) {
-          $wrapper.addClass('assist-preloader-ghost');
-          clearTimeout(preloadGhostThrottle);
-          preloadGhostThrottle = setTimeout(function () {
-            $wrapper.removeClass('assist-preloader-ghost');
-          }, 200);
-        }
-
-        clearTimeout(renderThrottle);
-        var startDiff = Math.abs($parentFVOwnerElement.data('startIndex') - startIndex);
-        var endDiff = Math.abs($parentFVOwnerElement.data('endIndex') - endIndex);
-        if (startDiff > incrementLimit
-          || endDiff > incrementLimit
-          || (startDiff !== 0 && startIndex === 0)
-          || (endDiff !== 0 && endIndex === allEntries.length - 1))  {
-          renderThrottle = setTimeout(render, 0);
-        }
-      };
-
-      huePubSubs.push(huePubSub.subscribe('foreach.visible.update', function (callerId) {
-        if (callerId === id && endIndex > 0) {
-          setStartAndEndFromScrollTop();
-          clearTimeout(renderThrottle);
-          renderThrottle = setTimeout(render, 0);
-        }
-      }));
-
-      $container.bind('scroll', onScroll);
-
-      $parentFVOwnerElement.data('disposalFunction', function () {
-        setTimeout(function () {
-          huePubSub.publish('foreach.visible.update.heights', parentId);
-        }, 0);
-        huePubSubs.forEach(function (pubSub) {
-          pubSub.remove();
-        });
-        $container.unbind('scroll', onScroll);
-        clearInterval(updateCountInterval);
-        clearInterval(updateHeightsInterval);
-        $parentFVOwnerElement.data('disposalFunction', null);
-      });
-
-      if (typeof options.pubSubDispose !== 'undefined') {
-        huePubSubs.push(huePubSub.subscribe(options.pubSubDispose, $parentFVOwnerElement.data('disposalFunction')));
-      }
-
-      ko.utils.domNodeDisposal.addDisposeCallback($wrapper[0], $parentFVOwnerElement.data('disposalFunction'));
-
-      setStartAndEndFromScrollTop();
-      render();
-    }
-  };
-  ko.expressionRewriting.bindingRewriteValidators['foreachVisible'] = false;
-  ko.virtualElements.allowedBindings['foreachVisible'] = true;
-
-  ko.bindingHandlers.hueach = {
-    init: function (element, valueAccessor, allBindings) {
-      var valueAccessorBuilder = function () {
-        return {
-          data: ko.observableArray([])
-        }
-      };
-      ko.bindingHandlers.foreach.init(element, valueAccessorBuilder, allBindings);
-    },
-    update: function (element, valueAccessor, allBindings, viewModel, bindingContext) {
-      var $element = $(element),
-        $parent = $element.parent(),
-        data = typeof valueAccessor().data === 'function' ? valueAccessor().data() : valueAccessor().data,
-        considerStretching = valueAccessor().considerStretching || false,
-        itemHeight = valueAccessor().itemHeight || 22,
-        scrollable = valueAccessor().scrollable || 'body',
-        scrollUp = valueAccessor().scrollUp || false,
-        scrollableOffset = valueAccessor().scrollableOffset || 0,
-        disableHueEachRowCount = valueAccessor().disableHueEachRowCount || 0,
-        forceRenderSub = valueAccessor().forceRenderSub || null,
-        renderTimeout = -1,
-        dataHasChanged = true;
-
-      var wrappable = $(element);
-      if (data.length > disableHueEachRowCount) {
-        if ($parent.is('table')) {
-          wrappable = $parent;
-          $parent = wrappable.parent();
-        }
-
-        if (!wrappable.parent().hasClass('hueach')) {
-          wrappable.wrap('<div class="hueach"></div>');
-          $parent = wrappable.parent();
-          wrappable.css({
-            position: 'absolute',
-            width: '100%'
-          });
-        }
-
-        $parent.height(data.length * itemHeight);
-        if (wrappable.is('table')) {
-          $parent.height($parent.height() + (data.length > 0 ? itemHeight : 0));
-        }
-      }
-
-      try {
-        if (ko.utils.domData.get(element, 'originalData') && JSON.stringify(ko.utils.domData.get(element, 'originalData')) === JSON.stringify(data)) {
-          dataHasChanged = false;
-        }
-      }
-      catch (e) {
-      }
-
-      if (dataHasChanged) {
-        ko.utils.domData.set(element, 'originalData', data);
-      }
-
-      var startItem = 0, endItem = 0;
-      var valueAccessorBuilder = function () {
-        return {
-          data: ko.utils.domData.get(element, 'originalData') ? ko.observableArray(ko.utils.domData.get(element, 'originalData').slice(startItem, endItem)) : []
-        }
-      }
-
-      var render = function () {
-        if ($parent.parents('.hueach').length === 0) {
-          var heightCorrection = 0, fluidCorrection = 0;
-          var scrollTop = $parent.parents(scrollable).scrollTop();
-          if (wrappable.is('table')) {
-            if (scrollTop < scrollableOffset + itemHeight) {
-              wrappable.find('thead').css('opacity', '1');
-            }
-            else {
-              wrappable.find('thead').css('opacity', '0');
-            }
-          }
-          else {
-            wrappable.children(':visible').each(function (cnt, child) {
-              if ($(child).height() >= itemHeight) {
-                heightCorrection += $(child).height();
-              }
-            });
-            if (heightCorrection > 0) {
-              ko.utils.domData.set(element, 'heightCorrection', heightCorrection);
-            }
-            if (heightCorrection == 0 && ko.utils.domData.get(element, 'heightCorrection')) {
-              fluidCorrection = ko.utils.domData.get(element, 'heightCorrection') - 20;
-            }
-          }
-          startItem = Math.max(0, Math.floor(Math.max(1, (scrollTop - heightCorrection - fluidCorrection - scrollableOffset)) / itemHeight) - 10);
-          if (wrappable.is('table') && startItem % 2 == 1) {
-            startItem--;
-          }
-          endItem = Math.min(startItem + Math.ceil($parent.parents(scrollable).height() / itemHeight) + 20, data.length);
-          wrappable.css('top', ((startItem * itemHeight) + fluidCorrection) + 'px');
-        }
-        else {
-          startItem = 0, endItem = data.length;
-        }
-        bindingContext.$indexOffset = function () {
-          return startItem
-        }
-        ko.bindingHandlers.foreach.update(element, valueAccessorBuilder, allBindings, viewModel, bindingContext);
-      }
-
-
-      $parent.parents(scrollable).off('scroll');
-      huePubSub.publish('scrollable.scroll.off', scrollable);
-
-      $parent.parents(scrollable).on('scroll', render);
-      if (scrollUp){
-        $parent.parents(scrollable).jHueScrollUp();
-      }
-
-      if ($parent.parents('.hueach').length > 0) {
-        window.setTimeout(render, 100);
-      }
-
-      if (considerStretching) {
-        huePubSub.subscribe('assist.stretchDown', function () {
-          window.clearTimeout(renderTimeout);
-          renderTimeout = window.setTimeout(function () {
-            ko.utils.domData.set(element, 'hasStretched', true);
-            render();
-          }, 300);
-        });
-      }
-
-      if (forceRenderSub) {
-        huePubSub.subscribe(forceRenderSub, function () {
-          window.setTimeout(render, 300);
-        });
-      }
-
-      window.clearTimeout(renderTimeout);
-      renderTimeout = window.setTimeout(function () {
-        ko.utils.domData.set(element, 'hasStretched', true);
-        render();
-      }, 300);
-
-    }
-  };
-
-  ko.bindingHandlers.plotly = {
-    init: function (element, valueAccessor, allBindings) {
-      var options = valueAccessor() || {};
-      if (Plotly){
-        Plotly.plot(element, options.data || [], options.layout || {}, {displaylogo: false});
-      }
-    }
-  };
-
-  ko.bindingHandlers.dockable = {
-    init: function (element, valueAccessor, allBindings) {
-      var options = valueAccessor() || {};
-      var scrollable = options.scrollable ? options.scrollable : window;
-      var triggerAdjust = options.triggerAdjust || 0;
-      var zIndex = options.zIndex || 1000;
-      $(element).addClass('dockable');
-
-      var initialTopPosition = -1;
-      var initialSize = {
-        w: $(element).width() - hueUtils.scrollbarWidth(),
-        h: $(element).outerHeight() + (options.jumpCorrection || 0)
-      };
-
-      var ghost = $('<div>').css({'display': 'none', 'height': initialSize.h}).insertBefore($(element));
-
-      function dock() {
-        if (initialTopPosition == -1) {
-          initialTopPosition = $(element).position().top;
-          ghost.height($(element).outerHeight() + (options.jumpCorrection || 0));
-        }
-        if ($(scrollable).scrollTop() + triggerAdjust > initialTopPosition) {
-          $(element).attr('style', 'position: fixed!important; top: ' + options.topSnap + '; width: ' + initialSize.w + 'px!important; z-index: ' + zIndex);
-          ghost.show();
-        }
-        else {
-          $(element).removeAttr('style');
-          ghost.hide();
-        }
-      }
-
-      $(scrollable).on('scroll', dock);
-
-      var scrollOffSubscription = huePubSub.subscribe('scrollable.scroll.off', function (scrollElement) {
-        if (scrollElement === scrollable) {
-          $(scrollable).on('scroll', dock);
-        }
-      });
-
-
-      function resetInitialStyle() {
-        $(element).removeAttr('style');
-        initialSize = {
-          w: $(element).width() - hueUtils.scrollbarWidth(),
-          h: $(element).outerHeight() + (options.jumpCorrection || 0)
-        };
-        dock();
-      }
-
-      $(window).on('resize', resetInitialStyle);
-
-      ko.utils.domNodeDisposal.addDisposeCallback(element, function () {
-        $(window).off('resize', resetInitialStyle);
-        $(scrollable).off('scroll', dock);
-        scrollOffSubscription.remove();
-      });
-
-    }
-  };
-
-  ko.bindingHandlers.autogrowInput = {
-    init: function (element, valueAccessor, allBindingsAccessor, viewModel) {
-      var o = $.extend({
-        minWidth: 0,
-        maxWidth: 1000,
-        comfortZone: 70
-      }, valueAccessor());
-      var minWidth = o.minWidth || $(element).width(),
-        val = '',
-        input = $(element),
-        testSubject = $('<tester/>').css({
-          position: 'absolute',
-          top: -9999,
-          left: -9999,
-          width: 'auto',
-          fontSize: input.css('fontSize'),
-          fontFamily: input.css('fontFamily'),
-          fontWeight: input.css('fontWeight'),
-          letterSpacing: input.css('letterSpacing'),
-          whiteSpace: 'nowrap'
-        }),
-        check = function () {
-          if (val === (val = input.val())) {
-            return;
-          }
-          var escaped = val.replace(/&/g, '&amp;').replace(/\s/g, ' ').replace(/</g, '&lt;').replace(/>/g, '&gt;');
-          testSubject.html(escaped);
-          var testerWidth = testSubject.width(),
-            newWidth = (testerWidth + o.comfortZone) >= minWidth ? testerWidth + o.comfortZone : minWidth,
-            currentWidth = input.width(),
-            isValidWidthChange = (newWidth < currentWidth && newWidth >= minWidth) || (newWidth > minWidth && newWidth < o.maxWidth);
-          if (isValidWidthChange) {
-            input.width(newWidth);
-          }
-        };
-      testSubject.insertAfter(element);
-      ko.utils.registerEventHandler(element, 'keyup keydown blur update', check);
-    }
-  };
-
-  ko.bindingHandlers.readOnlyAce = {
-    init: function (element, valueAccessor, allBindingsAccessor) {
-      $(element).css({
-        'min-height': '250px'
-      });
-      var editor = ace.edit(element);
-      editor.setOptions({
-        readOnly: true,
-        maxLines: Infinity
-      });
-      editor.setTheme($.totalStorage("hue.ace.theme") || "ace/theme/hue");
-      $(element).data('aceEditor', editor);
-    },
-    update: function (element, valueAccessor, allBindingsAccessor) {
-      var value = ko.unwrap(valueAccessor());
-      var options = ko.unwrap(allBindingsAccessor());
-      $(element).data('aceEditor').getSession().setMode("ace/mode/" + options.type || 'xml'); // e.g. xml, json...
-      if (typeof value !== 'undefined' && value !== '') { // allows highlighting static code
-        if (options.path) {
-          value = value[options.path];
-        }
-        $(element).data('aceEditor').setValue(value, -1)
-      }
-    }
-  };
-
-  ko.bindingHandlers.highlight = {
-    init: function (element) {
-      $(element).addClass('ace-highlight');
-    },
-    update: function (element, valueAccessor) {
-      var options = $.extend({
-        dialect: 'hive',
-        value: '',
-        formatted: false
-      }, valueAccessor());
-
-      var value = ko.unwrap(options.value);
-
-      if (typeof value !== 'undefined' && value !== '') { // allows highlighting static code
-        if (options.path) {
-          value = value[options.path];
-        }
-        ace.require([
-          'ace/mode/impala_highlight_rules',
-          'ace/mode/hive_highlight_rules',
-          'ace/mode/xml_highlight_rules',
-          'ace/tokenizer',
-          'ace/layer/text',
-          'ace/config'
-        ], function (impalaRules, hiveRules, xmlRules, tokenizer, text, config) {
-          var res = [];
-
-          var Tokenizer = tokenizer.Tokenizer;
-          var Rules = hiveRules.HiveHighlightRules;
-          if (options.dialect && ko.unwrap(options.dialect) == 'impala') {
-            Rules = impalaRules.ImpalaHighlightRules;
-          }
-
-          config.loadModule(["theme", $.totalStorage("hue.ace.theme") || "ace/theme/hue"]);
-
-          var Text = text.Text;
-
-          var tok = new Tokenizer(new Rules().getRules());
-          var lines = value.split('\n');
-
-          var renderSimpleLine = function(txt, stringBuilder, tokens) {
-            var screenColumn = 0;
-            var token = tokens[0];
-            var value = token.value;
-            if (value) {
-              screenColumn = txt.$renderToken(stringBuilder, screenColumn, token, value);
-            }
-            for (var i = 1; i < tokens.length; i++) {
-              token = tokens[i];
-              value = token.value;
-              try {
-                screenColumn = txt.$renderToken(stringBuilder, screenColumn, token, value);
-              }
-              catch (e) {
-                if (console && console.warn) {
-                  console.warn(value, 'This token has some parsing errors and it has been rendered without highlighting.');
-                }
-                stringBuilder.push(value);
-                screenColumn = screenColumn + value.length;
-              }
-            }
-          };
-
-          var additionalClass = '';
-          if (!options.splitLines && !options.formatted) {
-            additionalClass = 'pull-left';
-          } else if (options.formatted) {
-            additionalClass = 'ace-highlight-pre';
-          }
-
-          lines.forEach(function (line) {
-            var renderedTokens = [];
-            var tokens = tok.getLineTokens(line);
-
-            if (tokens && tokens.tokens.length) {
-              renderSimpleLine(new Text(document.createElement('div')), renderedTokens, tokens.tokens);
-            }
-
-            res.push('<div class="ace_line ' + additionalClass + '">' + renderedTokens.join('') + '&nbsp;</div>');
-          });
-
-          element.innerHTML = '<div class="ace_editor ace-hue"' +
-            (options.enableOverflow ? ' style="overflow: initial !important;"' : '') +
-            '><div class="ace_layer" style="position: static;' +
-            (options.enableOverflow ? ' overflow: initial !important;' : '') +
-            '">' + res.join('') + '</div></div>';
-          if (options.enableOverflow) {
-            $(element).css({ 'overflow': 'auto' });
-          }
-          $(element).find('.ace_invisible_space').remove();
-        });
-      }
-
-
-    }
-  };
-
-  ko.bindingHandlers.ellipsis = {
-    update: function (element, valueAccessor, allBindingsAccessor) {
-      var value = ko.unwrap(valueAccessor());
-      var $element = $(element);
-      var chopLength = value.length ? value.length : 30;
-      var text = typeof value === 'object' ? value.data : value;
-      if (text.length > chopLength) {
-        $element.attr('title', text);
-        $element.text(text.substr(0, chopLength) + '...');
-      }
-      else {
-        $element.text(text);
-      }
-    }
-  };
-
-  ko.bindingHandlers.select2Version4 = {
-    init: function (el, valueAccessor, allBindingsAccessor, viewModel) {
-      ko.utils.domNodeDisposal.addDisposeCallback(el, function () {
-        $(el).select2('destroy');
-      });
-
-      var allBindings = allBindingsAccessor(),
-        select2 = ko.utils.unwrapObservable(allBindings.select2Version4);
-
-      $(el).select2(select2);
-    },
-    update: function (el, valueAccessor, allBindingsAccessor, viewModel) {
-      var allBindings = allBindingsAccessor();
-
-      if ("value" in allBindings) {
-        if ((allBindings.select2Version4.multiple || el.multiple) && allBindings.value().constructor != Array) {
-          $(el).val(allBindings.value().split(',')).trigger('change');
-        }
-        else {
-          $(el).val(allBindings.value()).trigger('change');
-        }
-      } else if ("selectedOptions" in allBindings) {
-        var converted = [];
-        var textAccessor = function (value) {
-          return value;
-        };
-        if ("optionsText" in allBindings) {
-          textAccessor = function (value) {
-            var valueAccessor = function (item) {
-              return item;
-            }
-            if ("optionsValue" in allBindings) {
-              valueAccessor = function (item) {
-                return item[allBindings.optionsValue];
-              }
-            }
-            var items = $.grep(allBindings.options(), function (e) {
-              return valueAccessor(e) == value
-            });
-            if (items.length == 0 || items.length > 1) {
-              return "UNKNOWN";
-            }
-            return items[0][allBindings.optionsText];
-          }
-        }
-        $.each(allBindings.selectedOptions(), function (key, value) {
-          converted.push({id: value, text: textAccessor(value)});
-        });
-        $(el).select2("data", converted);
-      }
-    }
-  };
-
-
-  ko.bindingHandlers.momentFromNow = {
-    update: function (element, valueAccessor) {
-      var options = ko.unwrap(valueAccessor());
-      var $element = $(element);
-
-      var value = typeof options.data === 'function' ? options.data() : options.data;
-
-      function render() {
-        $element.text(moment(value).fromNow());
-        if (options.titleFormat) {
-          $element.attr('title', moment(value).format(options.titleFormat));
-        }
-      }
-
-      render();
-
-      if (options.interval) {
-        window.clearInterval($element.data('momentInterval'));
-        $element.data('momentInterval', window.setInterval(render, options.interval));
-      }
-    }
-  };
-
-  ko.bindingHandlers.moment = {
-    update: function (element, valueAccessor) {
-      var options = ko.unwrap(valueAccessor());
-      var $element = $(element);
-
-      var value = typeof options.data === 'function' ? options.data() : options.data;
-
-      function render() {
-        var fMoment = moment(value);
-        var text;
-        if (!fMoment.isValid()) {
-          text = value;
-        } else {
-          if (options.format) {
-            text = fMoment.format(options.format);
-          }
-          else {
-            text = fMoment.format();
-          }
-        }
-        $element.text(text);
-      }
-      render();
-    }
-  };
-
-
-  ko.bindingHandlers.attachViewModelToElementData = {
-    init: function (el, valueAccessor, allBindingsAccessor, viewModel) {
-      $(el).data('__ko_vm', viewModel);
-    }
-  };
-
-  ko.bindingHandlers.hdfsTree = {
-    update: function (element, valueAccessor) {
-      var options = ko.unwrap(valueAccessor());
-      var $element = $(element);
-
-      $element.empty();
-
-      var value = typeof options.data === 'function' ? options.data() : options.data;
-      $element.jHueHdfsTree({
-        home: '',
-        isS3: !!options.isS3,
-        root: options.root,
-        initialPath: options.path,
-        withTopPadding: false,
-        onPathChange: function (path) {
-          options.selectedPath(path);
-        }
-      });
-
-    }
-  };
-
-  ko.bindingHandlers.documentChooser = {
-    init: function (element, valueAccessor) {
-      var options = valueAccessor();
-      var TYPE_MAP = {
-        'hive': 'query-hive',
-        'impala': 'query-impala',
-        'java': 'query-java',
-        'spark': 'query-spark2',
-        'pig': 'query-pig',
-        'sqoop': 'query-sqoop1',
-        'distcp-doc': 'query-distcp',
-        'shell-doc': 'query-shell',
-        'mapreduce-doc': 'query-mapreduce',
-        'hive-document-widget': 'query-hive',
-        'impala-document-widget': 'query-impala',
-        'java-document-widget': 'query-java',
-        'spark-document-widget': 'query-spark2',
-        'pig-document-widget': 'query-pig',
-        'sqoop-document-widget': 'query-sqoop1',
-        'distcp-document-widget': 'query-distcp',
-        'shell-document-widget': 'query-shell',
-        'mapreduce-document-widget': 'query-mapreduce',
-      }
-      var type = 'query-hive';
-      if (options.type) {
-        var tempType = ko.unwrap(options.type);
-        if (tempType === 'function') {
-          tempType = tempType();
-        }
-        type = TYPE_MAP[tempType] ? TYPE_MAP[tempType] : tempType;
-      }
-      var firstLoad = false;
-      $(element).selectize({
-        valueField: 'uuid',
-        labelField: 'name',
-        searchField: 'name',
-        options: [],
-        create: false,
-        preload: true,
-        dropdownParent: 'body',
-        render: {
-          option: function (item, escape) {
-            return '<div>' +
-              '<strong>' + escape(item.name) + '</strong><br>' +
-              '<span class="muted">' + escape(item.description) + '</span>' +
-              '</div>';
-          }
-        },
-        load: function (query, callback) {
-          if (query === '' && options.value && !firstLoad){
-            firstLoad = true;
-          }
-          window.apiHelper.searchDocuments({
-            type: type,
-            text: query,
-            include_trashed: false,
-            limit: 100,
-            successCallback: function(data){
-              callback(data.documents)
-            }
-          });
-        },
-        onChange: function (val) {
-          if (options.value) {
-            options.value(val);
-          }
-          if (options.document) {
-            options.document(this.options[val]);
-          }
-          if (options.mappedDocument) {
-            options.mappedDocument(ko.mapping.fromJS(this.options[val]));
-          }
-        },
-        onLoad: function () {
-          if (options.value) {
-            this.setValue(options.value());
-          }
-          if (options.loading) {
-            options.loading(false);
-          }
-        },
-      });
-    },
-
-    update: function (element, valueAccessor) {
-      var options = valueAccessor();
-      if (options.value) {
-        element.selectize.setValue(options.value());
-      }
-      if (options.dependentValue && options.dependentValue() !== '') {
-        element.selectize.setValue(options.dependentValue());
-        options.dependentValue('');
-      }
-    }
-  };
-
-  ko.bindingHandlers.tagsNotAllowed = {
-    update: function (element, valueAccessor, allBindingsAccessor) {
-      var $element = $(element);
-      var params = allBindingsAccessor();
-      var valueObservable = ko.isObservable(params) ? params : (params.textInput ? params.textInput : params.value);
-      var value = valueObservable();
-      var escaped = value.replace(/<|>/g, '');
-      if (escaped !== value){
-        $element.val(escaped);
-      }
-    }
-  };
-
-  ko.bindingHandlers.truncatedText = {
-    update: function (element, valueAccessor, allBindingsAccessor) {
-      var text = ko.isObservable(valueAccessor()) ? ko.utils.unwrapObservable(valueAccessor()) : valueAccessor();
-      var length = ko.utils.unwrapObservable(allBindingsAccessor().maxLength) || 20;
-      var truncated = '';
-      if (typeof text !== 'undefined' && text !== null){
-        truncated = text.length > length ? text.substring(0, length) + '...' : text;
-      }
-      ko.bindingHandlers.text.update(element, function () {
-        return truncated;
-      });
-    }
-  };
-
-  ko.bindingHandlers.parseArguments = {
-    init: function (element, valueAccessor, allBindingsAccessor) {
-      var $el = $(element);
-
-      function splitStrings(str) {
-        var bits = [];
-        var isInQuotes = false;
-        var tempStr = '';
-        str.replace(/<\/?arg>|<\/?command>/gi, ' ').replace(/\r?\n|\r/g, '').replace(/\s\s+/g, ' ').split('').forEach(function (char) {
-          if (char == '"' || char == "'") {
-            isInQuotes = !isInQuotes;
-          }
-          else if ((char == ' ' || char == '\n') && !isInQuotes && tempStr != '') {
-            bits.push(tempStr);
-            tempStr = '';
-          }
-          else {
-            tempStr += char;
-          }
-        });
-        if (tempStr != '') {
-          bits.push(tempStr);
-        }
-        return bits;
-      }
-
-      $el.bind('paste', function (e) {
-        var pasted = e.originalEvent.clipboardData.getData('text');
-        var args = splitStrings(pasted);
-        if (args.length > 1) {
-          var newList = [];
-          args.forEach(function (arg) {
-            var obj = {};
-            obj[valueAccessor().objectKey] = $.trim(arg);
-            newList.push(obj);
-          });
-          valueAccessor().list(ko.mapping.fromJS(newList)());
-          valueAccessor().callback();
-        }
-      });
-    }
-  };
-
-
-  var aceInstancesById = {},
-    aceInitId = 0;
-
-  ko.bindingHandlers.ace = {
-    init: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
-
-      var options = allBindingsAccessor().aceOptions || {};
-      var value = ko.utils.unwrapObservable(valueAccessor());
-
-      if (!element.id) {
-        element.id = 'knockoutAce' + aceInitId;
-        aceInitId = aceInitId + 1;
-      }
-
-      var editor = ace.edit(element.id);
-
-      editor.setOptions(options);
-
-      if (options.theme) {
-        editor.setTheme('ace/theme/' + options.theme);
-      } else {
-        editor.setTheme('ace/theme/hue');
-      }
-      if (options.mode) {
-        editor.getSession().setMode('ace/mode/' + options.mode);
-      }
-      if (options.readOnly) {
-        editor.setReadOnly(true);
-      }
-
-      editor.setValue(value);
-      editor.gotoLine(0);
-
-      editor.getSession().on('change', function (delta) {
-        if (ko.isWriteableObservable(valueAccessor())) {
-          valueAccessor()(editor.getValue());
-        }
-      });
-
-      aceInstancesById[element.id] = editor;
-
-      ko.utils.domNodeDisposal.addDisposeCallback(element, function () {
-        editor.destroy();
-        delete aceInstancesById[element.id];
-      });
-    },
-    update: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
-      var value = ko.utils.unwrapObservable(valueAccessor());
-      var id = element.id;
-
-      if (typeof id !== 'undefined' && id !== '' && aceInstancesById.hasOwnProperty(id)) {
-        var editor = aceInstancesById[id];
-        var content = editor.getValue();
-        if (content !== value) {
-          editor.setValue(value);
-          editor.gotoLine(0);
-        }
-      }
-    }
-  };
-
-  ko.aceEditors = {
-    resizeAll: function () {
-      for (var id in aceInstancesById) {
-        if (!aceInstancesById.hasOwnProperty(id)) continue;
-        var editor = aceInstancesById[id];
-        editor.resize();
-      }
-    },
-    get: function (id) {
-      return aceInstancesById[id];
-    }
-  };
-
-  ko.bindingHandlers.dropzone = {
-    init: function (element, valueAccessor) {
-      var value = ko.unwrap(valueAccessor());
-      if (value.disabled) {
-        return;
-      }
-      var options = {
-        autoDiscover: false,
-        maxFilesize: 5000000,
-        previewsContainer: '#progressStatusContent',
-        previewTemplate: '<div class="progress-row">' +
-        '<span class="break-word" data-dz-name></span>' +
-        '<div class="pull-right">' +
-        '<span class="muted" data-dz-size></span>&nbsp;&nbsp;' +
-        '<span data-dz-remove><a href="javascript:undefined;" title="' + HUE_I18n.dropzone.cancelUpload + '"><i class="fa fa-fw fa-times"></i></a></span>' +
-          '<span style="display: none" data-dz-uploaded><i class="fa fa-fw fa-check muted"></i></span>' +
-        '</div>' +
-        '<div class="progress-row-bar" data-dz-uploadprogress></div>' +
-        '</div>',
-        sending: function (e) {
-          $('.hoverMsg').addClass('hide');
-          $('#progressStatus').removeClass('hide');
-          $('#progressStatusBar').removeClass('hide');
-          $('#progressStatus .progress-row').remove();
-          $('#progressStatusBar div').css('width', '0');
-        },
-        uploadprogress: function (file, progress) {
-          $('[data-dz-name]').each(function (cnt, item) {
-            if ($(item).text() === file.name) {
-              $(item).parents('.progress-row').find('[data-dz-uploadprogress]').width(progress.toFixed() + '%');
-              if (progress.toFixed() === '100') {
-                $(item).parents('.progress-row').find('[data-dz-remove]').hide();
-                $(item).parents('.progress-row').find('[data-dz-uploaded]').show();
-              }
-            }
-          });
-        },
-        totaluploadprogress: function (progress) {
-          $('#progressStatusBar div').width(progress.toFixed() + "%");
-        },
-        canceled: function () {
-          $.jHueNotify.info(HUE_I18n.dropzone.uploadCanceled);
-        },
-        complete: function (file) {
-          if (file.xhr.response != '') {
-            var response = JSON.parse(file.xhr.response);
-            if (response && response.status != null) {
-              if (response.status != 0) {
-                $(document).trigger('error', response.data);
-                if (value.onError) {
-                  value.onError(file.name);
-                }
-              }
-              else {
-                $(document).trigger('info', response.path + ' ' + HUE_I18n.dropzone.uploadSucceeded);
-                if (value.onComplete) {
-                  value.onComplete(response.path);
-                }
-              }
-            }
-          }
-        },
-        queuecomplete: function () {
-          window.setTimeout(function () {
-            $('#progressStatus').addClass('hide');
-            $('#progressStatusBar').addClass('hide');
-            $('#progressStatusBar div').css('width', '0');
-          }, 2500);
-        },
-        createImageThumbnails: false
-      };
-
-      $.extend(options, value);
-
-      $(element).addClass('dropzone');
-      
-      $(element).on('click', function (e) {
-        e.stopPropagation();
-      });
-
-      new Dropzone(element, options);
-    }
-  };
-
-  ko.bindingHandlers.jHueRowSelector = {
-    init: function (element, valueAccessor) {
-      $(element).jHueRowSelector();
-    }
-  };
-
-  //https://stackoverflow.com/questions/19865364/knockoutjs-linking-value-from-a-input-to-a-datalist-value
-  ko.bindingHandlers.datalist = (function () {
-    function getVal(rawItem, prop) {
-      var item = ko.unwrap(rawItem);
-      return item && prop ? ko.unwrap(item[prop]) : item;
-    }
-
-    function findItem(options, prop, ref) {
-      return ko.utils.arrayFirst(options, function (item) {
-        return ref === getVal(item, prop);
-      });
-    }
-    return {
-      init: function (element, valueAccessor, allBindingsAccessor) {
-        var setup = valueAccessor(),
-          textProperty = ko.unwrap(setup.optionsText),
-          valueProperty = ko.unwrap(setup.optionsValue),
-          dataItems = ko.unwrap(setup.options),
-          myValue = setup.value,
-          koValue = allBindingsAccessor().value,
-          datalist = document.createElement("DATALIST");
-
-        // create an associated <datalist> element
-        datalist.id = element.getAttribute("list");
-        document.body.appendChild(datalist);
-
-        // when the value is changed, write to the associated myValue observable
-        function onNewValue(newVal) {
-          var setup = valueAccessor(),
-            dataItems = ko.unwrap(setup.options),
-            selectedItem = findItem(dataItems, textProperty, newVal),
-            newValue = selectedItem ? getVal(selectedItem, valueProperty) : newVal;
-
-          if (ko.isWriteableObservable(myValue)) {
-            myValue(newValue);
-          }
-        }
-
-        // listen for value changes
-        // - either via KO's value binding (preferred) or the change event
-        if (ko.isSubscribable(koValue)) {
-          var onNewValueSubscription = koValue.subscribe(onNewValue);
-          ko.utils.domNodeDisposal.addDisposeCallback(element, function() {
-            onNewValueSubscription.remove();
-          });
-        } else {
-          var event = allBindingsAccessor().valueUpdate === "afterkeydown" ? "input" : "change";
-          ko.utils.registerEventHandler(element, event, function () {
-            onNewValue(this.value);
-          });
-        }
-
-        // init the element's value
-        // - either via the myValue observable (preferred) or KO's value binding
-        if (ko.isObservable(myValue) && myValue()) {
-          var selectedItem = findItem(dataItems, valueProperty, myValue());
-          element.value = selectedItem ? getVal(selectedItem, textProperty) : myValue();
-        } else if (ko.isObservable(koValue) && koValue()) {
-          onNewValue(koValue());
-        }
-      },
-      update: function (element, valueAccessor) {
-        var setup = valueAccessor(),
-          datalist = element.list,
-          dataItems = ko.unwrap(setup.options),
-          textProperty = ko.unwrap(setup.optionsText);
-
-        // rebuild list of options when an underlying observable changes
-        datalist.innerHTML = "";
-        ko.utils.arrayForEach(dataItems, function (item) {
-          var option = document.createElement("OPTION");
-          option.value = getVal(item, textProperty);
-          datalist.appendChild(option);
-        });
-        ko.utils.triggerEvent(element, "change");
-      }
-    };
-  })();
-
-  ko.bindingHandlers.impalaDagre = (function () {
-    return {
-      init: function (element, valueAccessor, allBindingsAccessor) {
-        var id = $(element).attr("id");
-        var self = this;
-        element._impalaDagre = impalaDagre(id);
-        var clickSubscription = huePubSub.subscribe('impala.node.moveto', function(value) {
-          element._impalaDagre.moveTo(value);
-        });
-        var selectSubscription = huePubSub.subscribe('impala.node.select', function(value) {
-          element._impalaDagre.select(value);
-        });
-        ko.utils.domNodeDisposal.addDisposeCallback(element, function () {
-          clickSubscription.remove();
-          selectSubscription.remove();
-        });
-      },
-      update: function (element, valueAccessor) {
-        var props = ko.unwrap(valueAccessor());
-        element._impalaDagre.metrics(props.metrics);
-        element._impalaDagre.height(props.height);
-        element._impalaDagre.update(props.value);
-      }
-    };
-  })();
-
-  ko.bindingHandlers.dropdown = {
-    init: function (element, valueAccessor) {
-        $(element).dropdown();
-    }
-  };
-
-  ko.bindingHandlers.numberFormat = (function() {
-    var that;
-    return that = {
-      init: function (element, valueAccessor) {
-        that.format(element, valueAccessor);
-      },
-      update: function (element, valueAccessor) {
-        that.format(element, valueAccessor);
-      },
-      format: function (element, valueAccessor) {
-        var value = valueAccessor();
-        var unwrapped = ko.unwrap(value);
-        $(element).text(that.human(unwrapped.value, unwrapped.unit));
-      },
-      human: function (value, unit) {
-        var fn;
-        if (unit === 1) {
-          fn = function(value) { return ko.bindingHandlers.simplesize.humanSize(value) + '/s'; }
-        } else if (unit === 3) {
-          fn = ko.bindingHandlers.bytesize.humanSize
-        } else if (unit === 4) {
-          fn = function(value) { return ko.bindingHandlers.bytesize.humanSize(value) + '/s'; }
-        } else if (unit === 5) {
-          fn = ko.bindingHandlers.duration.humanTime
-        } else if (unit === 8) {
-          fn = function (value) { return ko.bindingHandlers.duration.humanTime(value * 1000000); }
-        } else if (unit === 9) {
-          fn = function (value) { return ko.bindingHandlers.duration.humanTime(value * 1000000000); }
-        } else {
-          fn = ko.bindingHandlers.simplesize.humanSize
-        }
-        return fn(value);
-      }
-    }
-  })();
-
-  ko.bindingHandlers.duration = (function() {
-    var that;
-    return that = {
-      init: function (element, valueAccessor) {
-        that.format(element, valueAccessor);
-      },
-      update: function (element, valueAccessor) {
-        that.format(element, valueAccessor);
-      },
-      format: function (element, valueAccessor) {
-        var value = valueAccessor();
-        var formatted = that.humanTime(ko.unwrap(value));
-        $(element).text(formatted);
-      },
-      humanTime: function (value) {
-        value = value * 1;
-        if (value < Math.pow(10, 3)) {
-          return sprintf("%i ns", value);
-        } else if (value - Math.pow(10, 6) < -Math.pow(10, 3) / 2) { // Make sure rounding doesn't cause numbers to have more than 4 significant digits.
-          value = (value * 1.0) / Math.pow(10, 3);
-          var sprint = value > 100 ? "%i us" : "%.1f us";
-          return sprintf(sprint, value);
-        } else if (value - Math.pow(10, 9) < -Math.pow(10, 6) / 2) {
-          value = (value * 1.0) / Math.pow(10, 6);
-          var sprint = value > 100 ? "%i ms" : "%.1f ms";
-          return sprintf(sprint, value);
-        } else {
-          // get the ms value
-          var SECOND = 1;
-          var MINUTE = SECOND * 60;
-          var HOUR = MINUTE * 60;
-          value = value * 1 / Math.pow(10, 9);
-          var buffer = "";
-
-          if (value > (HOUR)) {
-            buffer += sprintf("%i h", value / HOUR);
-            value = value % HOUR;
-          }
-
-          if (buffer.length < 4 && value > MINUTE) {
-            var sprint = buffer.length ? " %i m" : "%i m";
-            buffer += sprintf(sprint, value / MINUTE);
-            value = value % MINUTE;
-          }
-
-          if (buffer.length < 4 && value > SECOND) {
-            var sprint = buffer.length ? " %i s" : "%.1f s";
-            buffer += sprintf(sprint, value * 1.0 / SECOND);
-          }
-          return buffer;
-        }
-      }
-    };
-  })();
-
-  ko.bindingHandlers.bytesize = (function() {
-    var that;
-    return that = {
-      units: ["B", "KB", "MB", "GB", "TB", "PB"],
-      init: function (element, valueAccessor) {
-        that.format(element, valueAccessor);
-      },
-      update: function (element, valueAccessor) {
-        that.format(element, valueAccessor);
-      },
-      format: function (element, valueAccessor) {
-        var value = valueAccessor();
-        var formatted = that.humanSize(ko.unwrap(value));
-        $(element).text(formatted);
-      },
-      getBaseLog: function(x, y) {
-        return Math.log(x) / Math.log(y);
-      },
-      humanSize: function(bytes) {
-        var isNumber = !isNaN(parseFloat(bytes)) && isFinite(bytes);
-        if (!isNumber) {
-          return '';
-        }
-
-        // Special case small numbers (including 0), because they're exact.
-        if (bytes < 1024) {
-          return sprintf("%d B", bytes);
-        }
-
-        var index = Math.floor(that.getBaseLog(bytes, 1024));
-        index = Math.min(that.units.length - 1, index);
-        return sprintf("%.1f %s", bytes / Math.pow(1024, index), that.units[index])
-      }
-    };
-  })();
-
-  ko.bindingHandlers.simplesize = (function() {
-    var that;
-    return that = {
-      units: ["", "K", "M", "G", "T", "P"],
-      init: function (element, valueAccessor) {
-        that.format(element, valueAccessor);
-      },
-      update: function (element, valueAccessor) {
-        that.format(element, valueAccessor);
-      },
-      format: function (element, valueAccessor) {
-        var value = valueAccessor();
-        var formatted = that.humanSize(ko.unwrap(value));
-        $(element).text(formatted);
-      },
-      getBaseLog: function(x, y) {
-        return Math.log(x) / Math.log(y);
-      },
-      humanSize: function(bytes) {
-        var isNumber = !isNaN(parseFloat(bytes)) && isFinite(bytes);
-        if (!isNumber) {
-          return '';
-        }
-
-        // Special case small numbers (including 0), because they're exact.
-        if (bytes < 1000) {
-          return sprintf("%d", bytes);
-        }
-
-        var index = Math.floor(that.getBaseLog(bytes, 1000));
-        index = Math.min(that.units.length - 1, index);
-        return sprintf("%.1f %s", bytes / Math.pow(1000, index), that.units[index])
-      }
-    };
-  })();
-
-})();

+ 0 - 219
desktop/core/src/desktop/static/desktop/js/ko.selectize.js

@@ -1,219 +0,0 @@
-// Licensed to Cloudera, Inc. under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  Cloudera, Inc. 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.
-
-// Based on https://gist.githubusercontent.com/xtranophilist/8001624/raw/ko_selectize.js
-
-var inject_binding = function (allBindings, key, value) {
-  //https://github.com/knockout/knockout/pull/932#issuecomment-26547528
-  return {
-    has: function (bindingKey) {
-      return (bindingKey == key) || allBindings.has(bindingKey);
-    },
-    get: function (bindingKey) {
-      var binding = allBindings.get(bindingKey);
-      if (bindingKey == key) {
-        binding = binding ? [].concat(binding, value) : value;
-      }
-      return binding;
-    }
-  };
-}
-
-ko.bindingHandlers.browserAwareSelectize = {
-  init: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
-    (window.isIE11 ? ko.bindingHandlers.options : ko.bindingHandlers.selectize).init.apply(null, arguments);
-  },
-  update: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
-    (window.isIE11 ? ko.bindingHandlers.options : ko.bindingHandlers.selectize).update.apply(null, arguments);
-  }
-}
-
-ko.bindingHandlers.selectize = {
-  init: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
-    if (typeof allBindingsAccessor.get('optionsCaption') == 'undefined')
-      allBindingsAccessor = inject_binding(allBindingsAccessor, 'optionsCaption', HUE_I18n.selectize.choose);
-
-    ko.bindingHandlers.options.update(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext);
-
-    var options = {};
-
-    if (allBindingsAccessor.get('optionsValue')) {
-      options.valueField = allBindingsAccessor.get('optionsValue');
-    }
-
-    if (allBindingsAccessor.get('optionsText')) {
-      options.labelField = allBindingsAccessor.get('optionsText'),
-        options.searchField = allBindingsAccessor.get('optionsText')
-    }
-
-    if (allBindingsAccessor.has('selectizeOptions')) {
-      var passed_options = allBindingsAccessor.get('selectizeOptions')
-      for (var attr_name in passed_options) {
-        if (attr_name === 'maxLength') {
-          options.createFilter = function (input) {
-            return input.length <= passed_options[attr_name]
-          }
-        }
-        else if (attr_name === 'clearable' && passed_options[attr_name]) {
-          options.plugins = ['clear_button'];
-        }
-        else {
-          options[attr_name] = passed_options[attr_name];
-        }
-      }
-    }
-
-    if (!options.hasOwnProperty('dropdownParent')) {
-      options.dropdownParent = 'body';
-    }
-
-    var $select = $(element).selectize(options)[0].selectize;
-
-
-    if (typeof allBindingsAccessor.get('value') == 'function') {
-      $select.addItem(allBindingsAccessor.get('value')());
-      allBindingsAccessor.get('value').subscribe(function (new_val) {
-        $select.addItem(new_val);
-      })
-    }
-
-    if (allBindingsAccessor.get('innerSubscriber')) {
-      valueAccessor()().forEach(function (item) {
-        var previousValue;
-        item[allBindingsAccessor.get('innerSubscriber')].subscribe(function (oldValue) {
-          previousValue = oldValue;
-        }, null, 'beforeChange');
-        item[allBindingsAccessor.get('innerSubscriber')].subscribe(function (newValue) {
-          var newOption = {};
-          newOption[options.valueField] = newValue;
-          newOption[options.labelField] = newValue;
-          $select.updateOption(previousValue, newOption);
-          $select.refreshOptions(false);
-        });
-      });
-    }
-
-    if (typeof allBindingsAccessor.get('selectedOptions') == 'function') {
-      allBindingsAccessor.get('selectedOptions').subscribe(function (new_val) {
-        // Removing items which are not in new value
-        var values = $select.getValue();
-        var items_to_remove = [];
-        for (var k in values) {
-          if (new_val.indexOf(values[k]) == -1) {
-            items_to_remove.push(values[k]);
-          }
-        }
-
-        for (var k in items_to_remove) {
-          $select.removeItem(items_to_remove[k]);
-        }
-
-        for (var k in new_val) {
-          $select.addItem(new_val[k]);
-        }
-
-      });
-      var selected = allBindingsAccessor.get('selectedOptions')();
-      for (var k in selected) {
-        $select.addItem(selected[k]);
-      }
-    }
-
-
-    if (typeof init_selectize == 'function') {
-      init_selectize($select);
-    }
-
-    if (typeof valueAccessor().subscribe == 'function') {
-      valueAccessor().subscribe(function (changes) {
-        // To avoid having duplicate keys, all delete operations will go first
-        var addedItems = new Array();
-        changes.forEach(function (change) {
-          switch (change.status) {
-            case 'added':
-              addedItems.push(change.value);
-              break;
-            case 'deleted':
-              var itemId = change.value[options.valueField];
-              if (typeof itemId === 'function') {
-                itemId = itemId();
-              }
-              if (itemId != null) {
-                $select.removeOption(itemId);
-              }
-          }
-        });
-        addedItems.forEach(function (item) {
-          var optionValue = item[options.valueField];
-          if (typeof optionValue === 'function') {
-            optionValue = optionValue();
-          }
-
-          var optionLabel = item[options.labelField];
-          if (typeof optionLabel === 'function') {
-            optionLabel = optionLabel();
-          }
-
-          var newOption = {};
-          newOption[options.valueField] = optionValue;
-          newOption[options.labelField] = optionLabel;
-
-          $select.addOption(newOption);
-
-          if (allBindingsAccessor.get('innerSubscriber')) {
-            var previousValue;
-            item[allBindingsAccessor.get('innerSubscriber')].subscribe(function (oldValue) {
-              previousValue = oldValue;
-            }, null, 'beforeChange');
-            item[allBindingsAccessor.get('innerSubscriber')].subscribe(function (newValue) {
-              var newOption = {};
-              newOption[options.valueField] = newValue;
-              newOption[options.labelField] = newValue;
-              $select.updateOption(previousValue, newOption);
-              $select.refreshOptions(false);
-            });
-          }
-        });
-
-      }, null, "arrayChange");
-    }
-
-  },
-  update: function (element, valueAccessor, allBindingsAccessor) {
-    var optionsValue = allBindingsAccessor.get('optionsValue') || 'value';
-    var value_accessor = valueAccessor();
-
-    if (allBindingsAccessor.has('selectedObjects')) {
-      allBindingsAccessor.get('selectedObjects')($.grep(value_accessor(), function (i) {
-        var id = i[optionsValue];
-        if (typeof i[optionsValue] == 'function') {
-          id = i[optionsValue]()
-        }
-        return allBindingsAccessor.get('selectedOptions')().indexOf(id) > -1;
-      }));
-    }
-
-    if (allBindingsAccessor.has('object')) {
-      allBindingsAccessor.get('object')($.grep(value_accessor(), function (i) {
-        var id = i[optionsValue];
-        if (typeof i[optionsValue] == 'function') {
-          id = i[optionsValue]()
-        }
-        return id == allBindingsAccessor.get('value')();
-      })[0]);
-    }
-  }
-}

+ 0 - 11
desktop/core/src/desktop/static/desktop/js/ko.switch-case.js

@@ -1,11 +0,0 @@
-/*
- SWITCH/CASE binding for Knockout http://knockoutjs.com/
- (c) Michael Best
- License: MIT (http://www.opensource.org/licenses/mit-license.php)
- Version 2.1.0
- */
-(function(b,k){"function"===typeof define&&define.amd?define(["knockout"],k):k(b.ko)})(this,function(b){function k(a,f){var c=m(f.$switchValueAccessor());return"boolean"==typeof c?a?c:!c:"boolean"==typeof a?a:a instanceof Array?-1!==b.utils.arrayIndexOf(a,c):a==c}function v(a,b){return!k(a,b)}function w(a){return function(){return a}}function h(a,f,c){var n=f?v:k;a||(a="if");c||(c=w);return{flags:d[a].flags,init:function(f,g,l,x,e){if(!e.$switchSkipNextArray)throw Error("case binding must only be used with a switch binding");
-  if(e.$switchIndex!==p)throw Error("case binding cannot be nested");e.$switchIndex=e.$switchSkipNextArray.push(b.observable(!1))-1;e.$caseValue=b.observable();b.computed(function(){var a=e.$switchIndex,b=a===e.$switchSkipNextArray.length-1,c,f,d;a&&e.$switchSkipNextArray[a-1]()?(c=!1,f=!0):(c=m(g()),c===e.$else?(c=e.$switchDefault()||b,f=!1):d=f=c=n(c,e));e.$caseValue(c);e.$switchSkipNextArray[a](f);d?e.$switchDefault(!1):!f&&b&&e.$switchDefault(!0)},null,{disposeWhenNodeIsRemoved:f});if(d[a].init)return d[a].init(f,
-      c(e.$caseValue),l,x,e)},update:function(b,f,g,n,e){if(d[a].update)return d[a].update(b,c(e.$caseValue),g,n,e)}}}function r(a,b,c){g.allowedBindings[a]&&(g.allowedBindings[c]=!0);return h(a,"casenot"===b)}function y(a,b,c){return r(b,a,c)}function s(a,b){d[a]=h("if",b);t[a]=!1;g.allowedBindings[a]=!0;d[a].makeSubkeyHandler=y;d[a].getNamespacedHandler=r}var p;if(!b.virtualElements)throw Error("Switch-case requires at least Knockout 2.1");var g=b.virtualElements,q=b.bindingFlags||{},t=b.bindingRewriteValidators||
-    b.jsonExpressionRewriting.bindingRewriteValidators,m=b.utils.unwrapObservable,d=b.bindingHandlers,u={};d["switch"]={flags:q.contentBind|q.canUseVirtual|q.noValue,init:function(a,f,c,d,k){var h={$switchSkipNextArray:[],$switchValueAccessor:f,$switchDefault:b.observable(!0),$default:u,$else:u},l=[];b.computed(function(){var a=m(f());h.$value=a;b.utils.arrayForEach(l,function(b){b.$value=a})},null,{disposeWhenNodeIsRemoved:a});for(c=g.firstChild(a);a=c;)switch(c=g.nextSibling(a),a.nodeType){case 1:case 8:d=
-    k.extend(h),d.$switchIndex=p,b.applyBindings(d,a),d.$switchIndex!==p&&l.push(d)}return{controlsDescendantBindings:!0}},preprocess:function(a){return a||"true"}};t["switch"]=!1;g.allowedBindings["switch"]=!0;s("case");s("casenot",!0);d["case.visible"]=h("visible");d["casenot.visible"]=h("visible",!0);d["switch"].makeCaseHandler=h});

+ 0 - 299
desktop/core/src/desktop/static/desktop/js/sqlUtils.js

@@ -1,299 +0,0 @@
-// Licensed to Cloudera, Inc. under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  Cloudera, Inc. 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.
-
-
-var SqlUtils = (function () {
-
-  var hiveReservedKeywords = {
-    ALL: true, ALTER: true, AND: true, ARRAY: true, AS: true, AUTHORIZATION: true, BETWEEN: true, BIGINT: true, BINARY: true, BOOLEAN: true, BOTH: true, BY: true, CACHE: true, CASE: true,
-    CAST: true, CHAR: true, COLUMN: true, COMMIT: true, CONF: true, CONSTRAINT: true, CREATE: true, CROSS: true, CUBE: true, CURRENT: true, CURRENT_DATE: true, CURRENT_TIMESTAMP: true,
-    CURSOR: true, DATABASE: true, DATE: true, DAYOFWEEK: true, DECIMAL: true, DELETE: true, DESCRIBE: true, DISTINCT: true, DIV: true, DOUBLE: true, DROP: true, ELSE: true, END: true,
-    EXCHANGE: true, EXTRACT: true, EXISTS: true, EXTENDED: true, EXTERNAL: true, FALSE: true, FETCH: true, FLOAT: true, FLOOR: true, FOLLOWING: true, FOR: true, FOREIGN: true,FROM: true,
-    FULL: true, FUNCTION: true, GRANT: true, GROUP: true, GROUPING: true, HAVING: true, IF: true, IMPORT: true, IN: true, INNER: true, INSERT: true, INT: true, INTEGER: true,
-    INTERSECT: true, INTERVAL: true, INTO: true, IS: true, JOIN: true, LATERAL: true, LEFT: true, LESS: true, LIKE: true, LOCAL: true, MACRO: true, MAP: true, MORE: true, NONE: true,
-    NOT: true, NULL: true, NUMERIC: true, OF: true, ON: true, ONLY: true, OR: true, ORDER: true, OUT: true, OUTER: true, OVER: true, PARTIALSCAN: true, PARTITION: true, PERCENT: true,
-    PRECEDING: true, PRECISION: true, PRESERVE: true, PRIMARY: true, PROCEDURE: true, RANGE: true, READS: true, REDUCE: true, REFERENCES: true, REGEXP: true, REVOKE: true, RIGHT: true,
-    RLIKE: true, ROLLBACK: true, ROLLUP: true, ROW: true, ROWS: true, SELECT: true, SET: true, SMALLINT: true, START: true, TABLE: true, TABLESAMPLE: true, THEN: true, TIME: true,
-    TIMESTAMP: true, TO: true, TRANSFORM: true, TRIGGER: true, TRUE: true, TRUNCATE: true, UNBOUNDED: true, UNION: true, UNIQUEJOIN: true, UPDATE: true, USER: true, USING: true,
-    VALUES: true, VARCHAR: true, VIEWS: true, WHEN: true, WHERE: true, WINDOW: true, WITH: true
-  };
-
-  var extraHiveReservedKeywords = {
-    ASC: true, CLUSTER: true, DESC: true, DISTRIBUTE: true, FORMATTED: true, FUNCTION: true, INDEX: true, INDEXES: true, LIMIT: true, LOCK: true, SCHEMA: true, SORT: true
-  };
-
-  var impalaReservedKeywords = {
-    ADD: true, AGGREGATE: true, ALL: true, ALLOCATE: true, ALTER: true, ANALYTIC: true, AND: true, ANTI: true, ANY: true, API_VERSION: true, ARE: true, ARRAY: true, ARRAY_AGG: true,
-    ARRAY_MAX_CARDINALITY: true, AS: true, ASC: true, ASENSITIVE: true, ASYMMETRIC: true, AT: true, ATOMIC: true, AUTHORIZATION: true, AVRO: true, BEGIN_FRAME: true, BEGIN_PARTITION: true,
-    BETWEEN: true, BIGINT: true, BINARY: true, BLOB: true, BLOCK_SIZE: true, BOOLEAN: true, BOTH: true, BY: true, CACHED: true, CALLED: true, CARDINALITY: true, CASCADE: true,
-    CASCADED: true, CASE: true, CAST: true, CHANGE: true, CHAR: true, CHARACTER: true, CLASS: true, CLOB: true, CLOSE_FN: true, COLLATE: true, COLLECT: true, COLUMN: true, COLUMNS: true,
-    COMMENT: true, COMMIT: true, COMPRESSION: true, COMPUTE: true, CONDITION: true, CONNECT: true, CONSTRAINT: true, CONTAINS: true, CONVERT: true, COPY: true, CORR: true,
-    CORRESPONDING: true, COVAR_POP: true, COVAR_SAMP: true, CREATE: true, CROSS: true, CUBE: true, CURRENT: true, CURRENT_DATE: true, CURRENT_DEFAULT_TRANSFORM_GROUP: true,
-    CURRENT_PATH: true, CURRENT_ROLE: true, CURRENT_ROW: true, CURRENT_SCHEMA: true, CURRENT_TIME: true, CURRENT_TRANSFORM_GROUP_FOR_TYPE: true, CURSOR: true, CYCLE: true, DATA: true,
-    DATABASE: true, DATABASES: true, DATE: true, DATETIME: true, DEALLOCATE: true, DEC: true, DECFLOAT: true, DECIMAL: true, DECLARE: true, DEFINE: true, DELETE: true, DELIMITED: true,
-    DEREF: true, DESC: true, DESCRIBE: true, DETERMINISTIC: true, DISCONNECT: true, DISTINCT: true, DIV: true, DOUBLE: true, DROP: true, DYNAMIC: true, EACH: true, ELEMENT: true,
-    ELSE: true, EMPTY: true, ENCODING: true, END: true, END_FRAME: true, END_PARTITION: true, EQUALS: true, ESCAPE: true, ESCAPED: true, EVERY: true, EXCEPT: true, EXEC: true,
-    EXECUTE: true, EXISTS: true, EXPLAIN: true, EXTENDED: true, EXTERNAL: true, FALSE: true, FETCH: true, FIELDS: true, FILEFORMAT: true, FILES: true, FILTER: true, FINALIZE_FN: true,
-    FIRST: true, FLOAT: true, FOLLOWING: true, FOR: true, FOREIGN: true, FORMAT: true, FORMATTED: true, FRAME_ROW: true, FREE: true, FROM: true, FULL: true, FUNCTION: true,
-    FUNCTIONS: true, FUSION: true, GET: true, GLOBAL: true, GRANT: true, GROUP: true, GROUPING: true, GROUPS: true, HASH: true, HAVING: true, HOLD: true, IF: true, IGNORE: true,
-    ILIKE: true, IN: true, INCREMENTAL: true, INDICATOR: true, INIT_FN: true, INITIAL: true, INNER: true, INOUT: true, INPATH: true, INSENSITIVE: true, INSERT: true, INT: true,
-    INTEGER: true, INTERMEDIATE: true, INTERSECT: true, INTERSECTION: true, INTERVAL: true, INTO: true, INVALIDATE: true, IREGEXP: true, IS: true, JOIN: true, JSON_ARRAY: true,
-    JSON_ARRAYAGG: true, JSON_EXISTS: true, JSON_OBJECT: true, JSON_OBJECTAGG: true, JSON_QUERY: true, JSON_TABLE: true, JSON_TABLE_PRIMITIVE: true, JSON_VALUE: true, KEY: true,
-    KUDU: true, LARGE: true, LAST: true, LATERAL: true, LEADING: true, LEFT: true, LIKE: true, LIKE_REGEX: true, LIMIT: true, LINES: true, LISTAGG: true, LOAD: true, LOCAL: true,
-    LOCALTIMESTAMP: true, LOCATION: true, MAP: true, MATCH: true, MATCH_NUMBER: true, MATCH_RECOGNIZE: true, MATCHES: true, MERGE: true, MERGE_FN: true, METADATA: true, METHOD: true,
-    MODIFIES: true, MULTISET: true, NATIONAL: true, NATURAL: true, NCHAR: true, NCLOB: true, NO: true, NONE: true, NORMALIZE: true, NOT: true, NTH_VALUE: true, NULL: true, NULLS: true,
-    NUMERIC: true, OCCURRENCES_REGEX: true, OCTET_LENGTH: true, OF: true, OFFSET: true, OMIT: true, ON: true, ONE: true, ONLY: true, OR: true, ORDER: true, OUT: true, OUTER: true,
-    OVER: true, OVERLAPS: true, OVERLAY: true, OVERWRITE: true, PARQUET: true, PARQUETFILE: true, PARTITION: true, PARTITIONED: true, PARTITIONS: true, PATTERN: true, PER: true,
-    PERCENT: true, PERCENTILE_CONT: true, PERCENTILE_DISC: true, PORTION: true, POSITION: true, POSITION_REGEX: true, PRECEDES: true, PRECEDING: true, PREPARE: true, PREPARE_FN: true,
-    PRIMARY: true, PROCEDURE: true, PRODUCED: true, PTF: true, PURGE: true, RANGE: true, RCFILE: true, READS: true, REAL: true, RECOVER: true, RECURSIVE: true, REF: true,
-    REFERENCES: true, REFERENCING: true, REFRESH: true, REGEXP: true, REGR_AVGX: true, REGR_AVGY: true, REGR_COUNT: true, REGR_INTERCEPT: true, REGR_R2: true,REGR_SLOPE: true,
-    REGR_SXX: true, REGR_SXY: true, REGR_SYY: true, RELEASE: true, RENAME: true, REPEATABLE: true, REPLACE: true, REPLICATION: true, RESTRICT: true, RETURNS: true, REVOKE: true,
-    RIGHT: true, RLIKE: true, ROLE: true, ROLES: true, ROLLBACK: true, ROLLUP: true, ROW: true, ROWS: true, RUNNING: true, SAVEPOINT: true, SCHEMA: true, SCHEMAS: true, SCOPE: true,
-    SCROLL: true, SEARCH: true, SEEK: true, SELECT: true, SEMI: true, SENSITIVE: true, SEQUENCEFILE: true, SERDEPROPERTIES: true, SERIALIZE_FN: true, SET: true, SHOW: true,
-    SIMILAR: true, SKIP: true, SMALLINT: true, SOME: true, SORT: true, SPECIFIC: true, SPECIFICTYPE: true, SQLEXCEPTION: true, SQLSTATE: true, SQLWARNING: true, STATIC: true,
-    STATS: true, STORED: true, STRAIGHT_JOIN: true, STRING: true, STRUCT: true, SUBMULTISET: true, SUBSET: true, SUBSTRING_REGEX: true, SUCCEEDS: true, SYMBOL: true, SYMMETRIC: true,
-    SYSTEM_TIME: true, SYSTEM_USER: true, TABLE: true, TABLES: true, TABLESAMPLE: true, TBLPROPERTIES: true, TERMINATED: true, TEXTFILE: true, THEN: true, TIMESTAMP: true,
-    TIMEZONE_HOUR: true, TIMEZONE_MINUTE: true, TINYINT: true, TO: true, TRAILING: true, TRANSLATE_REGEX: true, TRANSLATION: true, TREAT: true, TRIGGER: true, TRIM_ARRAY: true,
-    TRUE: true, TRUNCATE: true, UESCAPE: true, UNBOUNDED: true, UNCACHED: true, UNION: true, UNIQUE: true, UNKNOWN: true, UNNEST: true, UPDATE: true, UPDATE_FN: true, UPSERT: true,
-    USE: true, USER: true, USING: true, VALUE_OF: true, VALUES: true, VARBINARY: true, VARCHAR: true, VARYING: true, VERSIONING: true, VIEW: true, WHEN: true, WHENEVER: true,
-    WHERE: true, WIDTH_BUCKET: true, WINDOW: true, WITH: true, WITHIN: true, WITHOUT: true
-  };
-
-  var autocompleteFilter = function (filter, entries) {
-    var lowerCaseFilter = filter.toLowerCase();
-    return entries.filter(function (suggestion) {
-      // TODO: Extend with fuzzy matches
-      var foundIndex = suggestion.value.toLowerCase().indexOf(lowerCaseFilter);
-      if (foundIndex !== -1) {
-        if (foundIndex === 0 || (suggestion.filterValue && suggestion.filterValue.toLowerCase().indexOf(lowerCaseFilter) === 0)) {
-          suggestion.filterWeight = 3;
-        } else  {
-          suggestion.filterWeight = 2;
-        }
-      } else {
-        if (suggestion.details && suggestion.details.comment && lowerCaseFilter.indexOf(' ') === -1) {
-          foundIndex = suggestion.details.comment.toLowerCase().indexOf(lowerCaseFilter);
-          if (foundIndex !== -1) {
-            suggestion.filterWeight = 1;
-            suggestion.matchComment = true;
-          }
-        }
-      }
-      if (foundIndex !== -1) {
-        suggestion.matchIndex = foundIndex;
-        suggestion.matchLength = filter.length;
-        return true;
-      }
-      return false;
-    });
-  };
-
-  var sortSuggestions = function (suggestions, filter, sortOverride) {
-    suggestions.sort(function (a, b) {
-      if (filter) {
-        if (typeof a.filterWeight !== 'undefined' && typeof b.filterWeight !== 'undefined' && b.filterWeight !== a.filterWeight) {
-          return b.filterWeight - a.filterWeight;
-        }
-        if (typeof a.filterWeight !== 'undefined' && typeof b.filterWeight === 'undefined') {
-          return -1;
-        }
-        if (typeof a.filterWeight === 'undefined' && typeof b.filterWeight !== 'undefined') {
-          return 1;
-        }
-      }
-      if (sortOverride && sortOverride.partitionColumnsFirst) {
-        if (a.partitionKey && !b.partitionKey) {
-          return -1;
-        }
-        if (b.partitionKey && !a.partitionKey) {
-          return 1;
-        }
-      }
-      var aWeight = a.category.weight + (a.weightAdjust || 0);
-      var bWeight = b.category.weight + (b.weightAdjust || 0);
-      if (typeof aWeight !== 'undefined' && typeof bWeight !== 'undefined' && bWeight !== aWeight) {
-        return bWeight - aWeight;
-      }
-      if (typeof aWeight !== 'undefined' && typeof bWeight === 'undefined') {
-        return -1;
-      }
-      if (typeof aWeight === 'undefined' && typeof bWeight !== 'undefined') {
-        return 1;
-      }
-      return a.value.localeCompare(b.value);
-    });
-  };
-
-  var identifierChainToPath = function (identifierChain) {
-    return $.map(identifierChain, function (identifier) {
-      return identifier.name
-    })
-  };
-
-  /**
-   *
-   * @param {Object} options
-   * @param {String} options.sourceType
-   * @param {ContextNamespace} options.namespace
-   * @param {ContextCompute} options.compute
-   * @param {boolean} [options.temporaryOnly] - Default: false
-   * @param {Object[]} [options.identifierChain]
-   * @param {Object[]} [options.tables]
-   * @param {Object} [options.cancellable]
-   * @param {Object} [options.cachedOnly]
-   *
-   * @return {CancellablePromise}
-   */
-  var resolveCatalogEntry = function (options) {
-    var cancellablePromises = [];
-    var deferred = $.Deferred();
-    var promise = new CancellablePromise(deferred, undefined, cancellablePromises);
-    dataCatalog.applyCancellable(promise, options);
-
-    if (!options.identifierChain) {
-      deferred.reject();
-      return promise;
-    }
-
-    var findInTree = function (currentEntry, fieldsToGo) {
-      if (fieldsToGo.length === 0) {
-        deferred.reject();
-        return;
-      }
-
-      var nextField;
-      if (currentEntry.getType() === 'map') {
-        nextField = 'value';
-      } else if (currentEntry.getType() === 'array') {
-        nextField = 'item';
-      } else {
-        nextField = fieldsToGo.shift();
-      }
-
-      cancellablePromises.push(currentEntry.getChildren({
-        cancellable: options.cancellable,
-        cachedOnly: options.cachedOnly,
-        silenceErrors: true
-      }).done(function (childEntries) {
-        var foundEntry = undefined;
-        childEntries.some(function (childEntry) {
-          if (sqlUtils.identifierEquals(childEntry.name, nextField)) {
-            foundEntry = childEntry;
-            return true;
-          }
-        });
-        if (foundEntry && fieldsToGo.length) {
-          findInTree(foundEntry, fieldsToGo);
-        } else if (foundEntry) {
-          deferred.resolve(foundEntry);
-        } else {
-          deferred.reject();
-        }
-      }).fail(deferred.reject))
-    };
-
-    var findTable = function (tablesToGo) {
-      if (tablesToGo.length === 0) {
-        deferred.reject();
-        return;
-      }
-
-      var nextTable = tablesToGo.pop();
-      if (typeof nextTable.subQuery !== 'undefined') {
-        findTable(tablesToGo);
-        return;
-      }
-
-      cancellablePromises.push(dataCatalog.getChildren({
-        sourceType: options.sourceType,
-        namespace: options.namespace,
-        compute: options.compute,
-        path: sqlUtils.identifierChainToPath(nextTable.identifierChain),
-        cachedOnly: options && options.cachedOnly,
-        cancellable: options && options.cancellable,
-        temporaryOnly: options && options.temporaryOnly,
-        silenceErrors: true
-      }).done(function (childEntries) {
-        var foundEntry = undefined;
-        childEntries.some(function (childEntry) {
-          if (sqlUtils.identifierEquals(childEntry.name, options.identifierChain[0].name)) {
-            foundEntry = childEntry;
-            return true;
-          }
-        });
-
-        if (foundEntry && options.identifierChain.length > 1) {
-          findInTree(foundEntry, sqlUtils.identifierChainToPath(options.identifierChain.slice(1)));
-        } else if (foundEntry) {
-          deferred.resolve(foundEntry);
-        } else {
-          findTable(tablesToGo)
-        }
-      }).fail(deferred.reject));
-    };
-
-    if (options.tables) {
-      findTable(options.tables.concat())
-    } else {
-      dataCatalog.getEntry({
-        sourceType: options.sourceType,
-        namespace: options.namespace,
-        compute: options.compute,
-        path: [],
-        cachedOnly: options && options.cachedOnly,
-        cancellable: options && options.cancellable,
-        temporaryOnly: options && options.temporaryOnly,
-        silenceErrors: true
-      }).done(function (entry) {
-        findInTree(entry, sqlUtils.identifierChainToPath(options.identifierChain))
-      })
-    }
-
-    return promise;
-  };
-
-  return {
-    autocompleteFilter : autocompleteFilter,
-    backTickIfNeeded: function (sourceType, identifier) {
-      if (identifier.indexOf('`') === 0) {
-        return identifier;
-      }
-      var upperIdentifier = identifier.toUpperCase();
-      if (sourceType === 'hive' && (hiveReservedKeywords[upperIdentifier] || extraHiveReservedKeywords[upperIdentifier])) {
-        return '`' + identifier + '`';
-      }
-      if (sourceType === 'impala' && impalaReservedKeywords[upperIdentifier]) {
-        return '`' + identifier + '`';
-      }
-      if ((sourceType !== 'impala' && sourceType !== 'hive') && (impalaReservedKeywords[upperIdentifier] || hiveReservedKeywords[upperIdentifier] || extraHiveReservedKeywords[upperIdentifier])) {
-        return '`' + identifier + '`';
-      }
-      if (!/^[A-Za-z][A-Za-z0-9_]*$/.test(identifier)) {
-        return '`' + identifier + '`';
-      }
-      return identifier;
-    },
-    locationEquals: function (a, b) {
-      return a && b && a.first_line === b.first_line && a.first_column === b.first_column && a.last_line === b.last_line && a.last_column === b.last_column;
-    },
-    identifierEquals: function (a, b) {
-      return a && b && a.replace(/^\s*`/, '').replace(/`\s*$/, '').toLowerCase() === b.replace(/^\s*`/, '').replace(/`\s*$/, '').toLowerCase();
-    },
-    sortSuggestions: sortSuggestions,
-    resolveCatalogEntry: resolveCatalogEntry,
-    identifierChainToPath: identifierChainToPath
-  }
-})();

+ 0 - 3
desktop/core/src/desktop/templates/assist_m.mako

@@ -23,10 +23,7 @@ from django.utils.translation import ugettext as _
 
 ${ commonheader_m(_('Assist'), 'assist', user, request) | n,unicode }
 
-<script src="${ static('desktop/ext/js/jquery/plugins/jquery-ui-1.10.4.custom.min.js') }"></script>
-<script src="${ static('desktop/ext/js/selectize.min.js') }"></script>
 <script src="${ static('metastore/js/metastore.ko.js') }"></script>
-<script src="${ static('desktop/ext/js/knockout-sortable.min.js') }"></script>
 
 ${ assist.assistJSModels() }
 

+ 0 - 2
desktop/core/src/desktop/templates/common_dashboard.mako

@@ -32,8 +32,6 @@
 <%def name="import_layout(with_deferred=False)">
   <link rel="stylesheet" href="${ static('dashboard/css/common_dashboard.css') }">
   <script src="${ static('desktop/js/ko.common-dashboard.js') }" type="text/javascript" charset="utf-8"></script>
-  <script src="${ static('desktop/ext/js/jquery/plugins/jquery-ui-1.10.4.custom.min.js') }" type="text/javascript" charset="utf-8"></script>
-  <script src="${ static('desktop/ext/js/knockout-sortable.min.js') }" type="text/javascript" charset="utf-8"></script>
   <script src="${ static('desktop/js/ko.droppable.fix.js') }" type="text/javascript" charset="utf-8"></script>
   <script src="${ static('desktop/ext/js/clipboard.min.js') }"></script>
 

+ 4 - 28
desktop/core/src/desktop/templates/common_header.mako

@@ -24,6 +24,8 @@ from metadata.conf import has_optimizer, OPTIMIZER
 
 from desktop.auth.backend import is_admin
 
+from webpack_loader.templatetags.webpack_loader import render_bundle
+
 home_url = url('desktop_views_home')
 if USE_NEW_EDITOR.get():
   home_url = url('desktop_views_home2')
@@ -133,52 +135,26 @@ if USE_NEW_EDITOR.get():
   <script src="${ static('desktop/js/hue.errorcatcher.js') }"></script>
   % endif
 
-  <script src="${ static('desktop/ext/js/jquery/jquery-2.2.4.min.js') }"></script>
-  <script src="${ static('desktop/js/jquery.migration.js') }"></script>
-  <script src="${ static('desktop/js/jquery.hiveautocomplete.js') }"></script>
-  <script src="${ static('desktop/js/jquery.hdfsautocomplete.js') }"></script>
-  <script src="${ static('desktop/js/jquery.filechooser.js') }"></script>
-  <script src="${ static('desktop/js/jquery.selector.js') }"></script>
-  <script src="${ static('desktop/js/jquery.delayedinput.js') }"></script>
-  <script src="${ static('desktop/js/jquery.rowselector.js') }"></script>
-  <script src="${ static('desktop/js/jquery.notify.js') }"></script>
-  <script src="${ static('desktop/js/jquery.titleupdater.js') }"></script>
-  <script src="${ static('desktop/js/jquery.horizontalscrollbar.js') }"></script>
-  <script src="${ static('desktop/js/jquery.tablescroller.js') }"></script>
-  <script src="${ static('desktop/js/jquery.tableextender.js') }"></script>
-  <script src="${ static('desktop/js/jquery.tableextender2.js') }"></script>
-  <script src="${ static('desktop/js/jquery.scrollleft.js') }"></script>
-  <script src="${ static('desktop/js/jquery.scrollup.js') }"></script>
-  <script src="${ static('desktop/ext/js/jquery/plugins/jquery.cookie.js') }"></script>
-  <script src="${ static('desktop/ext/js/jquery/plugins/jquery.total-storage.min.js') }"></script>
-  <script src="${ static('desktop/ext/js/jquery/plugins/jquery.dataTables.1.8.2.min.js') }"></script>
-  <script src="${ static('desktop/ext/js/jquery/plugins/jquery.form.js') }"></script>
-  <script src="${ static('desktop/js/jquery.huedatatable.js') }"></script>
-  <script src="${ static('desktop/js/jquery.datatables.sorting.js') }"></script>
+  ${ render_bundle('hue') | n,unicode }
+
   <script src="${ static('desktop/ext/js/d3.v3.js') }"></script>
   <script src="${ static('desktop/ext/js/d3.v4.js') }"></script>
-  <script src="${ static('desktop/ext/js/bootstrap.min.js') }"></script>
   <script src="${ static('desktop/js/bootstrap-tooltip.js') }"></script>
   <script src="${ static('desktop/js/bootstrap-typeahead-touchscreen.js') }"></script>
   <script src="${ static('desktop/ext/js/bootstrap-better-typeahead.min.js') }"></script>
   <script src="${ static('desktop/js/hue.colors.js') }"></script>
-  <script src="${ static('desktop/ext/js/fileuploader.js') }"></script>
   <script src="${ static('desktop/js/popover-extra-placements.js') }"></script>
   <script src="${ static('desktop/ext/js/moment-with-locales.min.js') }"></script>
   <script src="${ static('desktop/ext/js/moment-timezone-with-data.min.js') }" type="text/javascript" charset="utf-8"></script>
   <script src="${ static('desktop/ext/js/tzdetect.js') }" type="text/javascript" charset="utf-8"></script>
-  <script src="${ static('desktop/ext/js/knockout.validation.min.js') }"></script>
-  <script src="${ static('desktop/js/ko.switch-case.js') }"></script>
 
 % if user.is_authenticated():
 
-  <script src="${ static('desktop/js/sqlUtils.js') }"></script>
   <script src="${ static('desktop/js/ace/ace.js') }"></script>
   <script src="${ static('desktop/js/ace/mode-impala.js') }"></script>
   <script src="${ static('desktop/js/ace/mode-hive.js') }"></script>
   <script src="${ static('desktop/js/ace/ext-language_tools.js') }"></script>
   <script src="${ static('desktop/js/ace.extended.js') }"></script>
-  <script src="${ static('desktop/js/autocomplete/sqlParseSupport.js') }"></script>
   <script src="${ static('desktop/js/autocomplete/sqlStatementsParser.js') }"></script>
   <script src="${ static('desktop/js/autocomplete/sqlAutocompleteParser.js') }"></script>
   <script src="${ static('desktop/js/autocomplete/solrQueryParser.js') }"></script>

+ 5 - 7
desktop/core/src/desktop/templates/common_header_m.mako

@@ -21,6 +21,9 @@ from metadata.conf import has_optimizer, OPTIMIZER
 
 home_url = url('desktop_views_home')
 from desktop.conf import USE_NEW_EDITOR
+
+from webpack_loader.templatetags.webpack_loader import render_bundle
+
 if USE_NEW_EDITOR.get():
   home_url = url('desktop_views_home2')
 %>
@@ -159,12 +162,9 @@ if USE_NEW_EDITOR.get():
     }
   </script>
 
-  <script src="${ static('desktop/ext/js/jquery/jquery-2.2.4.min.js') }"></script>
-  <script src="${ static('desktop/js/jquery.migration.js') }"></script>
-  <script src="${ static('desktop/ext/js/jquery/plugins/jquery.cookie.js') }"></script>
-  <script src="${ static('desktop/ext/js/jquery/plugins/jquery.total-storage.min.js') }"></script>
+  ${ render_bundle('hue') | n,unicode }
+
   <script src="${ static('desktop/ext/js/jquery/plugins/jquery.touchSwipe.min.js') }"></script>
-  <script src="${ static('desktop/ext/js/bootstrap.min.js') }"></script>
   <script src="${ static('desktop/js/bootstrap-typeahead-touchscreen.js') }"></script>
   <script src="${ static('desktop/ext/js/bootstrap-better-typeahead.min.js') }"></script>
   <script src="${ static('desktop/ext/js/moment-with-locales.min.js') }"></script>
@@ -172,8 +172,6 @@ if USE_NEW_EDITOR.get():
   <script src="${ static('desktop/ext/js/tzdetect.js') }" type="text/javascript" charset="utf-8"></script>
   <script src="${ static('desktop/ext/js/d3.v3.js') }"></script>
   <script src="${ static('desktop/ext/js/d3.v4.js') }"></script>
-  <script src="${ static('desktop/ext/js/knockout.validation.min.js') }"></script>
-  <script src="${ static('desktop/js/ko.switch-case.js') }"></script>
   <script src="${ static('desktop/js/hue.colors.js') }"></script>
   <script src="${ static('desktop/js/ace/ace.js') }"></script>
   <script src="${ static('desktop/js/ace/mode-impala.js') }"></script>

+ 0 - 3
desktop/core/src/desktop/templates/common_home.mako

@@ -24,9 +24,6 @@
 <%namespace name="docBrowser" file="/document_browser.mako" />
 
 <%def name="homeJSModels(is_embeddable=False)">
-  <script src="${ static('desktop/ext/js/jquery/plugins/jquery-ui-1.10.4.custom.min.js') }"></script>
-  <script src="${ static('desktop/ext/js/selectize.min.js') }"></script>
-  <script src="${ static('desktop/ext/js/knockout-sortable.min.js') }"></script>
   <script src="${ static('desktop/ext/js/jquery/plugins/jquery.mousewheel.min.js') }"></script>
   <script src="${ static('desktop/js/home2.vm.js') }"></script>
 

+ 0 - 3
desktop/core/src/desktop/templates/common_jasmine.mako

@@ -23,9 +23,6 @@
   <link rel="shortcut icon" type="image/png" href="${ static('desktop/ext/js/jasmine-2.3.4/jasmine_favicon.png') }">
   <link rel="stylesheet" href="${ static('desktop/ext/js/jasmine-2.3.4/jasmine.css') }">
 
-  <script type="text/javascript" src="${ static('desktop/ext/js/jquery/jquery-2.2.4.min.js') }"></script>
-  <script type="text/javascript" src="${ static('desktop/js/jquery.migration.js') }"></script>
-  <script type="text/javascript" src="${ static('desktop/ext/js/jquery/plugins/jquery.total-storage.min.js') }"></script>
   <script type="text/javascript" src="${ static('desktop/js/ace/ace.js') }"></script>
   <script>
     ace.config.set("basePath", "/static/desktop/js/ace");

+ 0 - 8
desktop/core/src/desktop/templates/hue.mako

@@ -132,7 +132,6 @@
   % if not conf.DEV.get():
   <script src="${ static('desktop/js/hue.errorcatcher.js') }"></script>
   % endif
-  <script src="${ static('desktop/js/hue4.utils.js') }"></script>
 </head>
 
 <body>
@@ -460,9 +459,6 @@ ${ render_bundle('hue') | n,unicode }
 <script src="${ static('desktop/ext/js/moment-timezone-with-data.min.js') }" type="text/javascript" charset="utf-8"></script>
 <script src="${ static('desktop/ext/js/tzdetect.js') }" type="text/javascript" charset="utf-8"></script>
 
-<script src="${ static('desktop/js/jquery.scrollup.js') }"></script>
-<script src="${ static('desktop/js/jquery.huedatatable.js') }"></script>
-
 <script src="${ static('desktop/js/bootstrap-tooltip.js') }"></script>
 <script src="${ static('desktop/js/bootstrap-typeahead-touchscreen.js') }"></script>
 <script src="${ static('desktop/ext/js/bootstrap-better-typeahead.min.js') }"></script>
@@ -477,9 +473,6 @@ ${ render_bundle('hue') | n,unicode }
 
 <script src="${ static('desktop/js/hue.colors.js') }"></script>
 
-<script src="${ static('desktop/js/sqlFunctions.js') }"></script>
-
-<script src="${ static('desktop/js/autocomplete/sqlParseSupport.js') }"></script>
 <script src="${ static('desktop/js/autocomplete/sqlStatementsParser.js') }"></script>
 <script src="${ static('desktop/js/autocomplete/sqlAutocompleteParser.js') }"></script>
 <script src="${ static('desktop/js/autocomplete/globalSearchParser.js') }"></script>
@@ -490,7 +483,6 @@ ${ render_bundle('hue') | n,unicode }
 <script src="${ static('desktop/js/sqlAutocompleter3.js') }"></script>
 <script src="${ static('desktop/js/hdfsAutocompleter.js') }"></script>
 <script src="${ static('desktop/js/autocompleter.js') }"></script>
-<script src="${ static('desktop/js/hue.json.js') }"></script>
 <script src="${ static('notebook/js/notebook.ko.js') }"></script>
 <script src="${ static('metastore/js/metastore.model.js') }"></script>
 

+ 0 - 5
desktop/libs/dashboard/src/dashboard/templates/common_search.mako

@@ -3077,8 +3077,6 @@ ${ dashboard.layout_skeleton(suffix='search') }
 <link rel="stylesheet" href="${ static('desktop/ext/select2/select2.css') }">
 <link rel="stylesheet" href="${ static('desktop/ext/css/jquery.gridster.min.css') }">
 
-<script src="${ static('desktop/js/hue.json.js') }" type="text/javascript" charset="utf-8"></script>
-
 ${ dashboard.import_layout(True) }
 
 % if not is_embeddable:
@@ -3092,9 +3090,6 @@ ${ dashboard.import_layout(True) }
 <script src="${ static('desktop/ext/chosen/chosen.jquery.min.js') }" type="text/javascript" charset="utf-8"></script>
 <script src="${ static('desktop/ext/js/jquery/plugins/jquery.hotkeys.js') }"></script>
 <script src="${ static('desktop/ext/select2/select2.min.js') }" type="text/javascript" charset="utf-8"></script>
-<script src="${ static('desktop/ext/js/selectize.min.js') }"></script>
-<script src="${ static('desktop/ext/js/selectize-plugin-clear.js') }"></script>
-<script src="${ static('desktop/js/ko.selectize.js') }"></script>
 <script src="${ static('dashboard/js/search.ko.js') }" type="text/javascript" charset="utf-8"></script>
 
 <script src="${ static('desktop/ext/js/jquery/plugins/jquery.gridster.with-extras.min.js') }"></script>

+ 0 - 2
desktop/libs/indexer/src/indexer/templates/collections.mako

@@ -480,12 +480,10 @@ ${ commonheader(_('Search Indexes'), "indexer", user, request, "90px") | n,unico
 </div>
 
 <script src="${ static('desktop/ext/chosen/chosen.jquery.min.js') }" type="text/javascript" charset="utf-8"></script>
-<script src="${ static('desktop/ext/js/jquery/plugins/jquery-ui-1.10.4.custom.min.js') }" type="text/javascript" charset="utf-8"></script>
 <script src="${ static('desktop/js/hue.routie.js') }" type="text/javascript" charset="utf-8"></script>
 <script>
   routie.setPathname('/indexer');
 </script>
-<script src="${ static('desktop/ext/js/knockout-sortable.min.js') }" type="text/javascript" charset="utf-8"></script>
 <script src="${ static('indexer/js/lib.js') }" type="text/javascript" charset="utf-8"></script>
 <script src="${ static('indexer/js/collections.js') }" type="text/javascript" charset="utf-8"></script>
 

+ 0 - 7
desktop/libs/indexer/src/indexer/templates/importer.mako

@@ -32,20 +32,13 @@
 ${ commonheader(_("Importer"), "indexer", user, request, "60px") | n,unicode }
 
 ## TODO lot of those re-imported
-<script src="${ static('desktop/js/autocomplete/sqlParseSupport.js') }"></script>
 <script src="${ static('desktop/js/autocomplete/sqlAutocompleteParser.js') }"></script>
 <script src="${ static('desktop/js/sqlAutocompleter2.js') }"></script>
 <script src="${ static('desktop/js/hdfsAutocompleter.js') }"></script>
 <script src="${ static('desktop/js/autocompleter.js') }"></script>
-<script src="${ static('desktop/js/hue.json.js') }"></script>
 
 
-<script src="${ static('desktop/ext/js/selectize.min.js') }"></script>
-<script src="${ static('desktop/ext/js/selectize-plugin-clear.js') }"></script>
 <script src="${ static('metastore/js/metastore.ko.js') }"></script>
-<script src="${ static('desktop/ext/js/knockout-sortable.min.js') }"></script>
-<script src="${ static('desktop/ext/js/selectize.min.js') }"></script>
-<script src="${ static('desktop/js/ko.selectize.js') }"></script>
 
 ${ assist.assistJSModels() }
 

+ 0 - 4
desktop/libs/indexer/src/indexer/templates/indexer.mako

@@ -27,11 +27,7 @@
 %if not is_embeddable:
 ${ commonheader(_("Solr Indexes"), "search", user, request, "60px") | n,unicode }
 
-<script src="${ static('desktop/ext/js/jquery/plugins/jquery-ui-1.10.4.custom.min.js') }"></script>
-<script src="${ static('desktop/ext/js/selectize.min.js') }"></script>
-<script src="${ static('desktop/ext/js/selectize-plugin-clear.js') }"></script>
 <script src="${ static('metastore/js/metastore.ko.js') }"></script>
-<script src="${ static('desktop/ext/js/knockout-sortable.min.js') }"></script>
 
 ${ assist.assistJSModels() }
 

+ 0 - 2
desktop/libs/indexer/src/indexer/templates/indexes.mako

@@ -30,7 +30,6 @@ MAIN_SCROLLABLE = is_embeddable and ".page-content" or ".content-panel"
 
 %if not is_embeddable:
 ${ commonheader(_("Index Browser"), "search", user, request, "60px") | n,unicode }
-<script src="${ static('desktop/ext/js/jquery/plugins/jquery-ui-1.10.4.custom.min.js') }"></script>
 <script src="${ static('desktop/ext/js/jquery/plugins/jquery.mousewheel.min.js') }"></script>
 
 ${ assist.assistJSModels() }
@@ -51,7 +50,6 @@ ${ assist.assistPanel() }
 
 <link rel="stylesheet" href="${ static('notebook/css/notebook.css') }" type="text/css">
 <link rel="stylesheet" href="${ static('indexer/css/indexes.css') }" type="text/css">
-<script src="${ static('desktop/js/hue.json.js') }" type="text/javascript" charset="utf-8"></script>
 <script src="${ static('dashboard/js/search.ko.js') }" type="text/javascript" charset="utf-8"></script>
 
 <script type="text/html" id="indexes-breadcrumbs">

+ 0 - 2
desktop/libs/indexer/src/indexer/templates/topics.mako

@@ -30,7 +30,6 @@ MAIN_SCROLLABLE = is_embeddable and ".page-content" or ".content-panel"
 
 %if not is_embeddable:
 ${ commonheader(_("Streams Browser"), "search", user, request, "60px") | n,unicode }
-<script src="${ static('desktop/ext/js/jquery/plugins/jquery-ui-1.10.4.custom.min.js') }"></script>
 <script src="${ static('desktop/ext/js/jquery/plugins/jquery.mousewheel.min.js') }"></script>
 
 ${ assist.assistJSModels() }
@@ -51,7 +50,6 @@ ${ assist.assistPanel() }
 
 <link rel="stylesheet" href="${ static('notebook/css/notebook.css') }" type="text/css">
 <link rel="stylesheet" href="${ static('indexer/css/indexes.css') }" type="text/css">
-<script src="${ static('desktop/js/hue.json.js') }" type="text/javascript" charset="utf-8"></script>
 <script src="${ static('dashboard/js/search.ko.js') }" type="text/javascript" charset="utf-8"></script>
 
 

+ 0 - 9
desktop/libs/notebook/src/notebook/templates/editor_components.mako

@@ -43,14 +43,10 @@ from desktop.auth.backend import is_admin
 
 <script src="${ static('desktop/ext/js/bootstrap-datepicker.min.js') }" type="text/javascript" charset="utf-8"></script>
 % if not is_embeddable:
-<script src="${ static('desktop/ext/js/jquery/plugins/jquery-ui-1.10.4.custom.min.js') }"></script>
-<script src="${ static('desktop/ext/js/knockout-sortable.min.js') }"></script>
 <script src="${ static('desktop/js/share2.vm.js') }"></script>
 % endif
 
 <script src="${ static('desktop/ext/js/clipboard.min.js') }"></script>
-<script src="${ static('desktop/ext/js/selectize.min.js') }"></script>
-<script src="${ static('desktop/ext/js/selectize-plugin-clear.js') }"></script>
 <script src="${ static('notebook/js/notebook.ko.js') }"></script>
 
 % if ENABLE_QUERY_SCHEDULING.get():
@@ -58,9 +54,6 @@ from desktop.auth.backend import is_admin
 <script src="${ static('oozie/js/list-oozie-coordinator.ko.js') }"></script>
 % endif
 
-<script src="${ static('desktop/js/ko.selectize.js') }"></script>
-<script src="${ static('desktop/js/sqlFunctions.js') }"></script>
-<script src="${ static('desktop/js/autocomplete/sqlParseSupport.js') }"></script>
 <script src="${ static('desktop/js/autocomplete/sqlStatementsParser.js') }"></script>
 <script src="${ static('desktop/js/autocomplete/sqlAutocompleteParser.js') }"></script>
 <script src="${ static('desktop/js/autocomplete/globalSearchParser.js') }"></script>
@@ -68,7 +61,6 @@ from desktop.auth.backend import is_admin
 <script src="${ static('desktop/js/sqlAutocompleter3.js') }"></script>
 <script src="${ static('desktop/js/hdfsAutocompleter.js') }"></script>
 <script src="${ static('desktop/js/autocompleter.js') }"></script>
-<script src="${ static('desktop/js/hue.json.js') }"></script>
 <script src="${ static('desktop/js/jquery.hdfstree.js') }"></script>
 <script src="${ static('desktop/ext/js/markdown.min.js') }"></script>
 <script src="${ static('desktop/ext/js/jquery/plugins/jquery.hotkeys.js') }"></script>
@@ -79,7 +71,6 @@ from desktop.auth.backend import is_admin
 <!-- For query builder -->
 <link rel="stylesheet" href="${ static('desktop/ext/css/jquery.contextMenu.min.css') }">
 <script src="${ static('desktop/ext/js/jquery/plugins/jquery.contextMenu.min.js') }"></script>
-<script src="${ static('desktop/ext/js/jquery/plugins/jquery.ui.position.min.js') }"></script>
 <script src="${ static('desktop/js/queryBuilder.js') }"></script>
 <script>
 

+ 0 - 5
desktop/libs/notebook/src/notebook/templates/editor_m.mako

@@ -162,16 +162,11 @@ ${ commonheader_m(editor_type, editor_type, user, request, "68px") | n,unicode }
 </div>
 
 
-<script src="${ static('desktop/ext/js/jquery/plugins/jquery-ui-1.10.4.custom.min.js') }"></script>
-<script src="${ static('desktop/js/ko.switch-case.js') }"></script>
-<script src="${ static('desktop/js/sqlFunctions.js') }"></script>
-<script src="${ static('desktop/js/autocomplete/sqlParseSupport.js') }"></script>
 <script src="${ static('desktop/js/autocomplete/sqlAutocompleteParser.js') }"></script>
 <script src="${ static('desktop/js/sqlAutocompleter2.js') }"></script>
 <script src="${ static('desktop/js/sqlAutocompleter3.js') }"></script>
 <script src="${ static('desktop/js/hdfsAutocompleter.js') }"></script>
 <script src="${ static('desktop/js/autocompleter.js') }"></script>
-<script src="${ static('desktop/js/hue.json.js') }"></script>
 <script src="${ static('notebook/js/notebook.ko.js') }"></script>
 
 ${ assist.assistJSModels() }

+ 122 - 0
package-lock.json

@@ -1227,6 +1227,13 @@
       "integrity": "sha1-6GuBnGAs+IIa1jdBNpjx3sAhhHo=",
       "dev": true
     },
+    "amdefine": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz",
+      "integrity": "sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU=",
+      "dev": true,
+      "optional": true
+    },
     "ansi-escapes": {
       "version": "3.2.0",
       "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.2.0.tgz",
@@ -1266,6 +1273,92 @@
       "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==",
       "dev": true
     },
+    "architect-build": {
+      "version": "0.1.1",
+      "resolved": "https://registry.npmjs.org/architect-build/-/architect-build-0.1.1.tgz",
+      "integrity": "sha512-VyG78Meb9l6Sl9L9ima93VlJTs6Ey1s8vdL+7KXpvVblfHzDqEne2/8TTHI89Im21/Zx69eXNXzDNkRI7AIMmw==",
+      "dev": true,
+      "requires": {
+        "async": "^2.6.2",
+        "mkdirp": "^0.5.1",
+        "through": "2.2.0",
+        "uglify-js": "2.4.14"
+      },
+      "dependencies": {
+        "async": {
+          "version": "2.6.2",
+          "resolved": "https://registry.npmjs.org/async/-/async-2.6.2.tgz",
+          "integrity": "sha512-H1qVYh1MYhEEFLsP97cVKqCGo7KfCyTt6uEWqsTBr9SO84oK9Uwbyd/yCW+6rKJLHksBNUVWZDAjfS+Ccx0Bbg==",
+          "dev": true,
+          "requires": {
+            "lodash": "^4.17.11"
+          }
+        },
+        "minimist": {
+          "version": "0.0.8",
+          "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz",
+          "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=",
+          "dev": true
+        },
+        "mkdirp": {
+          "version": "0.5.1",
+          "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz",
+          "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=",
+          "dev": true,
+          "requires": {
+            "minimist": "0.0.8"
+          }
+        },
+        "optimist": {
+          "version": "0.3.7",
+          "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.3.7.tgz",
+          "integrity": "sha1-yQlBrVnkJzMokjB00s8ufLxuwNk=",
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "wordwrap": "~0.0.2"
+          }
+        },
+        "source-map": {
+          "version": "0.1.43",
+          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.1.43.tgz",
+          "integrity": "sha1-wkvBRspRfBRx9drL4lcbK3+eM0Y=",
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "amdefine": ">=0.0.4"
+          }
+        },
+        "through": {
+          "version": "2.2.0",
+          "resolved": "https://registry.npmjs.org/through/-/through-2.2.0.tgz",
+          "integrity": "sha1-xOWiAKPxtIA2gZbPULxp/+LNznM=",
+          "dev": true
+        },
+        "uglify-js": {
+          "version": "2.4.14",
+          "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-2.4.14.tgz",
+          "integrity": "sha1-KudT7eO7TrvyXQe7mc8T6d4Aez4=",
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "async": "~0.2.6",
+            "optimist": "~0.3.5",
+            "source-map": "~0.1.33",
+            "uglify-to-browserify": "~1.0.0"
+          },
+          "dependencies": {
+            "async": {
+              "version": "0.2.10",
+              "resolved": "https://registry.npmjs.org/async/-/async-0.2.10.tgz",
+              "integrity": "sha1-trvgsGdLnXGXCMo43owjfLUmw9E=",
+              "dev": true,
+              "optional": true
+            }
+          }
+        }
+      }
+    },
     "argparse": {
       "version": "1.0.10",
       "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
@@ -2811,6 +2904,23 @@
       "resolved": "https://registry.npmjs.org/dropzone/-/dropzone-5.5.1.tgz",
       "integrity": "sha512-3VduRWLxx9hbVr42QieQN25mx/I61/mRdUSuxAmDGdDqZIN8qtP7tcKMa3KfpJjuGjOJGYYUzzeq6eGDnkzesA=="
     },
+    "dryice": {
+      "version": "0.4.11",
+      "resolved": "https://registry.npmjs.org/dryice/-/dryice-0.4.11.tgz",
+      "integrity": "sha1-FQ+x3CqQKG4YcUZ1dvGKhiR8T0k=",
+      "dev": true,
+      "requires": {
+        "uglify-js": "~1.3.4"
+      },
+      "dependencies": {
+        "uglify-js": {
+          "version": "1.3.5",
+          "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-1.3.5.tgz",
+          "integrity": "sha1-S1v/+Rhu/7qoiOTJ6UvZ/EyUkp0=",
+          "dev": true
+        }
+      }
+    },
     "duplexer": {
       "version": "0.1.1",
       "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.1.tgz",
@@ -7447,6 +7557,11 @@
         "sifter": "^0.5.1"
       }
     },
+    "selectize-plugin-clear": {
+      "version": "0.0.3",
+      "resolved": "https://registry.npmjs.org/selectize-plugin-clear/-/selectize-plugin-clear-0.0.3.tgz",
+      "integrity": "sha1-M8CMSpPClHQKZOgWBSeAKol6m3s="
+    },
     "semver": {
       "version": "5.6.0",
       "resolved": "https://registry.npmjs.org/semver/-/semver-5.6.0.tgz",
@@ -8241,6 +8356,13 @@
         }
       }
     },
+    "uglify-to-browserify": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/uglify-to-browserify/-/uglify-to-browserify-1.0.2.tgz",
+      "integrity": "sha1-bgkk1r2mta/jSeOabWMoUKD4grc=",
+      "dev": true,
+      "optional": true
+    },
     "underscore.string": {
       "version": "3.3.5",
       "resolved": "https://registry.npmjs.org/underscore.string/-/underscore.string-3.3.5.tgz",

+ 1 - 0
package.json

@@ -35,6 +35,7 @@
     "minimist": "^1.2.0",
     "page": "1.8.6",
     "selectize": "0.12.6",
+    "selectize-plugin-clear": "0.0.3",
     "sprintf-js": "1.1.2"
   },
   "devDependencies": {

+ 1 - 1
webpack-stats.json

@@ -1 +1 @@
-{"status":"done","chunks":{"hue":[{"name":"hue-bundle-c56027ed5fcc7f4abc0b.js","path":"/Users/jahlen/dev/hue/desktop/core/src/desktop/static/desktop/js/bundles/hue-bundle-c56027ed5fcc7f4abc0b.js"},{"name":"hue-bundle-c56027ed5fcc7f4abc0b.js.map","path":"/Users/jahlen/dev/hue/desktop/core/src/desktop/static/desktop/js/bundles/hue-bundle-c56027ed5fcc7f4abc0b.js.map"}],"sqlSyntaxWebWorker":[{"name":"sqlSyntaxWebWorker-bundle-c56027ed5fcc7f4abc0b.js","path":"/Users/jahlen/dev/hue/desktop/core/src/desktop/static/desktop/js/bundles/sqlSyntaxWebWorker-bundle-c56027ed5fcc7f4abc0b.js"},{"name":"sqlSyntaxWebWorker-bundle-c56027ed5fcc7f4abc0b.js.map","path":"/Users/jahlen/dev/hue/desktop/core/src/desktop/static/desktop/js/bundles/sqlSyntaxWebWorker-bundle-c56027ed5fcc7f4abc0b.js.map"}]}}
+{"status":"done","chunks":{"hue":[{"name":"hue-bundle-5a1bf7f66484544c5faf.js","path":"/Users/jahlen/dev/hue/desktop/core/src/desktop/static/desktop/js/bundles/hue-bundle-5a1bf7f66484544c5faf.js"},{"name":"hue-bundle-5a1bf7f66484544c5faf.js.map","path":"/Users/jahlen/dev/hue/desktop/core/src/desktop/static/desktop/js/bundles/hue-bundle-5a1bf7f66484544c5faf.js.map"}],"sqlSyntaxWebWorker":[{"name":"sqlSyntaxWebWorker-bundle-5a1bf7f66484544c5faf.js","path":"/Users/jahlen/dev/hue/desktop/core/src/desktop/static/desktop/js/bundles/sqlSyntaxWebWorker-bundle-5a1bf7f66484544c5faf.js"},{"name":"sqlSyntaxWebWorker-bundle-5a1bf7f66484544c5faf.js.map","path":"/Users/jahlen/dev/hue/desktop/core/src/desktop/static/desktop/js/bundles/sqlSyntaxWebWorker-bundle-5a1bf7f66484544c5faf.js.map"}]}}

Некоторые файлы не были показаны из-за большого количества измененных файлов