Explorar o código

HUE-8687 [frontend] Migrate various jquery plugins to webpack

Johan Ahlen %!s(int64=6) %!d(string=hai) anos
pai
achega
d92d831f9d
Modificáronse 29 ficheiros con 13336 adicións e 136 borrados
  1. 0 3
      apps/jobbrowser/src/jobbrowser/templates/job_browser.mako
  2. 8 0
      desktop/core/src/desktop/js/ext/bootstrap.2.3.2.min.js
  3. 1312 0
      desktop/core/src/desktop/js/ext/fileuploader.custom.js
  4. 37 0
      desktop/core/src/desktop/js/ext/jquery/hue.jquery.datatables.sorting.js
  5. 72 0
      desktop/core/src/desktop/js/ext/jquery/hue.jquery.delayedinput.js
  6. 677 0
      desktop/core/src/desktop/js/ext/jquery/hue.jquery.filechooser.js
  7. 337 0
      desktop/core/src/desktop/js/ext/jquery/hue.jquery.hdfs.autocomplete.js
  8. 121 0
      desktop/core/src/desktop/js/ext/jquery/hue.jquery.horizontalscrollbar.js
  9. 42 0
      desktop/core/src/desktop/js/ext/jquery/hue.jquery.lib.js
  10. 114 0
      desktop/core/src/desktop/js/ext/jquery/hue.jquery.migration.js
  11. 136 0
      desktop/core/src/desktop/js/ext/jquery/hue.jquery.notify.js
  12. 70 0
      desktop/core/src/desktop/js/ext/jquery/hue.jquery.rowselector.js
  13. 174 0
      desktop/core/src/desktop/js/ext/jquery/hue.jquery.selector.js
  14. 61 0
      desktop/core/src/desktop/js/ext/jquery/hue.jquery.titleupdater.js
  15. 151 0
      desktop/core/src/desktop/js/ext/jquery/jquery.dataTables.1.8.2.min.js
  16. 26 0
      desktop/core/src/desktop/js/ext/jquery/jquery.total-storage.1.1.3.min.js
  17. 221 0
      desktop/core/src/desktop/js/ext/ko.selectize.custom.js
  18. 9 7
      desktop/core/src/desktop/js/hue.js
  19. 0 55
      desktop/core/src/desktop/static/desktop/ext/css/basictable.css
  20. 0 3
      desktop/core/src/desktop/static/desktop/ext/js/jquery/plugins/jquery.basictable.min.js
  21. 0 22
      desktop/core/src/desktop/static/desktop/js/hue-bundle-10281a5aac52146933c4.js
  22. 0 0
      desktop/core/src/desktop/static/desktop/js/hue-bundle-10281a5aac52146933c4.js.map
  23. 9627 0
      desktop/core/src/desktop/static/desktop/js/hue-bundle-6bd3f5f21e9d494b3f9e.js
  24. 0 0
      desktop/core/src/desktop/static/desktop/js/hue-bundle-6bd3f5f21e9d494b3f9e.js.map
  25. 0 23
      desktop/core/src/desktop/templates/hue.mako
  26. 124 5
      package-lock.json
  27. 8 4
      package.json
  28. 1 1
      webpack-stats.json
  29. 8 13
      webpack.config.js

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

@@ -34,8 +34,6 @@ ${ commonheader("Job Browser", "jobbrowser", user, request) | n,unicode }
 
 <span class="notebook">
 
-<link rel="stylesheet" href="${ static('desktop/ext/css/basictable.css') }">
-
 % if not is_embeddable:
 <link rel="stylesheet" href="${ static('notebook/css/notebook.css') }">
 <link rel="stylesheet" href="${ static('notebook/css/notebook-layout.css') }">
@@ -54,7 +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.basictable.min.js') }"></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>

A diferenza do arquivo foi suprimida porque é demasiado grande
+ 8 - 0
desktop/core/src/desktop/js/ext/bootstrap.2.3.2.min.js


+ 1312 - 0
desktop/core/src/desktop/js/ext/fileuploader.custom.js

@@ -0,0 +1,1312 @@
+/*
+ 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.
+ */
+
+import $ from 'jquery';
+
+//
+// Helper functions
+//
+
+
+let 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
+//
+//
+
+/**
+ * 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;
+        }
+    }
+});
+
+export default qq;

+ 37 - 0
desktop/core/src/desktop/js/ext/jquery/hue.jquery.datatables.sorting.js

@@ -0,0 +1,37 @@
+// 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'
+
+$.fn.dataTableExt.afnSortData['dom-sort-value'] = function (oSettings, iColumn) {
+  var aData = [];
+  oSettings.oApi._fnGetTrNodes(oSettings).forEach(function (nRow) {
+    var oElem = $('td:eq(' + iColumn + ')', nRow);
+    var _val = oElem.text();
+    if (typeof oElem.attr('data-sort-value') == 'undefined') {
+      if (typeof oElem.find('span').attr('data-sort-value') != 'undefined') {
+        _val = parseInt(oElem.find('span').attr('data-sort-value'));
+      }
+    }
+    else {
+      _val = parseInt(oElem.attr('data-sort-value'));
+    }
+    aData.push(_val);
+  });
+
+  return aData;
+};
+

+ 72 - 0
desktop/core/src/desktop/js/ext/jquery/hue.jquery.delayedinput.js

@@ -0,0 +1,72 @@
+// 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.
+/*
+* jHue Delayed Input plugin
+* use it with
+* $("#element").jHueDelayedInput( __FUNCTION_YOU_WANT_TO_CALL__, __TIMEOUT_IN_MS__ [optional])
+*/
+
+import $ from 'jquery'
+
+var pluginName = "jHueDelayedInput",
+    defaults = {
+      fn: null,
+      timeout: 300,
+      skipOnEnterAndKeys: false
+    };
+
+function Plugin(element, options) {
+  this.element = element;
+  this.options = $.extend({}, defaults, options);
+  this._defaults = defaults;
+  this._name = pluginName;
+  this.init();
+}
+
+Plugin.prototype.setOptions = function (options) {
+  this.options = $.extend({}, defaults, options);
+};
+
+Plugin.prototype.init = function () {
+  var _this = this;
+  var _timeout = -1;
+  if (_this.options.fn != null) {
+    var event = isIE11 ? 'input' : 'keyup';
+
+    $(_this.element).on(event, function (e) {
+      if (!(_this.options.skipOnEnterAndKeys && [13, 37, 38, 39, 40].indexOf(e.keyCode) > -1)){
+        window.clearTimeout(_timeout);
+        _timeout = window.setTimeout(_this.options.fn, _this.options.timeout);
+      }
+    });
+  }
+};
+
+$.fn[pluginName] = function (fn, timeout, skipOnEnterAndKeys) {
+  var _options = {
+    fn: fn,
+    timeout: timeout,
+    skipOnEnterAndKeys: typeof skipOnEnterAndKeys !== 'undefined' && skipOnEnterAndKeys
+  }
+  return this.each(function () {
+    if (!$.data(this, 'plugin_' + pluginName)) {
+      $.data(this, 'plugin_' + pluginName, new Plugin(this, _options));
+    }
+    else {
+      $.data(this, 'plugin_' + pluginName).setOptions(_options);
+    }
+  });
+}

+ 677 - 0
desktop/core/src/desktop/js/ext/jquery/hue.jquery.filechooser.js

