You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nifi.apache.org by sc...@apache.org on 2017/01/17 20:44:32 UTC

[05/11] nifi git commit: NIFI-3291: - Upgrading jQuery and it's plugins. - Packaging at build time using npm.

http://git-wip-us.apache.org/repos/asf/nifi/blob/6170f644/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/jquery/slickgrid/slick.core.js
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/jquery/slickgrid/slick.core.js b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/jquery/slickgrid/slick.core.js
deleted file mode 100755
index 2f097b1..0000000
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/jquery/slickgrid/slick.core.js
+++ /dev/null
@@ -1,467 +0,0 @@
-/***
- * Contains core SlickGrid classes.
- * @module Core
- * @namespace Slick
- */
-
-(function ($) {
-  // register namespace
-  $.extend(true, window, {
-    "Slick": {
-      "Event": Event,
-      "EventData": EventData,
-      "EventHandler": EventHandler,
-      "Range": Range,
-      "NonDataRow": NonDataItem,
-      "Group": Group,
-      "GroupTotals": GroupTotals,
-      "EditorLock": EditorLock,
-
-      /***
-       * A global singleton editor lock.
-       * @class GlobalEditorLock
-       * @static
-       * @constructor
-       */
-      "GlobalEditorLock": new EditorLock()
-    }
-  });
-
-  /***
-   * An event object for passing data to event handlers and letting them control propagation.
-   * <p>This is pretty much identical to how W3C and jQuery implement events.</p>
-   * @class EventData
-   * @constructor
-   */
-  function EventData() {
-    var isPropagationStopped = false;
-    var isImmediatePropagationStopped = false;
-
-    /***
-     * Stops event from propagating up the DOM tree.
-     * @method stopPropagation
-     */
-    this.stopPropagation = function () {
-      isPropagationStopped = true;
-    };
-
-    /***
-     * Returns whether stopPropagation was called on this event object.
-     * @method isPropagationStopped
-     * @return {Boolean}
-     */
-    this.isPropagationStopped = function () {
-      return isPropagationStopped;
-    };
-
-    /***
-     * Prevents the rest of the handlers from being executed.
-     * @method stopImmediatePropagation
-     */
-    this.stopImmediatePropagation = function () {
-      isImmediatePropagationStopped = true;
-    };
-
-    /***
-     * Returns whether stopImmediatePropagation was called on this event object.\
-     * @method isImmediatePropagationStopped
-     * @return {Boolean}
-     */
-    this.isImmediatePropagationStopped = function () {
-      return isImmediatePropagationStopped;
-    }
-  }
-
-  /***
-   * A simple publisher-subscriber implementation.
-   * @class Event
-   * @constructor
-   */
-  function Event() {
-    var handlers = [];
-
-    /***
-     * Adds an event handler to be called when the event is fired.
-     * <p>Event handler will receive two arguments - an <code>EventData</code> and the <code>data</code>
-     * object the event was fired with.<p>
-     * @method subscribe
-     * @param fn {Function} Event handler.
-     */
-    this.subscribe = function (fn) {
-      handlers.push(fn);
-    };
-
-    /***
-     * Removes an event handler added with <code>subscribe(fn)</code>.
-     * @method unsubscribe
-     * @param fn {Function} Event handler to be removed.
-     */
-    this.unsubscribe = function (fn) {
-      for (var i = handlers.length - 1; i >= 0; i--) {
-        if (handlers[i] === fn) {
-          handlers.splice(i, 1);
-        }
-      }
-    };
-
-    /***
-     * Fires an event notifying all subscribers.
-     * @method notify
-     * @param args {Object} Additional data object to be passed to all handlers.
-     * @param e {EventData}
-     *      Optional.
-     *      An <code>EventData</code> object to be passed to all handlers.
-     *      For DOM events, an existing W3C/jQuery event object can be passed in.
-     * @param scope {Object}
-     *      Optional.
-     *      The scope ("this") within which the handler will be executed.
-     *      If not specified, the scope will be set to the <code>Event</code> instance.
-     */
-    this.notify = function (args, e, scope) {
-      e = e || new EventData();
-      scope = scope || this;
-
-      var returnValue;
-      for (var i = 0; i < handlers.length && !(e.isPropagationStopped() || e.isImmediatePropagationStopped()); i++) {
-        returnValue = handlers[i].call(scope, e, args);
-      }
-
-      return returnValue;
-    };
-  }
-
-  function EventHandler() {
-    var handlers = [];
-
-    this.subscribe = function (event, handler) {
-      handlers.push({
-        event: event,
-        handler: handler
-      });
-      event.subscribe(handler);
-
-      return this;  // allow chaining
-    };
-
-    this.unsubscribe = function (event, handler) {
-      var i = handlers.length;
-      while (i--) {
-        if (handlers[i].event === event &&
-            handlers[i].handler === handler) {
-          handlers.splice(i, 1);
-          event.unsubscribe(handler);
-          return;
-        }
-      }
-
-      return this;  // allow chaining
-    };
-
-    this.unsubscribeAll = function () {
-      var i = handlers.length;
-      while (i--) {
-        handlers[i].event.unsubscribe(handlers[i].handler);
-      }
-      handlers = [];
-
-      return this;  // allow chaining
-    }
-  }
-
-  /***
-   * A structure containing a range of cells.
-   * @class Range
-   * @constructor
-   * @param fromRow {Integer} Starting row.
-   * @param fromCell {Integer} Starting cell.
-   * @param toRow {Integer} Optional. Ending row. Defaults to <code>fromRow</code>.
-   * @param toCell {Integer} Optional. Ending cell. Defaults to <code>fromCell</code>.
-   */
-  function Range(fromRow, fromCell, toRow, toCell) {
-    if (toRow === undefined && toCell === undefined) {
-      toRow = fromRow;
-      toCell = fromCell;
-    }
-
-    /***
-     * @property fromRow
-     * @type {Integer}
-     */
-    this.fromRow = Math.min(fromRow, toRow);
-
-    /***
-     * @property fromCell
-     * @type {Integer}
-     */
-    this.fromCell = Math.min(fromCell, toCell);
-
-    /***
-     * @property toRow
-     * @type {Integer}
-     */
-    this.toRow = Math.max(fromRow, toRow);
-
-    /***
-     * @property toCell
-     * @type {Integer}
-     */
-    this.toCell = Math.max(fromCell, toCell);
-
-    /***
-     * Returns whether a range represents a single row.
-     * @method isSingleRow
-     * @return {Boolean}
-     */
-    this.isSingleRow = function () {
-      return this.fromRow == this.toRow;
-    };
-
-    /***
-     * Returns whether a range represents a single cell.
-     * @method isSingleCell
-     * @return {Boolean}
-     */
-    this.isSingleCell = function () {
-      return this.fromRow == this.toRow && this.fromCell == this.toCell;
-    };
-
-    /***
-     * Returns whether a range contains a given cell.
-     * @method contains
-     * @param row {Integer}
-     * @param cell {Integer}
-     * @return {Boolean}
-     */
-    this.contains = function (row, cell) {
-      return row >= this.fromRow && row <= this.toRow &&
-          cell >= this.fromCell && cell <= this.toCell;
-    };
-
-    /***
-     * Returns a readable representation of a range.
-     * @method toString
-     * @return {String}
-     */
-    this.toString = function () {
-      if (this.isSingleCell()) {
-        return "(" + this.fromRow + ":" + this.fromCell + ")";
-      }
-      else {
-        return "(" + this.fromRow + ":" + this.fromCell + " - " + this.toRow + ":" + this.toCell + ")";
-      }
-    }
-  }
-
-
-  /***
-   * A base class that all special / non-data rows (like Group and GroupTotals) derive from.
-   * @class NonDataItem
-   * @constructor
-   */
-  function NonDataItem() {
-    this.__nonDataRow = true;
-  }
-
-
-  /***
-   * Information about a group of rows.
-   * @class Group
-   * @extends Slick.NonDataItem
-   * @constructor
-   */
-  function Group() {
-    this.__group = true;
-
-    /**
-     * Grouping level, starting with 0.
-     * @property level
-     * @type {Number}
-     */
-    this.level = 0;
-
-    /***
-     * Number of rows in the group.
-     * @property count
-     * @type {Integer}
-     */
-    this.count = 0;
-
-    /***
-     * Grouping value.
-     * @property value
-     * @type {Object}
-     */
-    this.value = null;
-
-    /***
-     * Formatted display value of the group.
-     * @property title
-     * @type {String}
-     */
-    this.title = null;
-
-    /***
-     * Whether a group is collapsed.
-     * @property collapsed
-     * @type {Boolean}
-     */
-    this.collapsed = false;
-
-    /***
-     * GroupTotals, if any.
-     * @property totals
-     * @type {GroupTotals}
-     */
-    this.totals = null;
-
-    /**
-     * Rows that are part of the group.
-     * @property rows
-     * @type {Array}
-     */
-    this.rows = [];
-
-    /**
-     * Sub-groups that are part of the group.
-     * @property groups
-     * @type {Array}
-     */
-    this.groups = null;
-
-    /**
-     * A unique key used to identify the group.  This key can be used in calls to DataView
-     * collapseGroup() or expandGroup().
-     * @property groupingKey
-     * @type {Object}
-     */
-    this.groupingKey = null;
-  }
-
-  Group.prototype = new NonDataItem();
-
-  /***
-   * Compares two Group instances.
-   * @method equals
-   * @return {Boolean}
-   * @param group {Group} Group instance to compare to.
-   */
-  Group.prototype.equals = function (group) {
-    return this.value === group.value &&
-        this.count === group.count &&
-        this.collapsed === group.collapsed &&
-        this.title === group.title;
-  };
-
-  /***
-   * Information about group totals.
-   * An instance of GroupTotals will be created for each totals row and passed to the aggregators
-   * so that they can store arbitrary data in it.  That data can later be accessed by group totals
-   * formatters during the display.
-   * @class GroupTotals
-   * @extends Slick.NonDataItem
-   * @constructor
-   */
-  function GroupTotals() {
-    this.__groupTotals = true;
-
-    /***
-     * Parent Group.
-     * @param group
-     * @type {Group}
-     */
-    this.group = null;
-
-    /***
-     * Whether the totals have been fully initialized / calculated.
-     * Will be set to false for lazy-calculated group totals.
-     * @param initialized
-     * @type {Boolean}
-     */
-    this.initialized = false;
-  }
-
-  GroupTotals.prototype = new NonDataItem();
-
-  /***
-   * A locking helper to track the active edit controller and ensure that only a single controller
-   * can be active at a time.  This prevents a whole class of state and validation synchronization
-   * issues.  An edit controller (such as SlickGrid) can query if an active edit is in progress
-   * and attempt a commit or cancel before proceeding.
-   * @class EditorLock
-   * @constructor
-   */
-  function EditorLock() {
-    var activeEditController = null;
-
-    /***
-     * Returns true if a specified edit controller is active (has the edit lock).
-     * If the parameter is not specified, returns true if any edit controller is active.
-     * @method isActive
-     * @param editController {EditController}
-     * @return {Boolean}
-     */
-    this.isActive = function (editController) {
-      return (editController ? activeEditController === editController : activeEditController !== null);
-    };
-
-    /***
-     * Sets the specified edit controller as the active edit controller (acquire edit lock).
-     * If another edit controller is already active, and exception will be thrown.
-     * @method activate
-     * @param editController {EditController} edit controller acquiring the lock
-     */
-    this.activate = function (editController) {
-      if (editController === activeEditController) { // already activated?
-        return;
-      }
-      if (activeEditController !== null) {
-        throw "SlickGrid.EditorLock.activate: an editController is still active, can't activate another editController";
-      }
-      if (!editController.commitCurrentEdit) {
-        throw "SlickGrid.EditorLock.activate: editController must implement .commitCurrentEdit()";
-      }
-      if (!editController.cancelCurrentEdit) {
-        throw "SlickGrid.EditorLock.activate: editController must implement .cancelCurrentEdit()";
-      }
-      activeEditController = editController;
-    };
-
-    /***
-     * Unsets the specified edit controller as the active edit controller (release edit lock).
-     * If the specified edit controller is not the active one, an exception will be thrown.
-     * @method deactivate
-     * @param editController {EditController} edit controller releasing the lock
-     */
-    this.deactivate = function (editController) {
-      if (activeEditController !== editController) {
-        throw "SlickGrid.EditorLock.deactivate: specified editController is not the currently active one";
-      }
-      activeEditController = null;
-    };
-
-    /***
-     * Attempts to commit the current edit by calling "commitCurrentEdit" method on the active edit
-     * controller and returns whether the commit attempt was successful (commit may fail due to validation
-     * errors, etc.).  Edit controller's "commitCurrentEdit" must return true if the commit has succeeded
-     * and false otherwise.  If no edit controller is active, returns true.
-     * @method commitCurrentEdit
-     * @return {Boolean}
-     */
-    this.commitCurrentEdit = function () {
-      return (activeEditController ? activeEditController.commitCurrentEdit() : true);
-    };
-
-    /***
-     * Attempts to cancel the current edit by calling "cancelCurrentEdit" method on the active edit
-     * controller and returns whether the edit was successfully cancelled.  If no edit controller is
-     * active, returns true.
-     * @method cancelCurrentEdit
-     * @return {Boolean}
-     */
-    this.cancelCurrentEdit = function cancelCurrentEdit() {
-      return (activeEditController ? activeEditController.cancelCurrentEdit() : true);
-    };
-  }
-})(jQuery);
-
-