@@ -0,0 +1,677 @@
+// 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.
+/*
+ * jHue fileChooser plugin
+ */
+
+import $ from 'jquery';
+import huePubSub from '../../utils/huePubSub';
+
+var pluginName = "jHueFileChooser",
+  defaults = {
+    initialPath: "",
+    forceRefresh: false,
+    errorRedirectPath: "",
+    createFolder: true,
+    uploadFile: true,
+    selectFolder: false,
+    suppressErrors: false,
+    displayOnlyFolders: false,
+    showExtraHome: false,
+    extraHomeProperties: {},
+    filterExtensions: "",
+    labels: {
+      BACK: "Back",
+      SELECT_FOLDER: "Select this folder",
+      CREATE_FOLDER: "Create folder",
+      FOLDER_NAME: "Folder name",
+      CANCEL: "Cancel",
+      FILE_NOT_FOUND: "The file has not been found",
+      UPLOAD_FILE: "Upload a file",
+      FAILED: "Failed",
+      HOME: "Home"
+    },
+    filesystems: ['hdfs'],
+    filesysteminfo: {
+      "": {
+        scheme: "",
+        root: "/",
+        home: "/?default_to_home",
+        icon: {
+          brand: "fa-files-o",
+          home: "fa-home",
+        },
+        label : {
+          home: "home",
+          name: "HDFS",
+        }
+      },
+      hdfs: {
+        scheme: "",
+        root: "/",
+        home: "/?default_to_home",
+        icon: {
+          brand: "fa-files-o",
+          home: "fa-home",
+        },
+        label : {
+          home: "home",
+          name: "HDFS",
+        }
+      },
+      s3a: {
+        scheme: "s3a",
+        root: "s3a://",
+        home: "s3a://",
+        icon: {
+          brand: "fa-cubes",
+          home: "fa-cubes",
+        },
+        label : {
+          home: "",
+          name: "S3"
+        }
+      },
+      adl: {
+        scheme: "adl",
+        root: "adl:/",
+        home: "adl:/",
+        icon: {
+          svg:{
+            brand: "#hi-adls",
+            home: "#hi-adls"
+          },
+          brand: "fa-windows",
+          home: "fa-windows"
+        },
+        label : {
+          home: "",
+          name: "ADLS"
+        }
+      }
+    },
+    fsSelected: 'hdfs',
+    user: "",
+    onNavigate: function () {
+    },
+    onFileChoose: function () {
+    },
+    onFolderChoose: function () {
+    },
+    onFolderChange: function () {
+    },
+    onError: function () {
+    }
+  },
+  STORAGE_PREFIX = "hueFileBrowserLastPathForUser_";
+
+function Plugin(element, options) {
+  this.element = element;
+  $(element).data('jHueFileChooser', this);
+
+  this.options = $.extend({}, defaults, { user: LOGGED_USERNAME }, options);
+  this.options.labels = $.extend({}, defaults.labels, HUE_I18n.jHueFileChooser, options ? options.labels : {});
+  this._defaults = defaults;
+  this._name = pluginName;
+  this.previousPath = "";
+  this.init();
+}
+
+Plugin.prototype.setOptions = function (options) {
+  var self = this;
+  self.options = $.extend({}, defaults, { user: LOGGED_USERNAME }, options);
+  self.options.labels = $.extend({}, defaults.labels, HUE_I18n.jHueFileChooser, options ? options.labels : {});
+  var initialPath = $.trim(self.options.initialPath);
+  var scheme = initialPath && initialPath.substring(0,initialPath.indexOf(":"));
+  if (scheme && scheme.length) {
+    self.options.fsSelected = scheme;
+  }
+
+  $(self.element).find('.filechooser-services li').removeClass('active');
+  $(self.element).find('.filechooser-services li[data-fs="' + self.options.fsSelected + '"]').addClass('active');
+
+  if (self.options.forceRefresh) {
+    if (initialPath != "") {
+      self.navigateTo(self.options.initialPath);
+    } else if ($.totalStorage(STORAGE_PREFIX + self.options.user + self.options.fsSelected) != null) {
+      self.navigateTo($.totalStorage(STORAGE_PREFIX + self.options.user + self.options.fsSelected));
+    } else {
+      self.navigateTo("/?default_to_home");
+    }
+  } else {
+    if (initialPath != "") {
+      self.navigateTo(self.options.initialPath);
+    } else if ($.totalStorage(STORAGE_PREFIX + self.options.user + self.options.fsSelected) != null) {
+      self.navigateTo($.totalStorage(STORAGE_PREFIX + self.options.user + self.options.fsSelected));
+    }
+  }
+};
+
+function getScheme (path) {
+  var index = path.indexOf("://");
+  return index >= 0 ? path.substring(0, index) : "hdfs";
+}
+
+function getFs (scheme) {
+  if (scheme === 'adl') {
+    return 'adls';
+  } else if (scheme === 's3a' ){
+    return 's3';
+  } else if (!scheme || scheme === 'hdfs') {
+    return 'hdfs';
+  } else {
+    return scheme;
+  }
+}
+
+Plugin.prototype.setFileSystems = function (filesystems) {
+  var self = this, filters, filesystemsFiltered;
+  self.options.filesystems = [];
+  Object.keys(filesystems).forEach(function (k) {
+    if (filesystems[k]) {
+      self.options.filesystems.push(k);
+    }
+  });
+  self.options.filesystems.sort();
+  if (self.options.filesystemsFilter) {
+    filters = self.options.filesystemsFilter.reduce(function(filters, fs) {
+    filters[fs] = true;
+    return filters;
+  }, {});
+    filesystemsFiltered = self.options.filesystems.filter(function(fs) {
+      return filters[fs];
+    });
+  } else {
+    filesystemsFiltered = self.options.filesystems;
+  }
+
+  $(self.element).data('fs', filesystemsFiltered);
+  if (filesystemsFiltered.length > 1) {
+    var $ul = $('<ul>').addClass('nav nav-list').css('border', 'none');
+    filesystemsFiltered.forEach(function (fs) {
+      var filesysteminfo = self.options.filesysteminfo;
+      var $li = $('<li>').attr('data-fs', fs).addClass(self.options.fsSelected === fs ? 'active' : '').html('<a class="pointer" style="padding-left: 6px">' + (filesysteminfo[fs] ? filesysteminfo[fs].label.name : fs.toUpperCase()) + '</a>');
+      $li.on('click', function () {
+        $(this).siblings().removeClass('active');
+        $(this).addClass('active');
+        self.options.fsSelected = fs;
+        var storedPath = $.totalStorage(STORAGE_PREFIX + self.options.user + self.options.fsSelected);
+        if (storedPath !== null) {
+          if (filesysteminfo[fs] && storedPath.toLowerCase().indexOf(fs) === -1) {
+            self.navigateTo(filesysteminfo[fs].home);
+          } else {
+            self.navigateTo(storedPath);
+          }
+        } else {
+          self.navigateTo(filesysteminfo[fs] ? filesysteminfo[fs].home : '/?default_to_home');
+        }
+      });
+      $li.appendTo($ul);
+    });
+    $(self.element).find('.filechooser-services').empty().width(80);
+    $(self.element).find('.filechooser-tree').width(480).css('paddingLeft', '6px').css('borderLeft', '1px solid #EEE').css('marginLeft', '80px').css('min-height', '330px');
+    $ul.appendTo($(self.element).find('.filechooser-services'));
+  }
+};
+
+//TODO: refactor this method to template
+Plugin.prototype.navigateTo = function (path) {
+  var _parent = this;
+  $(_parent.element).find('.filechooser-tree').html("<i style=\"font-size: 24px; color: #DDD\" class=\"fa fa-spinner fa-spin\"></i>");
+  var pageSize = '?pagesize=1000';
+  if (path.indexOf('?') > -1) {
+    pageSize = pageSize.replace(/\?/, '&');
+  }
+  $.getJSON("/filebrowser/view=" + path + pageSize, function (data) {
+    $(_parent.element).find('.filechooser-tree').empty();
+
+    path = data.current_dir_path || path; // use real path.
+    var _flist = $("<ul>").addClass("unstyled").css({
+      'height': '260px',
+      'overflow-y': 'auto'
+    });
+    var $homeBreadcrumb = $("<ul>").addClass("hue-breadcrumbs").css({
+      'padding': '0',
+      'marginLeft': '0',
+      'float': 'left',
+      'white-space': 'nowrap'
+    });
+    var _home = $("<li>");
+    //var filesysteminfo = self.options.filesysteminfo;
+    var fs = _parent.options.filesysteminfo[_parent.options.fsSelected || "hdfs"];
+    var el = fs.icon.svg ? '<svg class="hi"><use xlink:href="'+fs.icon.svg.home+'"></use></svg>' : '<i class="fa '+fs.icon.home+'"></i> ' + fs.label.home;
+    var _homelink = $("<a>").addClass("nounderline").html(el).css("cursor", "pointer").click(function () {
+      _parent.navigateTo(fs.home);
+    });
+
+    _homelink.appendTo(_home);
+    _home.appendTo($homeBreadcrumb);
+
+    $("<span>").addClass("divider").css("margin-right", "20px").appendTo(_home);
+
+    if (data.error || (data.title != null && data.title == "Error")) {
+      $homeBreadcrumb.appendTo($(_parent.element).find('.filechooser-tree'));
+      $("<div class='clearfix'>").appendTo($(_parent.element).find('.filechooser-tree'));
+      var _errorMsg = $("<div>").addClass("alert").addClass("alert-error").text(data.message ? data.message : data.error);
+      _errorMsg.appendTo($(_parent.element).find('.filechooser-tree'));
+      //TODO: allow user to user breadcrums when there is an error
+      var _previousLink = $("<a>").addClass("btn").text(_parent.options.labels.BACK).click(function () {
+        function getParentPath (path) {
+          if (!path) return path;
+          var indexFirst = path.indexOf("/");
+          var indexLast = path.lastIndexOf("/");
+          return indexLast - indexFirst > 1 && indexLast > 0 ? path.substring(0, indexLast + 1) : path;
+        }
+        var next = path !== _parent.previousPath && getScheme(path) === getScheme(_parent.previousPath) ? _parent.previousPath : getParentPath(path);
+        _parent.options.onFolderChange(next);
+        _parent.navigateTo(next);
+      });
+      _previousLink.appendTo($(_parent.element).find('.filechooser-tree'));
+    } else {
+      if (data.type == "file") {
+        _parent.navigateTo(data.view.dirname);
+        return;
+      }
+      $.totalStorage(STORAGE_PREFIX + _parent.options.user + _parent.options.fsSelected, path);
+      _parent.previousPath = path;
+      _parent.options.onNavigate(_parent.previousPath);
+
+      var $search = $('<div>').html('<i class="fa fa-refresh inactive-action pointer" style="position: absolute; top: 3px; margin-left: -16px"></i> <i class="fa fa-search inactive-action pointer" style="position: absolute; top: 3px"></i><input type="text" class="small-search" style="display: none; width: 0; padding: 2px; padding-left: 20px">').css({
+        'position': 'absolute',
+        'right': '20px',
+        'background-color': '#FFF'
+      });
+
+      let slideOutInput = () => {
+        $search.find('input').animate({
+          'width': '0'
+        }, 100, function(){
+          $search.find('input').hide();
+          $search.find('.fa-refresh').show();
+        });
+      }
+
+      var $searchInput = $search.find('input');
+      let tog = (v) => v ? "addClass" : "removeClass";
+      $searchInput.addClass("clearable");
+      $searchInput.on("input", function () {
+        $searchInput[tog(this.value)]("x");
+      })
+      .on("mousemove", function (e) {
+        $searchInput[tog(this.offsetWidth - 18 < e.clientX - this.getBoundingClientRect().left)]("onX");
+      })
+      .on("click", function (e) {
+        if (this.offsetWidth - 18 < e.clientX - this.getBoundingClientRect().left) {
+          $searchInput.removeClass("x onX").val("");
+        }
+      });
+      if (!isIE11) {
+        $searchInput.on("blur", function (e) {
+          if ($searchInput.val() === ''){
+            slideOutInput();
+          }
+        });
+      }
+
+      $search.find('.fa-search').on('click', function(){
+        if ($searchInput.is(':visible')){
+          slideOutInput();
+        } else {
+          $search.find('.fa-refresh').hide();
+          $searchInput.show().animate({
+            'width': '100px'
+          }, 100, function(){
+            $searchInput.focus();
+          });
+        }
+      });
+
+      $search.find('.fa-refresh').on('click', function(){
+        _parent.navigateTo(path);
+      });
+
+      $search.appendTo($(_parent.element).find('.filechooser-tree'));
+
+      var $scrollingBreadcrumbs = $("<ul>").addClass("hue-breadcrumbs editable-breadcrumbs").css({
+        'padding': '0',
+        'marginLeft': '10px',
+        'marginBottom': '0',
+        'paddingRight': '10px',
+        'float': 'left',
+        'width': '300px',
+        'overflow-x': 'scroll',
+        'overflow-y': 'hidden',
+        'white-space': 'nowrap'
+      });
+
+      if (ko && ko.bindingHandlers.delayedOverflow) {
+        ko.bindingHandlers.delayedOverflow.init($scrollingBreadcrumbs[0]);
+      }
+
+      if (_parent.options.showExtraHome) {
+        var _extraHome = $("<li>");
+        var _extraHomelink = $("<a>").addClass("nounderline").html('<i class="fa ' + _parent.options.extraHomeProperties.icon + '"></i> ' + _parent.options.extraHomeProperties.label).css("cursor", "pointer").click(function () {
+          _parent.navigateTo(_parent.options.extraHomeProperties.path);
+        });
+        _extraHomelink.appendTo(_extraHome);
+        $("<span>").addClass("divider").css("margin-right", "20px").appendTo(_extraHome);
+        _extraHome.appendTo($scrollingBreadcrumbs);
+      }
+
+      var $hdfsAutocomplete = $('<input type="text">').addClass('editable-breadcrumb-input').val(path).hide();
+
+      $scrollingBreadcrumbs.click(function (e) {
+        if ($(e.target).is('ul') || $(e.target).hasClass('spacer')) {
+          $(this).hide();
+          $hdfsAutocomplete.show().focus();
+        }
+      });
+
+      var $editBreadcrumbs = $("<li>").css('marginRight', '2px');
+      var $crumbLink = $("<span>").addClass('spacer');
+      $crumbLink.html('&nbsp;').appendTo($editBreadcrumbs);
+      $editBreadcrumbs.appendTo($scrollingBreadcrumbs);
+      if (typeof data.breadcrumbs != "undefined" && data.breadcrumbs != null) {
+        var _bLength = data.breadcrumbs.length;
+        $(data.breadcrumbs).each(function (cnt, crumb) {
+          var _crumb = $("<li>");
+          var _crumbLink = $("<a>");
+          var _crumbLabel = (crumb.label != null && crumb.label != "") ? crumb.label : "/";
+          _crumbLink.attr("href", "javascript:void(0)").text(_crumbLabel).appendTo(_crumb);
+          if (cnt < _bLength - 1) {
+            if (cnt > 0) {
+              $("<span>").addClass("divider").text("/").appendTo(_crumb);
+            } else {
+              $("<span>").html("&nbsp;").appendTo(_crumb);
+            }
+          }
+          _crumb.click(function () {
+            var _url = (crumb.url != null && crumb.url != "") ? crumb.url : "/";
+            _parent.options.onFolderChange(_url);
+            _parent.navigateTo(_url);
+          });
+          _crumb.appendTo($scrollingBreadcrumbs);
+        });
+      }
+      $homeBreadcrumb.appendTo($(_parent.element).find('.filechooser-tree'));
+      $scrollingBreadcrumbs.appendTo($(_parent.element).find('.filechooser-tree'));
+      $hdfsAutocomplete.appendTo($(_parent.element).find('.filechooser-tree'));
+
+      $hdfsAutocomplete.jHueHdfsAutocomplete({
+        home: "/user/" + _parent.options.user + "/",
+        skipEnter: true,
+        skipKeydownEvents: true,
+        onEnter: function (el) {
+          var _url = el.val();
+          _parent.options.onFolderChange(_url);
+          _parent.navigateTo(_url);
+          $("#jHueHdfsAutocomplete").hide();
+        },
+        onBlur: function () {
+          $hdfsAutocomplete.hide();
+          $scrollingBreadcrumbs.show();
+        },
+        smartTooltip: _parent.options.labels.SMART_TOOLTIP
+      });
+
+      $('<div>').addClass('clearfix').appendTo($(_parent.element).find('.filechooser-tree'));
+
+      var resizeBreadcrumbs = window.setInterval(function(){
+        if ($homeBreadcrumb.is(':visible') && $homeBreadcrumb.width() > 0){
+          window.clearInterval(resizeBreadcrumbs);
+          $scrollingBreadcrumbs.width($(_parent.element).find('.filechooser-tree').width() - $homeBreadcrumb.width() - 65);
+        }
+      }, 100);
+
+      $(data.files).each(function (cnt, file) {
+        var _addFile = file.name !== '.';
+        if (_parent.options.filterExtensions != "" && file.type == "file") {
+          var _allowedExtensions = _parent.options.filterExtensions.split(",");
+          var _fileExtension = file.name.split(".").pop().toLowerCase();
+          _addFile = _allowedExtensions.indexOf(_fileExtension) > -1;
+        }
+        if (_addFile) {
+          var _f = $("<li>");
+          var _flink = $("<a>");
+
+          if (file.type == "dir") {
+            _flink.attr("href", "javascript:void(0)");
+            if (file.path.toLowerCase().indexOf('s3a://') == 0 && (file.path.substr(6).indexOf('/') > -1 || file.path.substr(6) == '')) {
+              _flink.text(" " + (cnt > 0 ? file.name : ".."))
+            } else {
+              _flink.text(" " + (file.name != "" ? file.name : ".."));
+            }
+            if (_flink.text() !== ' ..') {
+              _f.addClass('file-list-item');
+            }
+            _flink.appendTo(_f);
+            if (file.path.toLowerCase().indexOf('s3a://') == 0 && file.path.substr(5).indexOf('/') == -1) {
+              $("<i class='fa fa-cloud'></i>").prependTo(_flink);
+            } else {
+              $("<i class='fa fa-folder'></i>").prependTo(_flink);
+            }
+            _flink.click(function () {
+              _parent.options.onFolderChange(file.path);
+              _parent.navigateTo(file.path);
+            });
+          }
+          if (file.type == "file" && !_parent.options.displayOnlyFolders) {
+            _f.addClass('file-list-item');
+            _flink.attr("href", "javascript:void(0)").text(" " + (file.name != "" ? file.name : "..")).appendTo(_f);
+            $("<i class='fa fa-file-o'></i>").prependTo(_flink);
+            _flink.click(function () {
+              _parent.options.onFileChoose(file.path);
+            });
+          }
+          _f.appendTo(_flist);
+        }
+      });
+
+      _flist.appendTo($(_parent.element).find('.filechooser-tree'));
+
+      $searchInput.jHueDelayedInput(function () {
+        var filter = $searchInput.val().toLowerCase();
+        var results = 0;
+        $(_parent.element).find('.filechooser-tree .no-results').hide();
+        $(_parent.element).find('.filechooser-tree .file-list-item').each(function(){
+          if ($(this).text().toLowerCase().indexOf(filter) > -1) {
+            $(this).show();
+            results++;
+          } else {
+            $(this).hide();
+          }
+        });
+        if (results == 0){
+          $(_parent.element).find('.filechooser-tree .no-results').show();
+        }
+      }, 300);
+
+      var _actions = $("<div>").addClass("jHueFilechooserActions");
+      var _showActions = false;
+      var _uploadFileBtn;
+      var _createFolderBtn;
+      var _selectFolderBtn;
+      if (_parent.options.uploadFile) {
+        _uploadFileBtn = $("<div>").attr("id", "file-uploader").addClass('fileChooserActionUploader');
+        _uploadFileBtn.appendTo(_actions);
+        _showActions = true;
+        initUploader(path, _parent, _uploadFileBtn, _parent.options.labels);
+      }
+      if (_parent.options.selectFolder) {
+        _selectFolderBtn = $("<a>").addClass("btn").text(_parent.options.labels.SELECT_FOLDER);
+        if (_parent.options.uploadFile) {
+          _selectFolderBtn.css("margin-top", "10px");
+        }
+        _selectFolderBtn.appendTo(_actions);
+        _showActions = true;
+        _selectFolderBtn.click(function () {
+          _parent.options.onFolderChoose(path);
+        });
+      }
+      $("<span> </span>").appendTo(_actions);
+      if (_parent.options.createFolder) {
+        _createFolderBtn = $("<a>").addClass("btn").text(_parent.options.labels.CREATE_FOLDER);
+        if (_parent.options.uploadFile) {
+          _createFolderBtn.css("margin-top", "10px");
+        }
+        _createFolderBtn.appendTo(_actions);
+        _showActions = true;
+        var _createFolderDetails = $("<form>").css({"margin-top": "10px", "position": "fixed"}).addClass("form-inline");
+        _createFolderDetails.hide();
+        var _folderName = $("<input>").attr("type", "text").attr("placeholder", _parent.options.labels.FOLDER_NAME).appendTo(_createFolderDetails);
+        $("<span> </span>").appendTo(_createFolderDetails);
+        var _folderBtn = $("<input>").attr("type", "button").attr("value", _parent.options.labels.CREATE_FOLDER).addClass("btn primary").appendTo(_createFolderDetails);
+        $("<span> </span>").appendTo(_createFolderDetails);
+        var _folderCancel = $("<input>").attr("type", "button").attr("value", _parent.options.labels.CANCEL).addClass("btn").appendTo(_createFolderDetails);
+        _folderCancel.click(function () {
+          if (_uploadFileBtn) {
+            _uploadFileBtn.removeClass("disabled");
+          }
+          _createFolderBtn.removeClass("disabled");
+          _createFolderDetails.slideUp();
+        });
+        _folderBtn.click(function () {
+          if (_folderName.val().length > 0) {
+            $.ajax({
+              type: "POST",
+              url: "/filebrowser/mkdir",
+              data: {
+                name: _folderName.val(),
+                path: path
+              },
+              success: function (xhr, status) {
+                if (status == "success") {
+                  _parent.navigateTo(path);
+                  if (_uploadFileBtn) {
+                    _uploadFileBtn.removeClass("disabled");
+                  }
+                  _createFolderBtn.removeClass("disabled");
+                  _createFolderDetails.slideUp();
+                }
+              },
+              error: function (xhr) {
+                $(document).trigger("error", xhr.responseText);
+              }
+            });
+          }
+        });
+
+        _createFolderDetails.appendTo(_actions);
+
+        _createFolderBtn.click(function () {
+          if (_uploadFileBtn) {
+            _uploadFileBtn.addClass("disabled");
+          }
+          _createFolderBtn.addClass("disabled");
+          _createFolderDetails.slideDown();
+        });
+      }
+      if (_showActions) {
+        _actions.appendTo($(_parent.element).find('.filechooser-tree'));
+      }
+
+      window.setTimeout(function () {
+        $(_parent.element).parent().scrollTop(0);
+        $scrollingBreadcrumbs.animate({
+          'scrollLeft': $scrollingBreadcrumbs.width()
+        });
+      }, 0);
+    }
+  }).fail(function (e) {
+    if (!_parent.options.suppressErrors) {
+      $(document).trigger("info", _parent.options.labels.FILE_NOT_FOUND);
+      _parent.options.onError();
+    }
+    if (e.status === 404 || e.status === 500) {
+      var fs = _parent.options.filesysteminfo[_parent.options.fsSelected || "hdfs"];
+      _parent.navigateTo(_parent.options.errorRedirectPath !== "" ? _parent.options.errorRedirectPath : fs.home);
+    } else {
+      console.error(e);
+      $(document).trigger("error", e.statusText);
+    }
+  });
+};
+
+var num_of_pending_uploads = 0;
+
+function initUploader(path, _parent, el, labels) {
+  var uploader = new qq.FileUploader({
+    element: el[0],
+    action: '/filebrowser/upload/file',
+    params: {
+      dest: path,
+      fileFieldLabel: 'hdfs_file'
+    },
+    onComplete: function (id, fileName, responseJSON) {
+      num_of_pending_uploads--;
+      if (responseJSON.status == -1) {
+        $(document).trigger("error", responseJSON.data);
+      } else if (!num_of_pending_uploads) {
+        _parent.navigateTo(path);
+        huePubSub.publish('assist.' + getFs(getScheme(path)) + '.refresh');
+      }
+    },
+    onSubmit: function (id, fileName) {
+      num_of_pending_uploads++;
+    },
+    template: '<div class="qq-uploader">' +
+    '<div class="qq-upload-drop-area"><span></span></div>' +
+    '<div class="qq-upload-button">' + labels.UPLOAD_FILE + '</div><br>' +
+    '<ul class="qq-upload-list"></ul>' +
+    '</div>',
+    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="#">' + labels.CANCEL + '</a>' +
+    '<span class="qq-upload-failed-text">' + labels.FAILED + '</span>' +
+    '</li>',
+    debug: false
+  });
+}
+
+Plugin.prototype.init = function () {
+  var self = this;
+  $(self.element).empty().html('<div class="filechooser-container" style="position: relative"><div class="filechooser-services" style="position: absolute"></div><div class="filechooser-tree" style="width: 560px"></div></div>');
+  $.post('/filebrowser/api/get_filesystems', function (data) {
+    var initialPath = $.trim(self.options.initialPath);
+    var scheme = initialPath && initialPath.substring(0,initialPath.indexOf(":"));
+    if (data && data.status === 0) {
+      if (scheme && scheme.length && data.filesystems[scheme]) {
+        self.options.fsSelected = scheme;
+      }
+      self.setFileSystems(data.filesystems);
+    }
+    if (initialPath != "") {
+      self.navigateTo(self.options.initialPath);
+    } else if ($.totalStorage(STORAGE_PREFIX + self.options.user + self.options.fsSelected) != null) {
+      self.navigateTo($.totalStorage(STORAGE_PREFIX + self.options.user + self.options.fsSelected));
+    } else {
+      self.navigateTo("/?default_to_home");
+    }
+  });
+};
+
+$.fn[pluginName] = function (options) {
+  return this.each(function () {
+    if (!$.data(this, 'plugin_' + pluginName)) {
+      $.data(this, 'plugin_' + pluginName, new Plugin(this, options));
+    }
+    else {
+      $.data(this, 'plugin_' + pluginName).setOptions(options);
+    }
+  });
+};

+ 337 - 0
desktop/core/src/desktop/js/ext/jquery/hue.jquery.hdfs.autocomplete.js

@@ -0,0 +1,337 @@
+// 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.
+/*
+ * jHue HDFS autocomplete plugin
+ * augment a textbox into an HDFS autocomplete
+ */
+
+import $ from 'jquery';
+import hueUtils from '../../utils/hueUtils';
+
+var pluginName = "jHueHdfsAutocomplete",
+    defaults = {
+      home: "/",
+      onEnter: function () {
+      },
+      onBlur: function () {
+      },
+      onPathChange: function () {
+      },
+      smartTooltip: "",
+      smartTooltipThreshold: 10, // needs 10 up/down or click actions and no tab to activate the smart tooltip
+      showOnFocus: false,
+      skipKeydownEvents: false,
+      skipEnter: false,
+      skipScrollEvent: false,
+      zIndex: 33000,
+      root: "/",
+      isS3: false
+    };
+
+function Plugin(element, options) {
+  this.element = element;
+  this.options = $.extend({}, defaults, options);
+  this._defaults = defaults;
+  this._name = pluginName;
+  this.init();
+}
+
+Plugin.prototype.init = function () {
+
+  var _this = this;
+  var _el = $(_this.element);
+  _el.addClass("jHueAutocompleteElement");
+  _el.attr("autocomplete", "off"); // prevents default browser behavior
+
+  // creates autocomplete popover
+  if ($("#jHueHdfsAutocomplete").length == 0) {
+    $("<div>").attr("id", "jHueHdfsAutocomplete").addClass("jHueAutocomplete popover")
+        .attr("style", "position:absolute;display:none;max-width:1000px;z-index:" + _this.options.zIndex)
+        .html('<div class="arrow"></div><div class="popover-inner"><h3 class="popover-title"></h3><div class="popover-content"><p><ul class="unstyled"></ul></p></div></div>')
+        .appendTo($(HUE_CONTAINER));
+  }
+
+  function setHueBreadcrumbCaretAtEnd(element) {
+    var elemLength = element.value.length;
+    if (document.selection) {
+      element.focus();
+      var _oSel = document.selection.createRange();
+      _oSel.moveStart('character', -elemLength);
+      _oSel.moveStart('character', elemLength);
+      _oSel.moveEnd('character', 0);
+      _oSel.select();
+    }
+    else if (element.selectionStart || element.selectionStart == '0') {
+      element.selectionStart = elemLength;
+      element.selectionEnd = elemLength;
+      element.focus();
+    }
+  }
+
+
+  _el.focus(function () {
+    $(document.body).on("contextmenu", function (e) {
+      e.preventDefault(); // prevents native menu on FF for Mac from being shown
+    });
+    setHueBreadcrumbCaretAtEnd(_this.element);
+  });
+
+  _el.keydown(function (e) {
+    if (e.keyCode == 9) {
+      e.preventDefault();
+      showHdfsAutocomplete(function () {
+        var path = _el.val();
+        if (path.indexOf("/") > -1) {
+          path = path.substr(path.lastIndexOf("/") + 1);
+        }
+        guessHdfsPath(path);
+      });
+    }
+  });
+
+  function smartTooltipMaker() {
+    if (_this.options.smartTooltip != "" && typeof $.totalStorage != "undefined" && $.totalStorage("jHueHdfsAutocompleteTooltip") != -1) {
+      var cnt = 0;
+      if ($.totalStorage("jHueHdfsAutocompleteTooltip") != null) {
+        cnt = $.totalStorage("jHueHdfsAutocompleteTooltip") + 1;
+      }
+      $.totalStorage("jHueHdfsAutocompleteTooltip", cnt);
+      if (cnt >= _this.options.smartTooltipThreshold) {
+        _el.tooltip({
+          animation: true,
+          title: _this.options.smartTooltip,
+          trigger: "manual",
+          placement: "top"
+        }).tooltip("show");
+        window.setTimeout(function () {
+          _el.tooltip("hide");
+        }, 10000);
+        $.totalStorage("jHueHdfsAutocompleteTooltip", -1);
+      }
+    }
+  }
+
+  if (! _this.options.skipScrollEvent){
+    $(window).on("scroll", function(){
+      $("#jHueHdfsAutocomplete").css("top", _el.offset().top + _el.outerHeight() - 1).css("left", _el.offset().left).width(_el.outerWidth() - 4);
+    });
+  }
+
+
+  _el.on("keydown", function (e) {
+    if (!_this.options.skipKeydownEvents && e.keyCode == 191) {
+      e.preventDefault();
+    }
+    if (e.keyCode == 32 && e.ctrlKey) {
+      e.preventDefault();
+    }
+    if (_this.options.skipEnter && e.keyCode === 13){
+      e.preventDefault();
+      e.stopPropagation();
+      e.stopImmediatePropagation();
+    }
+  });
+
+
+  var _hdfsAutocompleteSelectedIndex = -1;
+  var _filterTimeout = -1;
+  _el.keyup(function (e) {
+    window.clearTimeout(_filterTimeout);
+    if ($.inArray(e.keyCode, [38, 40, 13, 32, 191]) == -1) {
+      _hdfsAutocompleteSelectedIndex = -1;
+      _filterTimeout = window.setTimeout(function () {
+        var path = _el.val();
+        if (path.indexOf("/") > -1) {
+          path = path.substr(path.lastIndexOf("/") + 1);
+        }
+        $("#jHueHdfsAutocomplete ul li").show();
+        $("#jHueHdfsAutocomplete ul li").each(function () {
+          if ($(this).text().trim().indexOf(path) != 0) {
+            $(this).hide();
+          }
+        });
+      }, 500);
+    }
+    if (e.keyCode == 38) {
+      if (_hdfsAutocompleteSelectedIndex <= 0) {
+        _hdfsAutocompleteSelectedIndex = $("#jHueHdfsAutocomplete ul li:visible").length - 1;
+      }
+      else {
+        _hdfsAutocompleteSelectedIndex--;
+      }
+    }
+    if (e.keyCode == 40) {
+      if (_hdfsAutocompleteSelectedIndex == $("#jHueHdfsAutocomplete ul li:visible").length - 1) {
+        _hdfsAutocompleteSelectedIndex = 0;
+      }
+      else {
+        _hdfsAutocompleteSelectedIndex++;
+      }
+    }
+    if (e.keyCode == 38 || e.keyCode == 40) {
+      smartTooltipMaker();
+      $("#jHueHdfsAutocomplete ul li").removeClass("active");
+      $("#jHueHdfsAutocomplete ul li:visible").eq(_hdfsAutocompleteSelectedIndex).addClass("active");
+      $("#jHueHdfsAutocomplete .popover-content").scrollTop($("#jHueHdfsAutocomplete ul li:visible").eq(_hdfsAutocompleteSelectedIndex).prevAll().length * $("#jHueHdfsAutocomplete ul li:visible").eq(_hdfsAutocompleteSelectedIndex).outerHeight());
+    }
+    if ((e.keyCode == 32 && e.ctrlKey) || e.keyCode == 191) {
+      smartTooltipMaker();
+      showHdfsAutocomplete();
+    }
+    if (e.keyCode == 13) {
+      if (_hdfsAutocompleteSelectedIndex > -1) {
+        $("#jHueHdfsAutocomplete ul li:visible").eq(_hdfsAutocompleteSelectedIndex).click();
+      }
+      else {
+        _this.options.onEnter($(this));
+      }
+      $("#jHueHdfsAutocomplete").hide();
+      _hdfsAutocompleteSelectedIndex = -1;
+    }
+  });
+
+  if (_this.options.showOnFocus){
+    _el.on("focus", function(){
+      showHdfsAutocomplete();
+    });
+  }
+
+  var _pauseBlur = false;
+
+  _el.blur(function () {
+    if (!_pauseBlur) {
+      $(document.body).off("contextmenu");
+      $("#jHueHdfsAutocomplete").hide();
+      _this.options.onBlur();
+    }
+  });
+
+  var BASE_PATH = "/filebrowser/view=";
+  var _currentFiles = [];
+
+  function showHdfsAutocomplete(callback) {
+    var base = "";
+    var path = _el.val();
+    var hasScheme = path.indexOf(":/") >= 0;
+    var isRelative = !hasScheme && path.charAt(0) !== "/";
+    if (isRelative && _this.options.root) {
+      base += _this.options.root;
+    }
+    var autocompleteUrl = BASE_PATH + base + path;
+    $.getJSON(autocompleteUrl + "?pagesize=1000&format=json", function (data) {
+      _currentFiles = [];
+      if (data.error == null) {
+        $(data.files).each(function (cnt, item) {
+          if (item.name != ".") {
+            var ico = "fa-file-o";
+            if (item.type == "dir") {
+              ico = "fa-folder";
+            }
+            _currentFiles.push('<li class="hdfsAutocompleteItem" data-value="' + hueUtils.escapeOutput(item.name) + '"><i class="fa ' + ico + '"></i> ' + hueUtils.escapeOutput(item.name) + '</li>');
+          }
+        });
+        window.setTimeout(function () {
+          $("#jHueHdfsAutocomplete").css("top", _el.offset().top + _el.outerHeight() - 1).css("left", _el.offset().left).width(_el.outerWidth() - 4);
+          $("#jHueHdfsAutocomplete").find("ul").empty().html(_currentFiles.join(""));
+          $("#jHueHdfsAutocomplete").find("li").on("click", function (e) {
+            smartTooltipMaker();
+            e.preventDefault();
+            var item = $(this).text().trim();
+            if (item == "..") { // one folder up
+              path = path.substring(0, path.lastIndexOf("/"));
+            } else {
+              path = path + (path.charAt(path.length - 1) == "/" ? "" : "/") + item;
+            }
+            _el.val(base + path);
+            if ($(this).html().indexOf("folder") > -1) {
+              _el.val(_el.val() + "/");
+              _this.options.onPathChange(_el.val());
+              showHdfsAutocomplete();
+            }
+            else {
+              _this.options.onEnter(_el);
+            }
+          });
+          $("#jHueHdfsAutocomplete").show();
+          setHueBreadcrumbCaretAtEnd(_this.element);
+          if ("undefined" != typeof callback) {
+            callback();
+          }
+        }, 100);  // timeout for IE8
+      }
+    });
+  }
+
+  $(document).on("mouseenter", ".hdfsAutocompleteItem", function () {
+    _pauseBlur = true;
+  });
+
+  $(document).on("mouseout", ".hdfsAutocompleteItem", function () {
+    _pauseBlur = false;
+  })
+
+  function guessHdfsPath(lastChars) {
+    var possibleMatches = [];
+    for (var i = 0; i < _currentFiles.length; i++) {
+      if (($(_currentFiles[i]).text().trim().indexOf(lastChars) == 0 || lastChars == "") && $(_currentFiles[i]).text().trim() != "..") {
+        possibleMatches.push(_currentFiles[i]);
+      }
+    }
+    if (possibleMatches.length == 1) {
+      _el.val(_el.val() + $(possibleMatches[0]).text().trim().substr(lastChars.length));
+      if ($(possibleMatches[0]).html().indexOf("folder") > -1) {
+        _el.val(_el.val() + "/");
+        showHdfsAutocomplete();
+      }
+    }
+    else if (possibleMatches.length > 1) {
+      // finds the longest common prefix
+      var possibleMatchesPlain = [];
+      for (var z = 0; z < possibleMatches.length; z++) {
+        possibleMatchesPlain.push($(possibleMatches[z]).text().trim());
+      }
+      var arr = possibleMatchesPlain.slice(0).sort(),
+          word1 = arr[0], word2 = arr[arr.length - 1],
+          j = 0;
+      while (word1.charAt(j) == word2.charAt(j))++j;
+      var match = word1.substring(0, j);
+      _el.val(_el.val() + match.substr(lastChars.length));
+    }
+  }
+};
+
+Plugin.prototype.setOptions = function (options) {
+  this.options = $.extend({}, defaults, options);
+};
+
+
+$.fn[pluginName] = function (options) {
+  return this.each(function () {
+    if (!$.data(this, 'plugin_' + pluginName)) {
+      $.data(this, 'plugin_' + pluginName, new Plugin(this, options));
+    }
+    else {
+      $.data(this, 'plugin_' + pluginName).setOptions(options);
+    }
+  });
+}
+
+$[pluginName] = function (options) {
+  if (typeof console != "undefined") {
+    console.warn("$(elem).jHueHdfsAutocomplete() is a preferred call method.");
+  }
+  $(options.element).jHueHdfsAutocomplete(options);
+};