http://git-wip-us.apache.org/repos/asf/nifi/blob/6170f644/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/jquery/slickgrid/slick.dataview.js
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/jquery/slickgrid/slick.dataview.js b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/jquery/slickgrid/slick.dataview.js
deleted file mode 100755
index f1c1b5e..0000000
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/jquery/slickgrid/slick.dataview.js
+++ /dev/null
@@ -1,1126 +0,0 @@
-(function ($) {
-  $.extend(true, window, {
-    Slick: {
-      Data: {
-        DataView: DataView,
-        Aggregators: {
-          Avg: AvgAggregator,
-          Min: MinAggregator,
-          Max: MaxAggregator,
-          Sum: SumAggregator
-        }
-      }
-    }
-  });
-
-
-  /***
-   * A sample Model implementation.
-   * Provides a filtered view of the underlying data.
-   *
-   * Relies on the data item having an "id" property uniquely identifying it.
-   */
-  function DataView(options) {
-    var self = this;
-
-    var defaults = {
-      groupItemMetadataProvider: null,
-      inlineFilters: false
-    };
-
-
-    // private
-    var idProperty = "id";  // property holding a unique row id
-    var items = [];         // data by index
-    var rows = [];          // data by row
-    var idxById = {};       // indexes by id
-    var rowsById = null;    // rows by id; lazy-calculated
-    var filter = null;      // filter function
-    var updated = null;     // updated item ids
-    var suspend = false;    // suspends the recalculation
-    var sortAsc = true;
-    var fastSortField;
-    var sortComparer;
-    var refreshHints = {};
-    var prevRefreshHints = {};
-    var filterArgs;
-    var filteredItems = [];
-    var compiledFilter;
-    var compiledFilterWithCaching;
-    var filterCache = [];
-
-    // grouping
-    var groupingInfoDefaults = {
-      getter: null,
-      formatter: null,
-      comparer: function(a, b) { return a.value - b.value; },
-      predefinedValues: [],
-      aggregators: [],
-      aggregateEmpty: false,
-      aggregateCollapsed: false,
-      aggregateChildGroups: false,
-      collapsed: false,
-      displayTotalsRow: true,
-      lazyTotalsCalculation: false
-    };
-    var groupingInfos = [];
-    var groups = [];
-    var toggledGroupsByLevel = [];
-    var groupingDelimiter = ':|:';
-
-    var pagesize = 0;
-    var pagenum = 0;
-    var totalRows = 0;
-
-    // events
-    var onRowCountChanged = new Slick.Event();
-    var onRowsChanged = new Slick.Event();
-    var onPagingInfoChanged = new Slick.Event();
-
-    options = $.extend(true, {}, defaults, options);
-
-
-    function beginUpdate() {
-      suspend = true;
-    }
-
-    function endUpdate() {
-      suspend = false;
-      refresh();
-    }
-
-    function setRefreshHints(hints) {
-      refreshHints = hints;
-    }
-
-    function setFilterArgs(args) {
-      filterArgs = args;
-    }
-
-    function updateIdxById(startingIndex) {
-      startingIndex = startingIndex || 0;
-      var id;
-      for (var i = startingIndex, l = items.length; i < l; i++) {
-        id = items[i][idProperty];
-        if (id === undefined) {
-          throw "Each data element must implement a unique 'id' property";
-        }
-        idxById[id] = i;
-      }
-    }
-
-    function ensureIdUniqueness() {
-      var id;
-      for (var i = 0, l = items.length; i < l; i++) {
-        id = items[i][idProperty];
-        if (id === undefined || idxById[id] !== i) {
-          throw "Each data element must implement a unique 'id' property";
-        }
-      }
-    }
-
-    function getItems() {
-      return items;
-    }
-
-    function setItems(data, objectIdProperty) {
-      if (objectIdProperty !== undefined) {
-        idProperty = objectIdProperty;
-      }
-      items = filteredItems = data;
-      idxById = {};
-      updateIdxById();
-      ensureIdUniqueness();
-      refresh();
-    }
-
-    function setPagingOptions(args) {
-      if (args.pageSize != undefined) {
-        pagesize = args.pageSize;
-        pagenum = pagesize ? Math.min(pagenum, Math.max(0, Math.ceil(totalRows / pagesize) - 1)) : 0;
-      }
-
-      if (args.pageNum != undefined) {
-        pagenum = Math.min(args.pageNum, Math.max(0, Math.ceil(totalRows / pagesize) - 1));
-      }
-
-      onPagingInfoChanged.notify(getPagingInfo(), null, self);
-
-      refresh();
-    }
-
-    function getPagingInfo() {
-      var totalPages = pagesize ? Math.max(1, Math.ceil(totalRows / pagesize)) : 1;
-      return {pageSize: pagesize, pageNum: pagenum, totalRows: totalRows, totalPages: totalPages};
-    }
-
-    function sort(comparer, ascending) {
-      sortAsc = ascending;
-      sortComparer = comparer;
-      fastSortField = null;
-      if (ascending === false) {
-        items.reverse();
-      }
-      items.sort(comparer);
-      if (ascending === false) {
-        items.reverse();
-      }
-      idxById = {};
-      updateIdxById();
-      refresh();
-    }
-
-    /***
-     * Provides a workaround for the extremely slow sorting in IE.
-     * Does a [lexicographic] sort on a give column by temporarily overriding Object.prototype.toString
-     * to return the value of that field and then doing a native Array.sort().
-     */
-    function fastSort(field, ascending) {
-      sortAsc = ascending;
-      fastSortField = field;
-      sortComparer = null;
-      var oldToString = Object.prototype.toString;
-      Object.prototype.toString = (typeof field == "function") ? field : function () {
-        return this[field]
-      };
-      // an extra reversal for descending sort keeps the sort stable
-      // (assuming a stable native sort implementation, which isn't true in some cases)
-      if (ascending === false) {
-        items.reverse();
-      }
-      items.sort();
-      Object.prototype.toString = oldToString;
-      if (ascending === false) {
-        items.reverse();
-      }
-      idxById = {};
-      updateIdxById();
-      refresh();
-    }
-
-    function reSort() {
-      if (sortComparer) {
-        sort(sortComparer, sortAsc);
-      } else if (fastSortField) {
-        fastSort(fastSortField, sortAsc);
-      }
-    }
-
-    function setFilter(filterFn) {
-      filter = filterFn;
-      if (options.inlineFilters) {
-        compiledFilter = compileFilter();
-        compiledFilterWithCaching = compileFilterWithCaching();
-      }
-      refresh();
-    }
-
-    function getGrouping() {
-      return groupingInfos;
-    }
-
-    function setGrouping(groupingInfo) {
-      if (!options.groupItemMetadataProvider) {
-        options.groupItemMetadataProvider = new Slick.Data.GroupItemMetadataProvider();
-      }
-
-      groups = [];
-      toggledGroupsByLevel = [];
-      groupingInfo = groupingInfo || [];
-      groupingInfos = (groupingInfo instanceof Array) ? groupingInfo : [groupingInfo];
-
-      for (var i = 0; i < groupingInfos.length; i++) {
-        var gi = groupingInfos[i] = $.extend(true, {}, groupingInfoDefaults, groupingInfos[i]);
-        gi.getterIsAFn = typeof gi.getter === "function";
-
-        // pre-compile accumulator loops
-        gi.compiledAccumulators = [];
-        var idx = gi.aggregators.length;
-        while (idx--) {
-          gi.compiledAccumulators[idx] = compileAccumulatorLoop(gi.aggregators[idx]);
-        }
-
-        toggledGroupsByLevel[i] = {};
-      }
-
-      refresh();
-    }
-
-    /**
-     * @deprecated Please use {@link setGrouping}.
-     */
-    function groupBy(valueGetter, valueFormatter, sortComparer) {
-      if (valueGetter == null) {
-        setGrouping([]);
-        return;
-      }
-
-      setGrouping({
-        getter: valueGetter,
-        formatter: valueFormatter,
-        comparer: sortComparer
-      });
-    }
-
-    /**
-     * @deprecated Please use {@link setGrouping}.
-     */
-    function setAggregators(groupAggregators, includeCollapsed) {
-      if (!groupingInfos.length) {
-        throw new Error("At least one grouping must be specified before calling setAggregators().");
-      }
-
-      groupingInfos[0].aggregators = groupAggregators;
-      groupingInfos[0].aggregateCollapsed = includeCollapsed;
-
-      setGrouping(groupingInfos);
-    }
-
-    function getItemByIdx(i) {
-      return items[i];
-    }
-
-    function getIdxById(id) {
-      return idxById[id];
-    }
-
-    function ensureRowsByIdCache() {
-      if (!rowsById) {
-        rowsById = {};
-        for (var i = 0, l = rows.length; i < l; i++) {
-          rowsById[rows[i][idProperty]] = i;
-        }
-      }
-    }
-
-    function getRowById(id) {
-      ensureRowsByIdCache();
-      return rowsById[id];
-    }
-
-    function getItemById(id) {
-      return items[idxById[id]];
-    }
-
-    function mapIdsToRows(idArray) {
-      var rows = [];
-      ensureRowsByIdCache();
-      for (var i = 0, l = idArray.length; i < l; i++) {
-        var row = rowsById[idArray[i]];
-        if (row != null) {
-          rows[rows.length] = row;
-        }
-      }
-      return rows;
-    }
-
-    function mapRowsToIds(rowArray) {
-      var ids = [];
-      for (var i = 0, l = rowArray.length; i < l; i++) {
-        if (rowArray[i] < rows.length) {
-          ids[ids.length] = rows[rowArray[i]][idProperty];
-        }
-      }
-      return ids;
-    }
-
-    function updateItem(id, item) {
-      if (idxById[id] === undefined || id !== item[idProperty]) {
-        throw "Invalid or non-matching id";
-      }
-      items[idxById[id]] = item;
-      if (!updated) {
-        updated = {};
-      }
-      updated[id] = true;
-      refresh();
-    }
-
-    function insertItem(insertBefore, item) {
-      items.splice(insertBefore, 0, item);
-      updateIdxById(insertBefore);
-      refresh();
-    }
-
-    function addItem(item) {
-      items.push(item);
-      updateIdxById(items.length - 1);
-      refresh();
-    }
-
-    function deleteItem(id) {
-      var idx = idxById[id];
-      if (idx === undefined) {
-        throw "Invalid id";
-      }
-      delete idxById[id];
-      items.splice(idx, 1);
-      updateIdxById(idx);
-      refresh();
-    }
-
-    function getLength() {
-      return rows.length;
-    }
-
-    function getItem(i) {
-      var item = rows[i];
-
-      // if this is a group row, make sure totals are calculated and update the title
-      if (item && item.__group && item.totals && !item.totals.initialized) {
-        var gi = groupingInfos[item.level];
-        if (!gi.displayTotalsRow) {
-          calculateTotals(item.totals);
-          item.title = gi.formatter ? gi.formatter(item) : item.value;
-        }
-      }
-      // if this is a totals row, make sure it's calculated
-      else if (item && item.__groupTotals && !item.initialized) {
-        calculateTotals(item);
-      }
-
-      return item;
-    }
-
-    function getItemMetadata(i) {
-      var item = rows[i];
-      if (item === undefined) {
-        return null;
-      }
-
-      // overrides for grouping rows
-      if (item.__group) {
-        return options.groupItemMetadataProvider.getGroupRowMetadata(item);
-      }
-
-      // overrides for totals rows
-      if (item.__groupTotals) {
-        return options.groupItemMetadataProvider.getTotalsRowMetadata(item);
-      }
-
-      return null;
-    }
-
-    function expandCollapseAllGroups(level, collapse) {
-      if (level == null) {
-        for (var i = 0; i < groupingInfos.length; i++) {
-          toggledGroupsByLevel[i] = {};
-          groupingInfos[i].collapsed = collapse;
-        }
-      } else {
-        toggledGroupsByLevel[level] = {};
-        groupingInfos[level].collapsed = collapse;
-      }
-      refresh();
-    }
-
-    /**
-     * @param level {Number} Optional level to collapse.  If not specified, applies to all levels.
-     */
-    function collapseAllGroups(level) {
-      expandCollapseAllGroups(level, true);
-    }
-
-    /**
-     * @param level {Number} Optional level to expand.  If not specified, applies to all levels.
-     */
-    function expandAllGroups(level) {
-      expandCollapseAllGroups(level, false);
-    }
-
-    function expandCollapseGroup(level, groupingKey, collapse) {
-      toggledGroupsByLevel[level][groupingKey] = groupingInfos[level].collapsed ^ collapse;
-      refresh();
-    }
-
-    /**
-     * @param varArgs Either a Slick.Group's "groupingKey" property, or a
-     *     variable argument list of grouping values denoting a unique path to the row.  For
-     *     example, calling collapseGroup('high', '10%') will collapse the '10%' subgroup of
-     *     the 'high' group.
-     */
-    function collapseGroup(varArgs) {
-      var args = Array.prototype.slice.call(arguments);
-      var arg0 = args[0];
-      if (args.length == 1 && arg0.indexOf(groupingDelimiter) != -1) {
-        expandCollapseGroup(arg0.split(groupingDelimiter).length - 1, arg0, true);
-      } else {
-        expandCollapseGroup(args.length - 1, args.join(groupingDelimiter), true);
-      }
-    }
-
-    /**
-     * @param varArgs Either a Slick.Group's "groupingKey" property, or a
-     *     variable argument list of grouping values denoting a unique path to the row.  For
-     *     example, calling expandGroup('high', '10%') will expand the '10%' subgroup of
-     *     the 'high' group.
-     */
-    function expandGroup(varArgs) {
-      var args = Array.prototype.slice.call(arguments);
-      var arg0 = args[0];
-      if (args.length == 1 && arg0.indexOf(groupingDelimiter) != -1) {
-        expandCollapseGroup(arg0.split(groupingDelimiter).length - 1, arg0, false);
-      } else {
-        expandCollapseGroup(args.length - 1, args.join(groupingDelimiter), false);
-      }
-    }
-
-    function getGroups() {
-      return groups;
-    }
-
-    function extractGroups(rows, parentGroup) {
-      var group;
-      var val;
-      var groups = [];
-      var groupsByVal = {};
-      var r;
-      var level = parentGroup ? parentGroup.level + 1 : 0;
-      var gi = groupingInfos[level];
-
-      for (var i = 0, l = gi.predefinedValues.length; i < l; i++) {
-        val = gi.predefinedValues[i];
-        group = groupsByVal[val];
-        if (!group) {
-          group = new Slick.Group();
-          group.value = val;
-          group.level = level;
-          group.groupingKey = (parentGroup ? parentGroup.groupingKey + groupingDelimiter : '') + val;
-          groups[groups.length] = group;
-          groupsByVal[val] = group;
-        }
-      }
-
-      for (var i = 0, l = rows.length; i < l; i++) {
-        r = rows[i];
-        val = gi.getterIsAFn ? gi.getter(r) : r[gi.getter];
-        group = groupsByVal[val];
-        if (!group) {
-          group = new Slick.Group();
-          group.value = val;
-          group.level = level;
-          group.groupingKey = (parentGroup ? parentGroup.groupingKey + groupingDelimiter : '') + val;
-          groups[groups.length] = group;
-          groupsByVal[val] = group;
-        }
-
-        group.rows[group.count++] = r;
-      }
-
-      if (level < groupingInfos.length - 1) {
-        for (var i = 0; i < groups.length; i++) {
-          group = groups[i];
-          group.groups = extractGroups(group.rows, group);
-        }
-      }      
-
-      groups.sort(groupingInfos[level].comparer);
-
-      return groups;
-    }
-
-    function calculateTotals(totals) {
-      var group = totals.group;
-      var gi = groupingInfos[group.level];
-      var isLeafLevel = (group.level == groupingInfos.length);
-      var agg, idx = gi.aggregators.length;
-
-      if (!isLeafLevel && gi.aggregateChildGroups) {
-        // make sure all the subgroups are calculated
-        var i = group.groups.length;
-        while (i--) {
-          if (!group.groups[i].initialized) {
-            calculateTotals(group.groups[i]);
-          }
-        }
-      }
-
-      while (idx--) {
-        agg = gi.aggregators[idx];
-        agg.init();
-        if (!isLeafLevel && gi.aggregateChildGroups) {
-          gi.compiledAccumulators[idx].call(agg, group.groups);
-        } else {
-          gi.compiledAccumulators[idx].call(agg, group.rows);
-        }
-        agg.storeResult(totals);
-      }
-      totals.initialized = true;
-    }
-
-    function addGroupTotals(group) {
-      var gi = groupingInfos[group.level];
-      var totals = new Slick.GroupTotals();
-      totals.group = group;
-      group.totals = totals;
-      if (!gi.lazyTotalsCalculation) {
-        calculateTotals(totals);
-      }
-    }
-
-    function addTotals(groups, level) {
-      level = level || 0;
-      var gi = groupingInfos[level];
-      var groupCollapsed = gi.collapsed;
-      var toggledGroups = toggledGroupsByLevel[level];      
-      var idx = groups.length, g;
-      while (idx--) {
-        g = groups[idx];
-
-        if (g.collapsed && !gi.aggregateCollapsed) {
-          continue;
-        }
-
-        // Do a depth-first aggregation so that parent group aggregators can access subgroup totals.
-        if (g.groups) {
-          addTotals(g.groups, level + 1);
-        }
-
-        if (gi.aggregators.length && (
-            gi.aggregateEmpty || g.rows.length || (g.groups && g.groups.length))) {
-          addGroupTotals(g);
-        }
-
-        g.collapsed = groupCollapsed ^ toggledGroups[g.groupingKey];
-        g.title = gi.formatter ? gi.formatter(g) : g.value;
-      }
-    } 
-
-    function flattenGroupedRows(groups, level) {
-      level = level || 0;
-      var gi = groupingInfos[level];
-      var groupedRows = [], rows, gl = 0, g;
-      for (var i = 0, l = groups.length; i < l; i++) {
-        g = groups[i];
-        groupedRows[gl++] = g;
-
-        if (!g.collapsed) {
-          rows = g.groups ? flattenGroupedRows(g.groups, level + 1) : g.rows;
-          for (var j = 0, jj = rows.length; j < jj; j++) {
-            groupedRows[gl++] = rows[j];
-          }
-        }
-
-        if (g.totals && gi.displayTotalsRow && (!g.collapsed || gi.aggregateCollapsed)) {
-          groupedRows[gl++] = g.totals;
-        }
-      }
-      return groupedRows;
-    }
-
-    function getFunctionInfo(fn) {
-      var fnRegex = /^function[^(]*\(([^)]*)\)\s*{([\s\S]*)}$/;
-      var matches = fn.toString().match(fnRegex);
-      return {
-        params: matches[1].split(","),
-        body: matches[2]
-      };
-    }
-
-    function compileAccumulatorLoop(aggregator) {
-      var accumulatorInfo = getFunctionInfo(aggregator.accumulate);
-      var fn = new Function(
-          "_items",
-          "for (var " + accumulatorInfo.params[0] + ", _i=0, _il=_items.length; _i<_il; _i++) {" +
-              accumulatorInfo.params[0] + " = _items[_i]; " +
-              accumulatorInfo.body +
-          "}"
-      );
-      fn.displayName = fn.name = "compiledAccumulatorLoop";
-      return fn;
-    }
-
-    function compileFilter() {
-      var filterInfo = getFunctionInfo(filter);
-
-      var filterBody = filterInfo.body
-          .replace(/return false\s*([;}]|$)/gi, "{ continue _coreloop; }$1")
-          .replace(/return true\s*([;}]|$)/gi, "{ _retval[_idx++] = $item$; continue _coreloop; }$1")
-          .replace(/return ([^;}]+?)\s*([;}]|$)/gi,
-          "{ if ($1) { _retval[_idx++] = $item$; }; continue _coreloop; }$2");
-
-      // This preserves the function template code after JS compression,
-      // so that replace() commands still work as expected.
-      var tpl = [
-        //"function(_items, _args) { ",
-        "var _retval = [], _idx = 0; ",
-        "var $item$, $args$ = _args; ",
-        "_coreloop: ",
-        "for (var _i = 0, _il = _items.length; _i < _il; _i++) { ",
-        "$item$ = _items[_i]; ",
-        "$filter$; ",
-        "} ",
-        "return _retval; "
-        //"}"
-      ].join("");
-      tpl = tpl.replace(/\$filter\$/gi, filterBody);
-      tpl = tpl.replace(/\$item\$/gi, filterInfo.params[0]);
-      tpl = tpl.replace(/\$args\$/gi, filterInfo.params[1]);
-
-      var fn = new Function("_items,_args", tpl);
-      fn.displayName = fn.name = "compiledFilter";
-      return fn;
-    }
-
-    function compileFilterWithCaching() {
-      var filterInfo = getFunctionInfo(filter);
-
-      var filterBody = filterInfo.body
-          .replace(/return false\s*([;}]|$)/gi, "{ continue _coreloop; }$1")
-          .replace(/return true\s*([;}]|$)/gi, "{ _cache[_i] = true;_retval[_idx++] = $item$; continue _coreloop; }$1")
-          .replace(/return ([^;}]+?)\s*([;}]|$)/gi,
-          "{ if ((_cache[_i] = $1)) { _retval[_idx++] = $item$; }; continue _coreloop; }$2");
-
-      // This preserves the function template code after JS compression,
-      // so that replace() commands still work as expected.
-      var tpl = [
-        //"function(_items, _args, _cache) { ",
-        "var _retval = [], _idx = 0; ",
-        "var $item$, $args$ = _args; ",
-        "_coreloop: ",
-        "for (var _i = 0, _il = _items.length; _i < _il; _i++) { ",
-        "$item$ = _items[_i]; ",
-        "if (_cache[_i]) { ",
-        "_retval[_idx++] = $item$; ",
-        "continue _coreloop; ",
-        "} ",
-        "$filter$; ",
-        "} ",
-        "return _retval; "
-        //"}"
-      ].join("");
-      tpl = tpl.replace(/\$filter\$/gi, filterBody);
-      tpl = tpl.replace(/\$item\$/gi, filterInfo.params[0]);
-      tpl = tpl.replace(/\$args\$/gi, filterInfo.params[1]);
-
-      var fn = new Function("_items,_args,_cache", tpl);
-      fn.displayName = fn.name = "compiledFilterWithCaching";
-      return fn;
-    }
-
-    function uncompiledFilter(items, args) {
-      var retval = [], idx = 0;
-
-      for (var i = 0, ii = items.length; i < ii; i++) {
-        if (filter(items[i], args)) {
-          retval[idx++] = items[i];
-        }
-      }
-
-      return retval;
-    }
-
-    function uncompiledFilterWithCaching(items, args, cache) {
-      var retval = [], idx = 0, item;
-
-      for (var i = 0, ii = items.length; i < ii; i++) {
-        item = items[i];
-        if (cache[i]) {
-          retval[idx++] = item;
-        } else if (filter(item, args)) {
-          retval[idx++] = item;
-          cache[i] = true;
-        }
-      }
-
-      return retval;
-    }
-
-    function getFilteredAndPagedItems(items) {
-      if (filter) {
-        var batchFilter = options.inlineFilters ? compiledFilter : uncompiledFilter;
-        var batchFilterWithCaching = options.inlineFilters ? compiledFilterWithCaching : uncompiledFilterWithCaching;
-
-        if (refreshHints.isFilterNarrowing) {
-          filteredItems = batchFilter(filteredItems, filterArgs);
-        } else if (refreshHints.isFilterExpanding) {
-          filteredItems = batchFilterWithCaching(items, filterArgs, filterCache);
-        } else if (!refreshHints.isFilterUnchanged) {
-          filteredItems = batchFilter(items, filterArgs);
-        }
-      } else {
-        // special case:  if not filtering and not paging, the resulting
-        // rows collection needs to be a copy so that changes due to sort
-        // can be caught
-        filteredItems = pagesize ? items : items.concat();
-      }
-
-      // get the current page
-      var paged;
-      if (pagesize) {
-        if (filteredItems.length < pagenum * pagesize) {
-          pagenum = Math.floor(filteredItems.length / pagesize);
-        }
-        paged = filteredItems.slice(pagesize * pagenum, pagesize * pagenum + pagesize);
-      } else {
-        paged = filteredItems;
-      }
-
-      return {totalRows: filteredItems.length, rows: paged};
-    }
-
-    function getRowDiffs(rows, newRows) {
-      var item, r, eitherIsNonData, diff = [];
-      var from = 0, to = newRows.length;
-
-      if (refreshHints && refreshHints.ignoreDiffsBefore) {
-        from = Math.max(0,
-            Math.min(newRows.length, refreshHints.ignoreDiffsBefore));
-      }
-
-      if (refreshHints && refreshHints.ignoreDiffsAfter) {
-        to = Math.min(newRows.length,
-            Math.max(0, refreshHints.ignoreDiffsAfter));
-      }
-
-      for (var i = from, rl = rows.length; i < to; i++) {
-        if (i >= rl) {
-          diff[diff.length] = i;
-        } else {
-          item = newRows[i];
-          r = rows[i];
-
-          if ((groupingInfos.length && (eitherIsNonData = (item.__nonDataRow) || (r.__nonDataRow)) &&
-              item.__group !== r.__group ||
-              item.__group && !item.equals(r))
-              || (eitherIsNonData &&
-              // no good way to compare totals since they are arbitrary DTOs
-              // deep object comparison is pretty expensive
-              // always considering them 'dirty' seems easier for the time being
-              (item.__groupTotals || r.__groupTotals))
-              || item[idProperty] != r[idProperty]
-              || (updated && updated[item[idProperty]])
-              ) {
-            diff[diff.length] = i;
-          }
-        }
-      }
-      return diff;
-    }
-
-    function recalc(_items) {
-      rowsById = null;
-
-      if (refreshHints.isFilterNarrowing != prevRefreshHints.isFilterNarrowing ||
-          refreshHints.isFilterExpanding != prevRefreshHints.isFilterExpanding) {
-        filterCache = [];
-      }
-
-      var filteredItems = getFilteredAndPagedItems(_items);
-      totalRows = filteredItems.totalRows;
-      var newRows = filteredItems.rows;
-
-      groups = [];
-      if (groupingInfos.length) {
-        groups = extractGroups(newRows);
-        if (groups.length) {
-          addTotals(groups);
-          newRows = flattenGroupedRows(groups);
-        }
-      }
-
-      var diff = getRowDiffs(rows, newRows);
-
-      rows = newRows;
-
-      return diff;
-    }
-
-    function refresh() {
-      if (suspend) {
-        return;
-      }
-
-      var countBefore = rows.length;
-      var totalRowsBefore = totalRows;
-
-      var diff = recalc(items, filter); // pass as direct refs to avoid closure perf hit
-
-      // if the current page is no longer valid, go to last page and recalc
-      // we suffer a performance penalty here, but the main loop (recalc) remains highly optimized
-      if (pagesize && totalRows < pagenum * pagesize) {
-        pagenum = Math.max(0, Math.ceil(totalRows / pagesize) - 1);
-        diff = recalc(items, filter);
-      }
-
-      updated = null;
-      prevRefreshHints = refreshHints;
-      refreshHints = {};
-
-      if (totalRowsBefore != totalRows) {
-        onPagingInfoChanged.notify(getPagingInfo(), null, self);
-      }
-      if (countBefore != rows.length) {
-        onRowCountChanged.notify({previous: countBefore, current: rows.length}, null, self);
-      }
-      if (diff.length > 0) {
-        onRowsChanged.notify({rows: diff}, null, self);
-      }
-    }
-
-    /***
-     * Wires the grid and the DataView together to keep row selection tied to item ids.
-     * This is useful since, without it, the grid only knows about rows, so if the items
-     * move around, the same rows stay selected instead of the selection moving along
-     * with the items.
-     *
-     * NOTE:  This doesn't work with cell selection model.
-     *
-     * @param grid {Slick.Grid} The grid to sync selection with.
-     * @param preserveHidden {Boolean} Whether to keep selected items that go out of the
-     *     view due to them getting filtered out.
-     * @param preserveHiddenOnSelectionChange {Boolean} Whether to keep selected items
-     *     that are currently out of the view (see preserveHidden) as selected when selection
-     *     changes.
-     * @return {Slick.Event} An event that notifies when an internal list of selected row ids
-     *     changes.  This is useful since, in combination with the above two options, it allows
-     *     access to the full list selected row ids, and not just the ones visible to the grid.
-     * @method syncGridSelection
-     */
-    function syncGridSelection(grid, preserveHidden, preserveHiddenOnSelectionChange) {
-      var self = this;
-      var inHandler;
-      var selectedRowIds = self.mapRowsToIds(grid.getSelectedRows());
-      var onSelectedRowIdsChanged = new Slick.Event();
-
-      function setSelectedRowIds(rowIds) {
-        if (selectedRowIds.join(",") == rowIds.join(",")) {
-          return;
-        }
-
-        selectedRowIds = rowIds;
-
-        onSelectedRowIdsChanged.notify({
-          "grid": grid,
-          "ids": selectedRowIds
-        }, new Slick.EventData(), self);
-      }
-
-      function update() {
-        if (selectedRowIds.length > 0) {
-          inHandler = true;
-          var selectedRows = self.mapIdsToRows(selectedRowIds);
-          if (!preserveHidden) {
-            setSelectedRowIds(self.mapRowsToIds(selectedRows));       
-          }
-          grid.setSelectedRows(selectedRows);
-          inHandler = false;
-        }
-      }
-
-      grid.onSelectedRowsChanged.subscribe(function(e, args) {
-        if (inHandler) { return; }
-        var newSelectedRowIds = self.mapRowsToIds(grid.getSelectedRows());
-        if (!preserveHiddenOnSelectionChange || !grid.getOptions().multiSelect) {
-          setSelectedRowIds(newSelectedRowIds);
-        } else {
-          // keep the ones that are hidden
-          var existing = $.grep(selectedRowIds, function(id) { return self.getRowById(id) === undefined; });
-          // add the newly selected ones
-          setSelectedRowIds(existing.concat(newSelectedRowIds));
-        }
-      });
-
-      this.onRowsChanged.subscribe(update);
-
-      this.onRowCountChanged.subscribe(update);
-
-      return onSelectedRowIdsChanged;
-    }
-
-    function syncGridCellCssStyles(grid, key) {
-      var hashById;
-      var inHandler;
-
-      // since this method can be called after the cell styles have been set,
-      // get the existing ones right away
-      storeCellCssStyles(grid.getCellCssStyles(key));
-
-      function storeCellCssStyles(hash) {
-        hashById = {};
-        for (var row in hash) {
-          var id = rows[row][idProperty];
-          hashById[id] = hash[row];
-        }
-      }
-
-      function update() {
-        if (hashById) {
-          inHandler = true;
-          ensureRowsByIdCache();
-          var newHash = {};
-          for (var id in hashById) {
-            var row = rowsById[id];
-            if (row != undefined) {
-              newHash[row] = hashById[id];
-            }
-          }
-          grid.setCellCssStyles(key, newHash);
-          inHandler = false;
-        }
-      }
-
-      grid.onCellCssStylesChanged.subscribe(function(e, args) {
-        if (inHandler) { return; }
-        if (key != args.key) { return; }
-        if (args.hash) {
-          storeCellCssStyles(args.hash);
-        }
-      });
-
-      this.onRowsChanged.subscribe(update);
-
-      this.onRowCountChanged.subscribe(update);
-    }
-
-    $.extend(this, {
-      // methods
-      "beginUpdate": beginUpdate,
-      "endUpdate": endUpdate,
-      "setPagingOptions": setPagingOptions,
-      "getPagingInfo": getPagingInfo,
-      "getItems": getItems,
-      "setItems": setItems,
-      "setFilter": setFilter,
-      "sort": sort,
-      "fastSort": fastSort,
-      "reSort": reSort,
-      "setGrouping": setGrouping,
-      "getGrouping": getGrouping,
-      "groupBy": groupBy,
-      "setAggregators": setAggregators,
-      "collapseAllGroups": collapseAllGroups,
-      "expandAllGroups": expandAllGroups,
-      "collapseGroup": collapseGroup,
-      "expandGroup": expandGroup,
-      "getGroups": getGroups,
-      "getIdxById": getIdxById,
-      "getRowById": getRowById,
-      "getItemById": getItemById,
-      "getItemByIdx": getItemByIdx,
-      "mapRowsToIds": mapRowsToIds,
-      "mapIdsToRows": mapIdsToRows,
-      "setRefreshHints": setRefreshHints,
-      "setFilterArgs": setFilterArgs,
-      "refresh": refresh,
-      "updateItem": updateItem,
-      "insertItem": insertItem,
-      "addItem": addItem,
-      "deleteItem": deleteItem,
-      "syncGridSelection": syncGridSelection,
-      "syncGridCellCssStyles": syncGridCellCssStyles,
-
-      // data provider methods
-      "getLength": getLength,
-      "getItem": getItem,
-      "getItemMetadata": getItemMetadata,
-
-      // events
-      "onRowCountChanged": onRowCountChanged,
-      "onRowsChanged": onRowsChanged,
-      "onPagingInfoChanged": onPagingInfoChanged
-    });
-  }
-
-  function AvgAggregator(field) {
-    this.field_ = field;
-
-    this.init = function () {
-      this.count_ = 0;
-      this.nonNullCount_ = 0;
-      this.sum_ = 0;
-    };
-
-    this.accumulate = function (item) {
-      var val = item[this.field_];
-      this.count_++;
-      if (val != null && val !== "" && val !== NaN) {
-        this.nonNullCount_++;
-        this.sum_ += parseFloat(val);
-      }
-    };
-
-    this.storeResult = function (groupTotals) {
-      if (!groupTotals.avg) {
-        groupTotals.avg = {};
-      }
-      if (this.nonNullCount_ != 0) {
-        groupTotals.avg[this.field_] = this.sum_ / this.nonNullCount_;
-      }
-    };
-  }
-
-  function MinAggregator(field) {
-    this.field_ = field;
-
-    this.init = function () {
-      this.min_ = null;
-    };
-
-    this.accumulate = function (item) {
-      var val = item[this.field_];
-      if (val != null && val !== "" && val !== NaN) {
-        if (this.min_ == null || val < this.min_) {
-          this.min_ = val;
-        }
-      }
-    };
-
-    this.storeResult = function (groupTotals) {
-      if (!groupTotals.min) {
-        groupTotals.min = {};
-      }
-      groupTotals.min[this.field_] = this.min_;
-    }
-  }
-
-  function MaxAggregator(field) {
-    this.field_ = field;
-
-    this.init = function () {
-      this.max_ = null;
-    };
-
-    this.accumulate = function (item) {
-      var val = item[this.field_];
-      if (val != null && val !== "" && val !== NaN) {
-        if (this.max_ == null || val > this.max_) {
-          this.max_ = val;
-        }
-      }
-    };
-
-    this.storeResult = function (groupTotals) {
-      if (!groupTotals.max) {
-        groupTotals.max = {};
-      }
-      groupTotals.max[this.field_] = this.max_;
-    }
-  }
-
-  function SumAggregator(field) {
-    this.field_ = field;
-
-    this.init = function () {
-      this.sum_ = null;
-    };
-
-    this.accumulate = function (item) {
-      var val = item[this.field_];
-      if (val != null && val !== "" && val !== NaN) {
-        this.sum_ += parseFloat(val);
-      }
-    };
-
-    this.storeResult = function (groupTotals) {
-      if (!groupTotals.sum) {
-        groupTotals.sum = {};
-      }
-      groupTotals.sum[this.field_] = this.sum_;
-    }
-  }
-
-  // TODO:  add more built-in aggregators
-  // TODO:  merge common aggregators in one to prevent needles iterating
-
-})(jQuery);