+ 121 - 0
desktop/core/src/desktop/js/ext/jquery/hue.jquery.horizontalscrollbar.js

@@ -0,0 +1,121 @@
+// 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.
+/*
+ * jHue horizontal scrollbar for dataTables_wrapper
+ *
+ */
+
+var pluginName = "jHueHorizontalScrollbar",
+  defaults = {};
+
+function Plugin(element, options) {
+  this.element = element;
+  this.options = $.extend({}, defaults, options);
+  this._defaults = defaults;
+  this._name = pluginName;
+  this.init();
+}
+
+function initWhenReady(el) {
+  if ($(el).parents('.dataTables_wrapper').length > 0) {
+    var colWidth = $(el).find('thead tr th').outerWidth();
+    if ($(el).parents('.dataTables_wrapper').find('.hue-scrollbar-x-rail').length == 0 && $(el).parents('.dataTables_wrapper').width() < $(el).parents('.dataTables_wrapper')[0].scrollWidth) {
+      $('.hue-scrollbar-x-rail').remove();
+      var scrollbarRail = $('<div>');
+      var scrollbar = $('<div>').addClass('hue-scrollbar-x');
+      scrollbar.width(Math.max(20, $(el).parents('.dataTables_wrapper').width() * ($(el).parents('.dataTables_wrapper').width() / $(el).parents('.dataTables_wrapper')[0].scrollWidth)));
+      scrollbar.appendTo(scrollbarRail);
+      try {
+        scrollbar.draggable('destroy');
+      }
+      catch (e) {}
+      var throttleScrollTimeout = -1;
+      scrollbar.draggable({
+        axis: 'x',
+        containment: 'parent',
+        drag: function (e, ui) {
+          $(el).parents('.dataTables_wrapper').scrollLeft(($(el).parents('.dataTables_wrapper')[0].scrollWidth - $(el).parents('.dataTables_wrapper').width()) * (ui.position.left / (scrollbarRail.width() - $(this).width())))
+          throttleScrollTimeout = window.setTimeout(function () {
+            $(el).parents('.dataTables_wrapper').trigger('scroll');
+          }, 50);
+        }
+      });
+      $(el).parents('.dataTables_wrapper').bind('mousewheel', function (e) {
+        var _deltaX = e.deltaX*e.deltaFactor,
+            _deltaY = e.deltaY;
+
+        if (Math.abs(_deltaX) >= Math.abs(_deltaY)) {
+          var self = this;
+          self.scrollLeft += _deltaX;
+          e.preventDefault();
+          e.stopPropagation();
+          e.stopImmediatePropagation();
+          if (self.scrollLeft > 0){
+            scrollbar.css("left", ((scrollbarRail[0].getBoundingClientRect().width - scrollbar[0].getBoundingClientRect().width) * (self.scrollLeft / (self.scrollWidth - self.getBoundingClientRect().width))) + "px");
+            window.clearTimeout(throttleScrollTimeout);
+            throttleScrollTimeout = window.setTimeout(function () {
+              $(el).parents('.dataTables_wrapper').trigger('scroll');
+            }, 50);
+          }
+        }
+      });
+      scrollbarRail.addClass('hue-scrollbar-x-rail').appendTo($(el).parents(".dataTables_wrapper"));
+      scrollbarRail.width($(el).parents(".dataTables_wrapper").width() - colWidth);
+      scrollbarRail.css("marginLeft", (colWidth) + "px");
+      if (scrollbarRail.position().top > $(window).height() - 10) {
+        scrollbarRail.css('bottom', '0');
+      }
+      $(el).parents('.dataTables_wrapper').bind('scroll_update', function () {
+        scrollbar.css("left", ((scrollbarRail.width() - scrollbar.width()) * ($(el).parents('.dataTables_wrapper').scrollLeft() / ($(el).parents('.dataTables_wrapper')[0].scrollWidth - $(el).parents('.dataTables_wrapper').width()))) + "px");
+      });
+    } else {
+      if ($(el).parents('.dataTables_wrapper').width() === $(el).parents('.dataTables_wrapper')[0].scrollWidth) {
+        $('.hue-scrollbar-x-rail').hide();
+      }
+      else {
+        $('.hue-scrollbar-x-rail').show();
+      }
+      $(el).parents('.dataTables_wrapper').find('.hue-scrollbar-x-rail').width($(el).parents(".dataTables_wrapper").width() - colWidth);
+      var scrollbar = $(el).parents('.dataTables_wrapper').find('.hue-scrollbar-x');
+      scrollbar.width(Math.max(20, $(el).parents('.dataTables_wrapper').width() * ($(el).parents('.dataTables_wrapper').width() / $(el).parents('.dataTables_wrapper')[0].scrollWidth)));
+
+      var scrollbarRail = $(el).parents('.dataTables_wrapper').find('.hue-scrollbar-x-rail');
+      scrollbarRail.width($(el).parents(".dataTables_wrapper").width() - colWidth);
+      scrollbarRail.css("marginLeft", (colWidth) + "px");
+      scrollbar.css("left", ((scrollbarRail.width() - scrollbar.width()) * ($(el).parents('.dataTables_wrapper').scrollLeft() / ($(el).parents('.dataTables_wrapper')[0].scrollWidth - $(el).parents('.dataTables_wrapper').width()))) + "px");
+    }
+  }
+}
+
+Plugin.prototype.init = function () {
+  var el = this.element;
+
+  var checkWidth = function () {
+    if ($(el).parents('.dataTables_wrapper').width() > 0) {
+      initWhenReady(el);
+    } else {
+      window.setTimeout(checkWidth, 100);
+    }
+  }
+
+  checkWidth();
+};
+
+$.fn[pluginName] = function (options) {
+  return this.each(function () {
+    $.data(this, 'plugin_' + pluginName, new Plugin(this, options));
+  });
+}