http://git-wip-us.apache.org/repos/asf/nifi/blob/6170f644/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/jquery/slickgrid/slick.editors.js
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/jquery/slickgrid/slick.editors.js b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/jquery/slickgrid/slick.editors.js
deleted file mode 100755
index 04b20d2..0000000
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/jquery/slickgrid/slick.editors.js
+++ /dev/null
@@ -1,512 +0,0 @@
-/***
- * Contains basic SlickGrid editors.
- * @module Editors
- * @namespace Slick
- */
-
-(function ($) {
-  // register namespace
-  $.extend(true, window, {
-    "Slick": {
-      "Editors": {
-        "Text": TextEditor,
-        "Integer": IntegerEditor,
-        "Date": DateEditor,
-        "YesNoSelect": YesNoSelectEditor,
-        "Checkbox": CheckboxEditor,
-        "PercentComplete": PercentCompleteEditor,
-        "LongText": LongTextEditor
-      }
-    }
-  });
-
-  function TextEditor(args) {
-    var $input;
-    var defaultValue;
-    var scope = this;
-
-    this.init = function () {
-      $input = $("<INPUT type=text class='editor-text' />")
-          .appendTo(args.container)
-          .bind("keydown.nav", function (e) {
-            if (e.keyCode === $.ui.keyCode.LEFT || e.keyCode === $.ui.keyCode.RIGHT) {
-              e.stopImmediatePropagation();
-            }
-          })
-          .focus()
-          .select();
-    };
-
-    this.destroy = function () {
-      $input.remove();
-    };
-
-    this.focus = function () {
-      $input.focus();
-    };
-
-    this.getValue = function () {
-      return $input.val();
-    };
-
-    this.setValue = function (val) {
-      $input.val(val);
-    };
-
-    this.loadValue = function (item) {
-      defaultValue = item[args.column.field] || "";
-      $input.val(defaultValue);
-      $input[0].defaultValue = defaultValue;
-      $input.select();
-    };
-
-    this.serializeValue = function () {
-      return $input.val();
-    };
-
-    this.applyValue = function (item, state) {
-      item[args.column.field] = state;
-    };
-
-    this.isValueChanged = function () {
-      return (!($input.val() == "" && defaultValue == null)) && ($input.val() != defaultValue);
-    };
-
-    this.validate = function () {
-      if (args.column.validator) {
-        var validationResults = args.column.validator($input.val());
-        if (!validationResults.valid) {
-          return validationResults;
-        }
-      }
-
-      return {
-        valid: true,
-        msg: null
-      };
-    };
-
-    this.init();
-  }
-
-  function IntegerEditor(args) {
-    var $input;
-    var defaultValue;
-    var scope = this;
-
-    this.init = function () {
-      $input = $("<INPUT type=text class='editor-text' />");
-
-      $input.bind("keydown.nav", function (e) {
-        if (e.keyCode === $.ui.keyCode.LEFT || e.keyCode === $.ui.keyCode.RIGHT) {
-          e.stopImmediatePropagation();
-        }
-      });
-
-      $input.appendTo(args.container);
-      $input.focus().select();
-    };
-
-    this.destroy = function () {
-      $input.remove();
-    };
-
-    this.focus = function () {
-      $input.focus();
-    };
-
-    this.loadValue = function (item) {
-      defaultValue = item[args.column.field];
-      $input.val(defaultValue);
-      $input[0].defaultValue = defaultValue;
-      $input.select();
-    };
-
-    this.serializeValue = function () {
-      return parseInt($input.val(), 10) || 0;
-    };
-
-    this.applyValue = function (item, state) {
-      item[args.column.field] = state;
-    };
-
-    this.isValueChanged = function () {
-      return (!($input.val() == "" && defaultValue == null)) && ($input.val() != defaultValue);
-    };
-
-    this.validate = function () {
-      if (isNaN($input.val())) {
-        return {
-          valid: false,
-          msg: "Please enter a valid integer"
-        };
-      }
-
-      return {
-        valid: true,
-        msg: null
-      };
-    };
-
-    this.init();
-  }
-
-  function DateEditor(args) {
-    var $input;
-    var defaultValue;
-    var scope = this;
-    var calendarOpen = false;
-
-    this.init = function () {
-      $input = $("<INPUT type=text class='editor-text' />");
-      $input.appendTo(args.container);
-      $input.focus().select();
-      $input.datepicker({
-        showOn: "button",
-        buttonImageOnly: true,
-        buttonImage: "../images/calendar.gif",
-        beforeShow: function () {
-          calendarOpen = true
-        },
-        onClose: function () {
-          calendarOpen = false
-        }
-      });
-      $input.width($input.width() - 18);
-    };
-
-    this.destroy = function () {
-      $.datepicker.dpDiv.stop(true, true);
-      $input.datepicker("hide");
-      $input.datepicker("destroy");
-      $input.remove();
-    };
-
-    this.show = function () {
-      if (calendarOpen) {
-        $.datepicker.dpDiv.stop(true, true).show();
-      }
-    };
-
-    this.hide = function () {
-      if (calendarOpen) {
-        $.datepicker.dpDiv.stop(true, true).hide();
-      }
-    };
-
-    this.position = function (position) {
-      if (!calendarOpen) {
-        return;
-      }
-      $.datepicker.dpDiv
-          .css("top", position.top + 30)
-          .css("left", position.left);
-    };
-
-    this.focus = function () {
-      $input.focus();
-    };
-
-    this.loadValue = function (item) {
-      defaultValue = item[args.column.field];
-      $input.val(defaultValue);
-      $input[0].defaultValue = defaultValue;
-      $input.select();
-    };
-
-    this.serializeValue = function () {
-      return $input.val();
-    };
-
-    this.applyValue = function (item, state) {
-      item[args.column.field] = state;
-    };
-
-    this.isValueChanged = function () {
-      return (!($input.val() == "" && defaultValue == null)) && ($input.val() != defaultValue);
-    };
-
-    this.validate = function () {
-      return {
-        valid: true,
-        msg: null
-      };
-    };
-
-    this.init();
-  }
-
-  function YesNoSelectEditor(args) {
-    var $select;
-    var defaultValue;
-    var scope = this;
-
-    this.init = function () {
-      $select = $("<SELECT tabIndex='0' class='editor-yesno'><OPTION value='yes'>Yes</OPTION><OPTION value='no'>No</OPTION></SELECT>");
-      $select.appendTo(args.container);
-      $select.focus();
-    };
-
-    this.destroy = function () {
-      $select.remove();
-    };
-
-    this.focus = function () {
-      $select.focus();
-    };
-
-    this.loadValue = function (item) {
-      $select.val((defaultValue = item[args.column.field]) ? "yes" : "no");
-      $select.select();
-    };
-
-    this.serializeValue = function () {
-      return ($select.val() == "yes");
-    };
-
-    this.applyValue = function (item, state) {
-      item[args.column.field] = state;
-    };
-
-    this.isValueChanged = function () {
-      return ($select.val() != defaultValue);
-    };
-
-    this.validate = function () {
-      return {
-        valid: true,
-        msg: null
-      };
-    };
-
-    this.init();
-  }
-
-  function CheckboxEditor(args) {
-    var $select;
-    var defaultValue;
-    var scope = this;
-
-    this.init = function () {
-      $select = $("<INPUT type=checkbox value='true' class='editor-checkbox' hideFocus>");
-      $select.appendTo(args.container);
-      $select.focus();
-    };
-
-    this.destroy = function () {
-      $select.remove();
-    };
-
-    this.focus = function () {
-      $select.focus();
-    };
-
-    this.loadValue = function (item) {
-      defaultValue = !!item[args.column.field];
-      if (defaultValue) {
-        $select.prop('checked', true);
-      } else {
-        $select.prop('checked', false);
-      }
-    };
-
-    this.serializeValue = function () {
-      return $select.prop('checked');
-    };
-
-    this.applyValue = function (item, state) {
-      item[args.column.field] = state;
-    };
-
-    this.isValueChanged = function () {
-      return (this.serializeValue() !== defaultValue);
-    };
-
-    this.validate = function () {
-      return {
-        valid: true,
-        msg: null
-      };
-    };
-
-    this.init();
-  }
-
-  function PercentCompleteEditor(args) {
-    var $input, $picker;
-    var defaultValue;
-    var scope = this;
-
-    this.init = function () {
-      $input = $("<INPUT type=text class='editor-percentcomplete' />");
-      $input.width($(args.container).innerWidth() - 25);
-      $input.appendTo(args.container);
-
-      $picker = $("<div class='editor-percentcomplete-picker' />").appendTo(args.container);
-      $picker.append("<div class='editor-percentcomplete-helper'><div class='editor-percentcomplete-wrapper'><div class='editor-percentcomplete-slider' /><div class='editor-percentcomplete-buttons' /></div></div>");
-
-      $picker.find(".editor-percentcomplete-buttons").append("<button val=0>Not started</button><br/><button val=50>In Progress</button><br/><button val=100>Complete</button>");
-
-      $input.focus().select();
-
-      $picker.find(".editor-percentcomplete-slider").slider({
-        orientation: "vertical",
-        range: "min",
-        value: defaultValue,
-        slide: function (event, ui) {
-          $input.val(ui.value)
-        }
-      });
-
-      $picker.find(".editor-percentcomplete-buttons button").bind("click", function (e) {
-        $input.val($(this).attr("val"));
-        $picker.find(".editor-percentcomplete-slider").slider("value", $(this).attr("val"));
-      })
-    };
-
-    this.destroy = function () {
-      $input.remove();
-      $picker.remove();
-    };
-
-    this.focus = function () {
-      $input.focus();
-    };
-
-    this.loadValue = function (item) {
-      $input.val(defaultValue = item[args.column.field]);
-      $input.select();
-    };
-
-    this.serializeValue = function () {
-      return parseInt($input.val(), 10) || 0;
-    };
-
-    this.applyValue = function (item, state) {
-      item[args.column.field] = state;
-    };
-
-    this.isValueChanged = function () {
-      return (!($input.val() == "" && defaultValue == null)) && ((parseInt($input.val(), 10) || 0) != defaultValue);
-    };
-
-    this.validate = function () {
-      if (isNaN(parseInt($input.val(), 10))) {
-        return {
-          valid: false,
-          msg: "Please enter a valid positive number"
-        };
-      }
-
-      return {
-        valid: true,
-        msg: null
-      };
-    };
-
-    this.init();
-  }
-
-  /*
-   * An example of a "detached" editor.
-   * The UI is added onto document BODY and .position(), .show() and .hide() are implemented.
-   * KeyDown events are also handled to provide handling for Tab, Shift-Tab, Esc and Ctrl-Enter.
-   */
-  function LongTextEditor(args) {
-    var $input, $wrapper;
-    var defaultValue;
-    var scope = this;
-
-    this.init = function () {
-      var $container = $("body");
-
-      $wrapper = $("<DIV style='z-index:10000;position:absolute;background:white;padding:5px;border:3px solid gray; -moz-border-radius:10px; border-radius:10px;'/>")
-          .appendTo($container);
-
-      $input = $("<TEXTAREA hidefocus rows=5 style='backround:white;width:250px;height:80px;border:0;outline:0'>")
-          .appendTo($wrapper);
-
-      $("<DIV style='text-align:right'><BUTTON>Save</BUTTON><BUTTON>Cancel</BUTTON></DIV>")
-          .appendTo($wrapper);
-
-      $wrapper.find("button:first").bind("click", this.save);
-      $wrapper.find("button:last").bind("click", this.cancel);
-      $input.bind("keydown", this.handleKeyDown);
-
-      scope.position(args.position);
-      $input.focus().select();
-    };
-
-    this.handleKeyDown = function (e) {
-      if (e.which == $.ui.keyCode.ENTER && e.ctrlKey) {
-        scope.save();
-      } else if (e.which == $.ui.keyCode.ESCAPE) {
-        e.preventDefault();
-        scope.cancel();
-      } else if (e.which == $.ui.keyCode.TAB && e.shiftKey) {
-        e.preventDefault();
-        args.grid.navigatePrev();
-      } else if (e.which == $.ui.keyCode.TAB) {
-        e.preventDefault();
-        args.grid.navigateNext();
-      }
-    };
-
-    this.save = function () {
-      args.commitChanges();
-    };
-
-    this.cancel = function () {
-      $input.val(defaultValue);
-      args.cancelChanges();
-    };
-
-    this.hide = function () {
-      $wrapper.hide();
-    };
-
-    this.show = function () {
-      $wrapper.show();
-    };
-
-    this.position = function (position) {
-      $wrapper
-          .css("top", position.top - 5)
-          .css("left", position.left - 5)
-    };
-
-    this.destroy = function () {
-      $wrapper.remove();
-    };
-
-    this.focus = function () {
-      $input.focus();
-    };
-
-    this.loadValue = function (item) {
-      $input.val(defaultValue = item[args.column.field]);
-      $input.select();
-    };
-
-    this.serializeValue = function () {
-      return $input.val();
-    };
-
-    this.applyValue = function (item, state) {
-      item[args.column.field] = state;
-    };
-
-    this.isValueChanged = function () {
-      return (!($input.val() == "" && defaultValue == null)) && ($input.val() != defaultValue);
-    };
-
-    this.validate = function () {
-      return {
-        valid: true,
-        msg: null
-      };
-    };
-
-    this.init();
-  }
-})(jQuery);