+ 42 - 0
desktop/core/src/desktop/js/ext/jquery/hue.jquery.lib.js

@@ -0,0 +1,42 @@
+// 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 'jquery'
+import './hue.jquery.migration'
+import 'jquery.cookie'
+import './jquery.dataTables.1.8.2.min'
+import './hue.jquery.datatables.sorting'
+import './hue.jquery.delayedinput'
+import './hue.jquery.filechooser'
+import 'jquery-form'
+import './hue.jquery.hdfs.autocomplete'
+import './hue.jquery.horizontalscrollbar'
+import './hue.jquery.notify'
+import './hue.jquery.rowselector'
+import './hue.jquery.selector'
+import './jquery.total-storage.1.1.3.min'
+import './hue.jquery.titleupdater'
+import 'jquery-ui/ui/widgets/autocomplete'
+import 'jquery-ui/ui/widgets/mouse'
+import 'jquery-ui/ui/widgets/draggable'
+import 'jquery-ui/ui/widgets/droppable'
+import 'jquery-ui/ui/widgets/resizable'
+import 'jquery-ui/ui/widgets/sortable'
+import 'selectize'
+// chunks
+
+// window.$ = $;
+// window.jQuery = $;

+ 114 - 0
desktop/core/src/desktop/js/ext/jquery/hue.jquery.migration.js

@@ -0,0 +1,114 @@
+// 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.
+/*
+ * Repo for missing jQuery 2 functions, this ease the transition without updating every other plugin in Hue
+ *
+ */
+
+import jQuery from 'jquery';
+
+jQuery.uaMatch = function (ua) {
+  ua = ua.toLowerCase();
+
+  var match = /(chrome)[ \/]([\w.]+)/.exec(ua) ||
+    /(webkit)[ \/]([\w.]+)/.exec(ua) ||
+    /(opera)(?:.*version|)[ \/]([\w.]+)/.exec(ua) ||
+    /(msie) ([\w.]+)/.exec(ua) ||
+    ua.indexOf("compatible") < 0 && /(mozilla)(?:.*? rv:([\w.]+)|)/.exec(ua) ||
+    [];
+
+  return {
+    browser: match[ 1 ] || "",
+    version: match[ 2 ] || "0"
+  };
+};
+
+// Don't clobber any existing jQuery.browser in case it's different
+if (!jQuery.browser) {
+  let matched = jQuery.uaMatch(navigator.userAgent);
+  let browser = {};
+
+  if (matched.browser) {
+    browser[ matched.browser ] = true;
+    browser.version = matched.version;
+  }
+
+  // Chrome is Webkit, but Webkit is also Safari.
+  if (browser.chrome) {
+    browser.webkit = true;
+  } else if (browser.webkit) {
+    browser.safari = true;
+  }
+
+  jQuery.browser = browser;
+}
+
+// Since jQuery.clean is used internally on older versions, we only shim if it's missing
+if (!jQuery.clean) {
+  let rscriptType = /\/(java|ecma)script/i;
+
+  jQuery.clean = function (elems, context, fragment, scripts) {
+    // Set context per 1.8 logic
+    context = context || document;
+    context = !context.nodeType && context[0] || context;
+    context = context.ownerDocument || context;
+
+    var i, elem, handleScript, jsTags,
+      ret = [];
+
+    jQuery.merge(ret, jQuery.buildFragment(elems, context).childNodes);
+
+    // Complex logic lifted directly from jQuery 1.8
+    if (fragment) {
+      // Special handling of each script element
+      handleScript = function (elem) {
+        // Check if we consider it executable
+        if (!elem.type || rscriptType.test(elem.type)) {
+          // Detach the script and store it in the scripts array (if provided) or the fragment
+          // Return truthy to indicate that it has been handled
+          return scripts ?
+            scripts.push(elem.parentNode ? elem.parentNode.removeChild(elem) : elem) :
+            fragment.appendChild(elem);
+        }
+      };
+
+      for (i = 0; (elem = ret[i]) != null; i++) {
+        // Check if we're done after handling an executable script
+        if (!( jQuery.nodeName(elem, "script") && handleScript(elem) )) {
+          // Append to fragment and handle embedded scripts
+          fragment.appendChild(elem);
+          if (typeof elem.getElementsByTagName !== "undefined") {
+            // handleScript alters the DOM, so use jQuery.merge to ensure snapshot iteration
+            jsTags = jQuery.grep(jQuery.merge([], elem.getElementsByTagName("script")), handleScript);
+
+            // Splice the scripts into ret after their former ancestor and advance our index beyond them
+            ret.splice.apply(ret, [i + 1, 0].concat(jsTags));
+            i += jsTags.length;
+          }
+        }
+      }
+    }
+
+    return ret;
+  };
+}
+
+
+let oldSelf = jQuery.fn.andSelf || jQuery.fn.addBack;
+
+jQuery.fn.andSelf = function () {
+  return oldSelf.apply(this, arguments);
+};

+ 136 - 0
desktop/core/src/desktop/js/ext/jquery/hue.jquery.notify.js

@@ -0,0 +1,136 @@
+// 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.
+/*
+ * jHue notify plugin
+ *
+ */
+import $ from 'jquery';
+
+var pluginName = "jHueNotify",
+  TYPES = {
+    INFO: "INFO",
+    ERROR: "ERROR",
+    GENERAL: "GENERAL"
+  },
+  defaults = {
+    level: TYPES.GENERAL,
+    message: "",
+    sticky: false,
+    css: null
+  };
+
+function Plugin(options) {
+  this.options = $.extend({}, defaults, options);
+  this._defaults = defaults;
+  this._name = pluginName;
+  this.show();
+}
+
+Plugin.prototype.setOptions = function (options) {
+  this.options = $.extend({}, defaults, options);
+};
+
+Plugin.prototype.show = function () {
+  var _this = this;
+  var MARGIN = 4;
+
+  _this.options.message = _this.options.message.replace(/(<([^>]+)>)/ig, ''); // escape HTML messages
+
+  if (_this.options.message !== '' && $(".jHueNotify .message").last().text() !== _this.options.message) {
+
+    var el = $("#jHueNotify").clone();
+    el.removeAttr("id");
+
+    // stops all the current animations and resets the style
+    el.stop(true);
+    el.attr("class", "alert jHueNotify");
+    el.find(".close").hide();
+
+    if ($(".jHueNotify").last().position() != null) {
+      el.css("top", $(".jHueNotify").last().position().top + $(".jHueNotify").last().outerHeight() + MARGIN);
+    }
+
+    var scrollColor = '#f0c36d';
+
+    if (_this.options.level == TYPES.ERROR) {
+      el.addClass("alert-error");
+      scrollColor = '#b94a48';
+    }
+    else if (_this.options.level == TYPES.INFO) {
+      el.addClass("alert-info");
+      scrollColor = '#0B7FAD';
+    }
+    el.find(".message").html("<strong>" + _this.options.message + "</strong>");
+
+    if (_this.options.css != null) {
+      el.attr("style", _this.options.css);
+    }
+
+    el.on('dblclick', function () {
+      el.toggleClass('expanded');
+    });
+
+    if (_this.options.sticky) {
+      el.find(".close").click(function () {
+        el.fadeOut();
+        el.nextAll(".jHueNotify").animate({
+          top: '-=' + (el.outerHeight() + MARGIN)
+        }, 200);
+        el.remove();
+      }).show();
+      el.show();
+    }
+    else {
+      var t = window.setTimeout(function () {
+        el.fadeOut();
+        el.nextAll(".jHueNotify").animate({
+          top: '-=' + (el.outerHeight() + MARGIN)
+        }, 200);
+        el.remove();
+
+      }, 3000);
+      el.click(function () {
+        window.clearTimeout(t);
+        $(this).stop(true);
+        $(this).fadeOut();
+        $(this).nextAll(".jHueNotify").animate({
+          top: '-=' + ($(this).outerHeight() + MARGIN)
+        }, 200);
+      });
+      el.show();
+    }
+    el.appendTo(HUE_CONTAINER);
+  }
+};
+
+$[pluginName] = function () {
+};
+
+$[pluginName].info = function (message) {
+  new Plugin({level: TYPES.INFO, message: message});
+};
+
+$[pluginName].warn = function (message) {
+  new Plugin({level: TYPES.GENERAL, message: message, sticky: true});
+};
+
+$[pluginName].error = function (message) {
+  new Plugin({level: TYPES.ERROR, message: message, sticky: true});
+};
+
+$[pluginName].notify = function (options) {
+  new Plugin(options);
+};

+ 70 - 0
desktop/core/src/desktop/js/ext/jquery/hue.jquery.rowselector.js

@@ -0,0 +1,70 @@
+// 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.
+/*
+ * jHue row selector plugin
+ *
+ */
+
+import huePubSub from '../../utils/huePubSub'
+
+var pluginName = "jHueRowSelector",
+  defaults = {};
+
+function Plugin(element, options) {
+  this.element = element;
+  this.options = $.extend({}, defaults, options);
+  this._defaults = defaults;
+  this._name = pluginName;
+  this.init();
+}
+
+Plugin.prototype.setOptions = function (options) {
+  this.options = $.extend({}, defaults, options);
+};
+
+Plugin.prototype.init = function () {
+  var _this = this;
+  $(_this.element).closest("tr").click(function (e) {
+    if ($(e.target).data("row-selector-exclude") || $(e.target).closest("td").hasClass("row-selector-exclude")) {
+      return;
+    }
+    if (!$(e.target).is("a")) {
+      var href = $.trim($(_this.element).attr("href"));
+      if (href != "" && href != "#" && href.indexOf("void(0)") == -1) {
+        if (window.IS_HUE_4) {
+          huePubSub.publish('open.link', $(_this.element).attr("href"));
+        }
+        else {
+          location.href = $(_this.element).attr("href");
+        }
+      }
+      else {
+        $(_this.element).click();
+      }
+    }
+  }).css("cursor", "pointer");
+};
+
+$.fn[pluginName] = function (options) {
+  return this.each(function () {
+    if (!$.data(this, 'plugin_' + pluginName)) {
+      $.data(this, 'plugin_' + pluginName, new Plugin(this, options));
+    }
+    else {
+      $.data(this, 'plugin_' + pluginName).setOptions(options);
+    }
+  });
+}

+ 174 - 0
desktop/core/src/desktop/js/ext/jquery/hue.jquery.selector.js

@@ -0,0 +1,174 @@
+// 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.
+/*
+ * jHue selector plugin
+ * it tranforms a select multiple into a searchable/selectable alphabetical list
+ */
+
+var pluginName = "jHueSelector",
+    defaults = {
+      selectAllLabel: "Select all",
+      showSelectAll: true,
+      searchPlaceholder: "Search",
+      noChoicesFound: "No choices found for this element",
+      width: 300,
+      height: 200,
+      onChange: function () {
+      }
+    };
+
+function Plugin(element, options) {
+  this.element = element;
+  this.options = $.extend({}, defaults, options);
+  this._defaults = defaults;
+  this._name = pluginName;
+  this.init();
+}
+
+Plugin.prototype.setOptions = function (options) {
+  this.options = $.extend({}, defaults, options);
+};
+
+Plugin.prototype.init = function () {
+  var _this = this;
+  var addressBook = [];
+  var selectorContainer = $("<div>");
+  if (this.options.width != 300) {
+    selectorContainer.width(this.options.width);
+  }
+  $(_this.element).hide();
+  $(_this.element).find("option").each(function (cnt, opt) {
+    var initial = $(opt).text().substr(0, 1).toLowerCase();
+    if (addressBook[initial] == null) {
+      addressBook[initial] = [];
+    }
+    addressBook[initial].push($(opt));
+  });
+  var sortedKeys = [];
+  for (var key in addressBook) {
+    if (addressBook.hasOwnProperty(key)) {
+      sortedKeys.push(key);
+    }
+  }
+  sortedKeys.sort();
+
+  if (sortedKeys.length == 0) {
+    $(_this.element).after($("<div>").addClass("alert").css("margin-top", "-2px").css("float", "left").html(this.options.noChoicesFound));
+  }
+  else {
+    selectorContainer.addClass("jHueSelector");
+    var body = $("<div>").addClass("jHueSelectorBody");
+    body.appendTo(selectorContainer);
+
+    for (var i = 0; i < sortedKeys.length; i++) {
+      var key = sortedKeys[i];
+      var ul = $("<ul>");
+      var dividerLi = $("<li>").addClass("selectorDivider");
+      dividerLi.html("<strong>" + key.toUpperCase() + "</strong>");
+      dividerLi.appendTo(ul);
+      $.each(addressBook[key], function (cnt, opt) {
+        var li = $("<li>");
+        var lbl = $("<label>").text(opt.text());
+        var chk = $("<input>").attr("type", "checkbox").addClass("selector").change(function () {
+          if ($(this).is(":checked")) {
+            $(this).data("opt").attr("selected", "selected");
+          }
+          else {
+            $(this).data("opt").removeAttr("selected");
+          }
+          _this.options.onChange();
+        }).data("opt", opt).prependTo(lbl);
+        if (opt.is(":selected")) {
+          chk.attr("checked", "checked");
+        }
+        lbl.appendTo(li);
+        li.appendTo(ul);
+      });
+      ul.appendTo(body);
+    }
+
+    var header = $("<div>").addClass("jHueSelectorHeader");
+    header.prependTo(selectorContainer);
+
+    var selectAll = $("<label>").html("&nbsp;");
+
+    if (this.options.showSelectAll) {
+      selectAll.text(this.options.selectAllLabel);
+      $("<input>").attr("type", "checkbox").change(function () {
+        var isChecked = $(this).is(":checked");
+        selectorContainer.find("input.selector:visible").each(function () {
+          if (isChecked) {
+            $(this).prop("checked", true);
+            $(this).data("opt").attr("selected", "selected");
+          }
+          else {
+            $(this).prop("checked", false);
+            $(this).data("opt").removeAttr("selected");
+          }
+        });
+        if (searchBox.val() != "") {
+          $(this).prop("checked", false);
+        }
+        _this.options.onChange();
+      }).prependTo(selectAll);
+    }
+
+    selectAll.appendTo(header);
+
+    var searchBox = $("<input>").attr("type", "text").attr("placeholder", this.options.searchPlaceholder).keyup(function () {
+      body.find("ul").attr("show", true).show();
+      var q = $.trim($(this).val());
+      if (q != "") {
+        body.find("li.selectorDivider").hide();
+        body.find("label").each(function () {
+          if ($(this).text().toLowerCase().indexOf(q.toLowerCase()) > -1) {
+            $(this).parent().show();
+          }
+          else {
+            $(this).parent().hide();
+          }
+        });
+        body.find("ul").attr("show", false);
+        body.find("ul > *:visible").parent().attr("show", true).find("li.selectorDivider").show();
+      }
+      else {
+        body.find("li.selectorDivider").show();
+        body.find("label").parent().show();
+      }
+      body.find("ul[show=false]").hide();
+      body.find("ul[show=true]").show();
+    });
+    if (this.options.width != 300) {
+      searchBox.css("margin-left", this.options.width - 120 + "px");
+    }
+    searchBox.prependTo(header);
+
+    body.height(this.options.height - header.outerHeight());
+
+    $(_this.element).after(selectorContainer);
+  }
+};
+
+$.fn[pluginName] = function (options) {
+  return this.each(function () {
+    if (!$.data(this, 'plugin_' + pluginName)) {
+      $.data(this, 'plugin_' + pluginName, new Plugin(this, options));
+    }
+    else {
+      $.data(this, 'plugin_' + pluginName).setOptions(options);
+    }
+  });
+}