http://git-wip-us.apache.org/repos/asf/nifi/blob/6170f644/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/jquery/slickgrid/slick.formatters.js
----------------------------------------------------------------------
diff --git a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/jquery/slickgrid/slick.formatters.js b/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/jquery/slickgrid/slick.formatters.js
deleted file mode 100755
index a31aaf9..0000000
--- a/nifi-nar-bundles/nifi-framework-bundle/nifi-framework/nifi-web/nifi-web-ui/src/main/webapp/js/jquery/slickgrid/slick.formatters.js
+++ /dev/null
@@ -1,59 +0,0 @@
-/***
- * Contains basic SlickGrid formatters.
- * 
- * NOTE:  These are merely examples.  You will most likely need to implement something more
- *        robust/extensible/localizable/etc. for your use!
- * 
- * @module Formatters
- * @namespace Slick
- */
-
-(function ($) {
-  // register namespace
-  $.extend(true, window, {
-    "Slick": {
-      "Formatters": {
-        "PercentComplete": PercentCompleteFormatter,
-        "PercentCompleteBar": PercentCompleteBarFormatter,
-        "YesNo": YesNoFormatter,
-        "Checkmark": CheckmarkFormatter
-      }
-    }
-  });
-
-  function PercentCompleteFormatter(row, cell, value, columnDef, dataContext) {
-    if (value == null || value === "") {
-      return "-";
-    } else if (value < 50) {
-      return "<span style='color:red;font-weight:bold;'>" + value + "%</span>";
-    } else {
-      return "<span style='color:green'>" + value + "%</span>";
-    }
-  }
-
-  function PercentCompleteBarFormatter(row, cell, value, columnDef, dataContext) {
-    if (value == null || value === "") {
-      return "";
-    }
-
-    var color;
-
-    if (value < 30) {
-      color = "red";
-    } else if (value < 70) {
-      color = "silver";
-    } else {
-      color = "green";
-    }
-
-    return "<span class='percent-complete-bar' style='background:" + color + ";width:" + value + "%'></span>";
-  }
-
-  function YesNoFormatter(row, cell, value, columnDef, dataContext) {
-    return value ? "Yes" : "No";
-  }
-
-  function CheckmarkFormatter(row, cell, value, columnDef, dataContext) {
-    return value ? "<img src='../images/tick.png'>" : "";
-  }
-})(jQuery);