+ 61 - 0
desktop/core/src/desktop/js/ext/jquery/hue.jquery.titleupdater.js

@@ -0,0 +1,61 @@
+// 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.
+/*
+ * jHue title updater plugin
+ *
+ */
+
+var pluginName = "jHueTitleUpdater",
+  defaults = {
+    message: "",
+    reset: false
+  };
+
+function Plugin(options) {
+  this.options = $.extend({}, defaults, options);
+  this._defaults = defaults;
+  this._name = pluginName;
+  this.updateStatusBar();
+}
+
+Plugin.prototype.setOptions = function (options) {
+  this.options = $.extend({}, defaults, options);
+};
+
+Plugin.prototype.updateStatusBar = function () {
+  var _this = this;
+  if (_this.options.reset && $(document).data("jHueTitleUpdaterOriginal") != null) {
+    document.title = $(document).data("jHueTitleUpdaterOriginal");
+    $(document).data("jHueTitleUpdaterOriginal", null);
+  }
+  else if (_this.options.message != "") {
+    if ($(document).data("jHueTitleUpdaterOriginal") == null) {
+      $(document).data("jHueTitleUpdaterOriginal", document.title);
+    }
+    document.title = _this.options.message + " - " + $(document).data("jHueTitleUpdaterOriginal");
+  }
+};
+
+$[pluginName] = function () {
+};
+
+$[pluginName].reset = function () {
+  new Plugin({ reset: true});
+};
+
+$[pluginName].set = function (message) {
+  new Plugin({ message: message});
+};

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

@@ -0,0 +1,151 @@
+/*
+ * 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);

+ 26 - 0
desktop/core/src/desktop/js/ext/jquery/jquery.total-storage.1.1.3.min.js

@@ -0,0 +1,26 @@
+/**
+ * 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)

+ 221 - 0
desktop/core/src/desktop/js/ext/ko.selectize.custom.js

@@ -0,0 +1,221 @@
+// 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
+
+import ko from 'knockout';
+
+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]);
+    }
+  }
+}

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

@@ -14,11 +14,11 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-var locale = 'en-US';
-
-import $ from 'jquery';
+import './ext/jquery/hue.jquery.lib';
+import './ext/bootstrap.2.3.2.min';
 import _ from 'lodash';
 import filesize from 'filesize';
+import qq from './ext/fileuploader.custom';
 import ko from 'knockout';
 import komapping from 'knockout.mapping';
 import page from 'page';
@@ -28,14 +28,15 @@ import hueDebug from 'utils/hueDebug';
 import huePubSub from 'utils/huePubSub';
 import hueDrop from 'utils/hueDrop';
 import localforage from 'localforage';
-import 'knockout-switch-case';
 import 'ext/ko.editable.custom';
+import 'ext/ko.selectize.custom';
+import 'knockout-switch-case';
+import 'knockout-sortable';
+import 'knockout.validation';
 
 // TODO: Migrate away
-window.$ = $;
 window._ = _;
 window.filesize = filesize;
-window.jQuery = $;
 window.ko = ko;
 window.ko.mapping = komapping;
 window.page = page;
@@ -44,4 +45,5 @@ window.hueAnalytics = hueAnalytics;
 window.hueDebug = hueDebug;
 window.huePubSub = huePubSub;
 window.hueDrop = hueDrop;
-window.localforage = localforage;
+window.localforage = localforage;
+window.qq = qq;

+ 0 - 55
desktop/core/src/desktop/static/desktop/ext/css/basictable.css

@@ -1,55 +0,0 @@
-/*
- * jQuery Basic Table
- * Author: Jerry Low
- */
-
-table.bt thead,
-table.bt tbody th {
-  display: none;
-}
-
-table.bt tfoot th,
-table.bt tfoot td,
-table.bt tbody td {
-  border: none;
-  display: block;
-  display: -webkit-box;
-  display: -webkit-flex;
-  display: -ms-flexbox;
-  display: flex;
-  vertical-align: top;
-
-  /* IE 9 */
-  float: left\9;
-  width: 100%\9;
-}
-
-table.bt tfoot th::before,
-table.bt tfoot td::before,
-table.bt tbody td::before {
-  content: attr(data-th) ": ";
-  display: inline-block;
-  -webkit-flex-shrink: 0;
-  -ms-flex-shrink: 0;
-  flex-shrink: 0;
-  font-weight: bold;
-  width: 6.5em;
-}
-
-table.bt tfoot th.bt-hide,
-table.bt tfoot td.bt-hide,
-table.bt tbody td.bt-hide {
-  display: none;
-}
-
-table.bt tfoot th .bt-content,
-table.bt tfoot td .bt-content,
-table.bt tbody td .bt-content {
-  vertical-align: top;
-}
-
-.bt-wrapper.active {
-  max-height: 310px;
-  overflow: auto;
-  -webkit-overflow-scrolling: touch;
-}

A diferenza do arquivo foi suprimida porque é demasiado grande
+ 0 - 3
desktop/core/src/desktop/static/desktop/ext/js/jquery/plugins/jquery.basictable.min.js


A diferenza do arquivo foi suprimida porque é demasiado grande
+ 0 - 22
desktop/core/src/desktop/static/desktop/js/hue-bundle-10281a5aac52146933c4.js


A diferenza do arquivo foi suprimida porque é demasiado grande
+ 0 - 0
desktop/core/src/desktop/static/desktop/js/hue-bundle-10281a5aac52146933c4.js.map


A diferenza do arquivo foi suprimida porque é demasiado grande
+ 9627 - 0
desktop/core/src/desktop/static/desktop/js/hue-bundle-6bd3f5f21e9d494b3f9e.js


A diferenza do arquivo foi suprimida porque é demasiado grande
+ 0 - 0
desktop/core/src/desktop/static/desktop/js/hue-bundle-6bd3f5f21e9d494b3f9e.js.map


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

@@ -454,32 +454,14 @@ ${ commonshare() | n,unicode }
 
 ${ render_bundle('hue') | n,unicode }
 
-<script src="${ static('desktop/js/jquery.migration.js') }"></script>
 <script src="${ static('desktop/js/polyfills.js') }"></script>
-<script src="${ static('desktop/ext/js/bootstrap.min.js') }"></script>
 <script src="${ static('desktop/ext/js/tether.js') }"></script>
 <script src="${ static('desktop/ext/js/shepherd.min.js') }"></script>
-<script src="${ static('desktop/ext/js/fileuploader.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/jquery/plugins/jquery.total-storage.min.js') }"></script>
-<script src="${ static('desktop/ext/js/jquery/plugins/jquery.cookie.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.datatables.sorting.js') }"></script>
-<script src="${ static('desktop/ext/js/jquery/plugins/jquery.basictable.min.js') }"></script>
-<script src="${ static('desktop/ext/js/jquery/plugins/jquery-ui-1.10.4.custom.min.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>
@@ -487,16 +469,11 @@ ${ render_bundle('hue') | n,unicode }
 <script src="${ static('desktop/js/jquery.scrollup.js') }"></script>
 <script src="${ static('desktop/js/jquery.huedatatable.js') }"></script>
 
-<script src="${ static('desktop/ext/js/knockout-sortable.min.js') }"></script>
-<script src="${ static('desktop/ext/js/knockout.validation.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/ext/js/bootstrap-editable.min.js') }"></script>
 
-<script src="${ static('desktop/ext/js/selectize.min.js') }"></script>
-<script src="${ static('desktop/js/ko.selectize.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>

+ 124 - 5
package-lock.json

@@ -1233,6 +1233,11 @@
       "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=",
       "dev": true
     },
+    "ansicolors": {
+      "version": "0.2.1",
+      "resolved": "https://registry.npmjs.org/ansicolors/-/ansicolors-0.2.1.tgz",
+      "integrity": "sha1-vgiVmQl7dKXJxKhKDNvNtivYeu8="
+    },
     "anymatch": {
       "version": "2.0.0",
       "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz",
@@ -1936,11 +1941,6 @@
         "safe-json-parse": "~1.0.1"
       }
     },
-    "bootstrap-2.3.2": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/bootstrap-2.3.2/-/bootstrap-2.3.2-1.0.0.tgz",
-      "integrity": "sha1-4z6DRXTnuoDo6hiPVs4i7ChRz+w="
-    },
     "brace-expansion": {
       "version": "1.1.11",
       "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
@@ -2183,6 +2183,15 @@
       "integrity": "sha512-KD+pw9DderBLB8CGqBzYyFWpnrPVOEjsjargU/CvkNyg60od3cxSPTcTeMPhxJhDbkQPWvOz5BAyBzNl/St9vg==",
       "dev": true
     },
+    "cardinal": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/cardinal/-/cardinal-1.0.0.tgz",
+      "integrity": "sha1-UOIcGwqjdyn5N33vGWtanOyTLuk=",
+      "requires": {
+        "ansicolors": "~0.2.1",
+        "redeyed": "~1.0.0"
+      }
+    },
     "caseless": {
       "version": "0.12.0",
       "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz",
@@ -2527,6 +2536,11 @@
         "randomfill": "^1.0.3"
       }
     },
+    "csv-parse": {
+      "version": "2.5.0",
+      "resolved": "https://registry.npmjs.org/csv-parse/-/csv-parse-2.5.0.tgz",
+      "integrity": "sha512-4OcjOJQByI0YDU5COYw9HAqjo8/MOLLmT9EKyMCXUzgvh30vS1SlMK+Ho84IH5exN44cSnrYecw/7Zpu2m4lkA=="
+    },
     "currently-unhandled": {
       "version": "0.4.1",
       "resolved": "https://registry.npmjs.org/currently-unhandled/-/currently-unhandled-0.4.1.tgz",
@@ -4455,6 +4469,11 @@
       "integrity": "sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM=",
       "dev": true
     },
+    "humanize": {
+      "version": "0.0.9",
+      "resolved": "https://registry.npmjs.org/humanize/-/humanize-0.0.9.tgz",
+      "integrity": "sha1-GZT/rs3+nEQe0r2sdFK3u0yeQaQ="
+    },
     "iconv-lite": {
       "version": "0.4.24",
       "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
@@ -4828,6 +4847,24 @@
       "resolved": "https://registry.npmjs.org/jquery/-/jquery-3.3.1.tgz",
       "integrity": "sha512-Ubldcmxp5np52/ENotGxlLe6aGMvmF4R8S6tZjsP6Knsaxd/xp3Zrh50cG93lR6nPXyUFwzN3ZSOQI0wRJNdGg=="
     },
+    "jquery-form": {
+      "version": "4.2.2",
+      "resolved": "https://registry.npmjs.org/jquery-form/-/jquery-form-4.2.2.tgz",
+      "integrity": "sha512-HJTef7DRBSg8ge/RNUw8rUTTtB3l8ozO0OhD16AzDl+eIXp4skgCqRTd9fYPsOzL+pN6+1B9wvbTLGjgikz8Tg==",
+      "requires": {
+        "jquery": ">=1.7.2"
+      }
+    },
+    "jquery-ui": {
+      "version": "1.12.1",
+      "resolved": "https://registry.npmjs.org/jquery-ui/-/jquery-ui-1.12.1.tgz",
+      "integrity": "sha1-vLQEXI3QU5wTS8FIjN0+dop6nlE="
+    },
+    "jquery.cookie": {
+      "version": "1.4.1",
+      "resolved": "https://registry.npmjs.org/jquery.cookie/-/jquery.cookie-1.4.1.tgz",
+      "integrity": "sha1-1j3OIJ6raR/mMxbbCMqeR+D5OFs="
+    },
     "js-levenshtein": {
       "version": "1.1.6",
       "resolved": "https://registry.npmjs.org/js-levenshtein/-/js-levenshtein-1.1.6.tgz",
@@ -4913,6 +4950,11 @@
       "resolved": "https://registry.npmjs.org/knockout/-/knockout-3.4.2.tgz",
       "integrity": "sha1-6HlY3netHpNvfOZFuri118RW2Tc="
     },
+    "knockout-sortable": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/knockout-sortable/-/knockout-sortable-1.1.0.tgz",
+      "integrity": "sha1-/E+K22hhOVDTn+a7iwzK3q2UhdI="
+    },
     "knockout-switch-case": {
       "version": "2.1.0",
       "resolved": "https://registry.npmjs.org/knockout-switch-case/-/knockout-switch-case-2.1.0.tgz",
@@ -4926,6 +4968,11 @@
         "knockout": "^3.1.0"
       }
     },
+    "knockout.validation": {
+      "version": "2.0.3",
+      "resolved": "https://registry.npmjs.org/knockout.validation/-/knockout.validation-2.0.3.tgz",
+      "integrity": "sha1-iZ3lIyNk4ezV2UbggPaiYpMEYyk="
+    },
     "lcid": {
       "version": "2.0.0",
       "resolved": "https://registry.npmjs.org/lcid/-/lcid-2.0.0.tgz",
@@ -5310,6 +5357,11 @@
         "to-regex": "^3.0.2"
       }
     },
+    "microplugin": {
+      "version": "0.0.3",
+      "resolved": "https://registry.npmjs.org/microplugin/-/microplugin-0.0.3.tgz",
+      "integrity": "sha1-H8Lhu3yeGegr2Eu6kTe75xJQ2M0="
+    },
     "miller-rabin": {
       "version": "4.0.1",
       "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz",
@@ -5694,6 +5746,22 @@
         "wrappy": "1"
       }
     },
+    "optimist": {
+      "version": "0.6.1",
+      "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.6.1.tgz",
+      "integrity": "sha1-2j6nRob6IaGaERwybpDrFaAZZoY=",
+      "requires": {
+        "minimist": "~0.0.1",
+        "wordwrap": "~0.0.2"
+      },
+      "dependencies": {
+        "minimist": {
+          "version": "0.0.10",
+          "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.10.tgz",
+          "integrity": "sha1-3j+YVD2/lggr5IrRoMfNqDYwHc8="
+        }
+      }
+    },
     "os-browserify": {
       "version": "0.3.0",
       "resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.3.0.tgz",
@@ -6319,6 +6387,21 @@
         "strip-indent": "^1.0.1"
       }
     },
+    "redeyed": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/redeyed/-/redeyed-1.0.1.tgz",
+      "integrity": "sha1-6WwZO0DAgWsArshCaY5hGF5VSYo=",
+      "requires": {
+        "esprima": "~3.0.0"
+      },
+      "dependencies": {
+        "esprima": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/esprima/-/esprima-3.0.0.tgz",
+          "integrity": "sha1-U88kes2ncxPlUcOqLnM0LT+099k="
+        }
+      }
+    },
     "regenerate": {
       "version": "1.4.0",
       "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.0.tgz",
@@ -6746,6 +6829,15 @@
         "ajv-keywords": "^3.1.0"
       }
     },
+    "selectize": {
+      "version": "0.12.6",
+      "resolved": "https://registry.npmjs.org/selectize/-/selectize-0.12.6.tgz",
+      "integrity": "sha512-bWO5A7G+I8+QXyjLfQUgh31VI4WKYagUZQxAXlDyUmDDNrFxrASV0W9hxCOl0XJ/XQ1dZEu3G9HjXV4Wj0yb6w==",
+      "requires": {
+        "microplugin": "0.0.3",
+        "sifter": "^0.5.1"
+      }
+    },
     "semver": {
       "version": "5.6.0",
       "resolved": "https://registry.npmjs.org/semver/-/semver-5.6.0.tgz",
@@ -6818,6 +6910,28 @@
       "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=",
       "dev": true
     },
+    "sifter": {
+      "version": "0.5.3",
+      "resolved": "https://registry.npmjs.org/sifter/-/sifter-0.5.3.tgz",
+      "integrity": "sha1-XmUH/owRSyso2Qtr9OW2NuYR5Is=",
+      "requires": {
+        "async": "^2.6.0",
+        "cardinal": "^1.0.0",
+        "csv-parse": "^2.0.0",
+        "humanize": "^0.0.9",
+        "optimist": "^0.6.1"
+      },
+      "dependencies": {
+        "async": {
+          "version": "2.6.1",
+          "resolved": "https://registry.npmjs.org/async/-/async-2.6.1.tgz",
+          "integrity": "sha512-fNEiL2+AZt6AlAw/29Cr0UDe4sRAHCpEHh54WMz+Bb7QfNcFw4h3loofyJpLeQs4Yx7yuqu/2dLgM5hKOs6HlQ==",
+          "requires": {
+            "lodash": "^4.17.10"
+          }
+        }
+      }
+    },
     "signal-exit": {
       "version": "3.0.2",
       "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz",
@@ -7909,6 +8023,11 @@
       "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=",
       "dev": true
     },
+    "wordwrap": {
+      "version": "0.0.3",
+      "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz",
+      "integrity": "sha1-o9XabNXAvAAI03I0u68b7WMFkQc="
+    },
     "worker-farm": {
       "version": "1.6.0",
       "resolved": "https://registry.npmjs.org/worker-farm/-/worker-farm-1.6.0.tgz",

+ 8 - 4
package.json

@@ -9,7 +9,6 @@
   },
   "author": "Cloudera, Inc.",
   "contributors": [
-    "Andrew Yao <andyao@cloudera.com>",
     "Johan Ahlen <johan.ahlen@cloudera.com>"
   ],
   "license": "Apache",
@@ -18,17 +17,22 @@
     "node": ">=0.10.0"
   },
   "dependencies": {
-    "bootstrap-2.3.2": "1.0.0",
     "filesize": "4.0.0",
     "jquery": "3.3.1",
+    "jquery-ui": "1.12.1",
+    "jquery.cookie": "1.4.1",
+    "jquery-form": "4.2.2",
     "knockout": "3.4.2",
     "knockout.mapping": "2.4.3",
+    "knockout-sortable": "1.1.0",
     "knockout-switch-case": "2.1.0",
+    "knockout.validation": "2.0.3",
     "less": "3.9.0",
     "localforage": "1.7.3",
     "lodash": "4.17.11",
     "minimist": "^1.2.0",
-    "page": "1.8.6"
+    "page": "1.8.6",
+    "selectize": "0.12.6"
   },
   "devDependencies": {
     "@babel/core": "7.2.2",
@@ -53,7 +57,7 @@
     "devinstall": "npm cache clean && npm install && npm prune",
     "less": "./node_modules/.bin/grunt less",
     "watch": "./node_modules/.bin/grunt watch",
-    "webpack": "./node_modules/.bin/webpack"
+    "webpack": "webpack --config webpack.config.js"
   },
   "files": []
 }

+ 1 - 1
webpack-stats.json

@@ -1 +1 @@
-{"status":"done","chunks":{"hue":[{"name":"hue-bundle-10281a5aac52146933c4.js","path":"/Users/jahlen/dev/hue/desktop/core/src/desktop/static/desktop/js/hue-bundle-10281a5aac52146933c4.js"},{"name":"hue-bundle-10281a5aac52146933c4.js.map","path":"/Users/jahlen/dev/hue/desktop/core/src/desktop/static/desktop/js/hue-bundle-10281a5aac52146933c4.js.map"}]}}
+{"status":"done","chunks":{"hue":[{"name":"hue-bundle-6bd3f5f21e9d494b3f9e.js","path":"/Users/jahlen/dev/hue/desktop/core/src/desktop/static/desktop/js/hue-bundle-6bd3f5f21e9d494b3f9e.js"},{"name":"hue-bundle-6bd3f5f21e9d494b3f9e.js.map","path":"/Users/jahlen/dev/hue/desktop/core/src/desktop/static/desktop/js/hue-bundle-6bd3f5f21e9d494b3f9e.js.map"}]}}

+ 8 - 13
webpack.config.js

@@ -5,9 +5,9 @@ var WebpackShellPlugin = require('webpack-shell-plugin');
 module.exports = {
   devtool: 'source-map',
   mode: 'development',
-  optimization: {
-    minimize: true
-  },
+  // optimization: {
+  //   minimize: true
+  // },
   performance: {
     maxEntrypointSize: 400 * 1024, // 400kb
     maxAssetSize: 400 * 1024 // 400kb
@@ -19,7 +19,7 @@ module.exports = {
       'js'
     ],
     alias: {
-      'bootstrap': 'bootstrap/js'
+      'bootstrap': __dirname + '/node_modules/bootstrap-2.3.2/js'
     }
   },
   entry: {
@@ -40,10 +40,10 @@ module.exports = {
         exclude: /node_modules/,
         loader: 'babel-loader'
       },
-      // expose lodash and jquery for knockout templates to access
       { test: /lodash$/, loader: 'expose-loader?_' },
-      { test: /jquery/, loader: 'expose-loader?$!expose-loader?jQuery' },
-
+      { test: /jquery.js$/, loader: [
+        'expose-loader?$',
+          'expose-loader?jQuery'] },
       // needed for moment-timezone
       { include: /\.json$/, loaders: ['json-loader'] }
     ]
@@ -52,11 +52,6 @@ module.exports = {
   plugins: [
     new WebpackShellPlugin({ onBuildStart:[__dirname + '/tools/scripts/clean_js_bundles.sh ' +  __dirname ] }),
     new BundleTracker({ filename: './webpack-stats.json' }),
-    new webpack.BannerPlugin('\nLicensed to Cloudera, Inc. under one\nor more contributor license agreements.  See the NOTICE file\ndistributed with this work for additional information\nregarding copyright ownership.  Cloudera, Inc. licenses this file\nto you under the Apache License, Version 2.0 (the\n"License"); you may not use this file except in compliance\nwith the License.  You may obtain a copy of the License at\n\nhttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an "AS IS" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n'),
-    new webpack.ProvidePlugin({
-      $: 'jquery',
-      jQuery: 'jquery',
-      'window.jQuery': 'jquery'
-    })
+    new webpack.BannerPlugin('\nLicensed to Cloudera, Inc. under one\nor more contributor license agreements.  See the NOTICE file\ndistributed with this work for additional information\nregarding copyright ownership.  Cloudera, Inc. licenses this file\nto you under the Apache License, Version 2.0 (the\n"License"); you may not use this file except in compliance\nwith the License.  You may obtain a copy of the License at\n\nhttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an "AS IS" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n')
   ]
 };

Algúns arquivos non se mostraron porque demasiados arquivos cambiaron neste cambio