<commit_before>import BasePlugin from './../_base.js';
import {registerPlugin, getPlugin} from './../../plugins.js';

/**
 * @class ColumnSummary
 * @plugin
 *
 *
 */
class ColumnSummary extends BasePlugin {
  constructor(hotInstance) {
    super(hotInstance);

    if (!this.hot.getSettings().columnSummary) {
      return;
    }

    this.endpoints = [];
    this.settings = null;
    this.currentEndpoint = null;

    this.init();
  }

  init() {
    this.settings = this.hot.getSettings().columnSummary;

    this.bindHooks();
  }

  bindHooks() {
    let _this = this;

    this.hot.addHook('afterInit', function() {
      _this.parseSettings(_this.settings);
      _this.refreshAllEndpoints(true);
    });

    this.hot.addHook('afterChange', function(changes, source) {
      if (changes && source !== 'columnSummary' && source !== 'loadData') {
        _this.refreshChangedEndpoints(changes);
      }
    });

  }

  parseSettings() {
    for (var s in this.settings) {
      if (this.settings.hasOwnProperty(s)) {
        let newEndpoint = {};

        this.assignSetting(this.settings[s], newEndpoint, 'ranges', [[0, this.hot.countRows() - 1]]);
        this.assignSetting(this.settings[s], newEndpoint, 'reversedRowCoords', false);
        this.assignSetting(this.settings[s], newEndpoint, 'destinationRow', new Error('You must provide a destination row for the Column Summary plugin in order to work properly!'));
        this.assignSetting(this.settings[s], newEndpoint, 'destinationColumn', new Error('You must provide a destination column for the Column Summary plugin in order to work properly!'));
        this.assignSetting(this.settings[s], newEndpoint, 'sourceColumn', this.settings[s].destinationColumn);
        this.assignSetting(this.settings[s], newEndpoint, 'type', 'sum');
        this.assignSetting(this.settings[s], newEndpoint, 'forceNumeric', false);
        this.assignSetting(this.settings[s], newEndpoint, 'suppressDataTypeErrors', true);
        this.assignSetting(this.settings[s], newEndpoint, 'suppressDataTypeErrors', true);
        this.assignSetting(this.settings[s], newEndpoint, 'customFunction', null);
        this.assignSetting(this.settings[s], newEndpoint, 'readOnly', true);
        this.assignSetting(this.settings[s], newEndpoint, 'roundFloat', false);

        this.endpoints.push(newEndpoint);
      }
    }
  }

  assignSetting(settings, endpoint, name, defaultValue) {
    if (name === 'ranges' && settings[name] === void 0) {
      endpoint[name] = defaultValue;
      return;
    } else if (name === 'ranges' && settings[name].length === 0) {
      return;
    }

    if (settings[name] !== void 0) {
      if (name === 'destinationRow' && endpoint.reversedRowCoords) {
        endpoint[name] = this.hot.countRows() + this.hot.getSettings().minSpareRows - settings[name] - 1;

      } else {
        endpoint[name] = settings[name];

      }
    } else {
      if (defaultValue instanceof Error) {
        throw defaultValue;

      }

      endpoint[name] = defaultValue;
    }
  }

  /**
   * Do the math for a single endpoint
   * @param endpoint
   */
  calculate(endpoint) {
    switch (endpoint.type.toLowerCase()) {
      case 'sum':
        endpoint.result = this.calculateSum(endpoint);
        break;
      case 'min':
        endpoint.result = this.calculateMinMax(endpoint, endpoint.type);
        break;
      case 'max':
        endpoint.result = this.calculateMinMax(endpoint, endpoint.type);
        break;
      case 'count':
        endpoint.result = this.countEntries(endpoint);
        break;
      case 'average':
        endpoint.result = this.calculateAverage(endpoint);
        break;
      case 'custom':
        endpoint.result = endpoint.customFunction.call(this, endpoint);
        break;
    }
  }

  /**
   * Calculate and refresh all defined endpoints
   */
  refreshAllEndpoints(init) {
    for (var i = 0; i < this.endpoints.length; i++) {
      this.currentEndpoint = this.endpoints[i];
      this.calculate(this.endpoints[i]);
      this.setEndpointValue(this.endpoints[i], 'init');
    }
    this.currentEndpoint = null;
  }

  /**
   * Calculate and refresh endpoints only in the changed columns
   * @param changes
   */
  refreshChangedEndpoints(changes) {
    let needToRefresh = [];

    for (var i = 0, changesCount = changes.length; i < changesCount; i++) {
      for (var j = 0, endpointsCount = this.endpoints.length; j < endpointsCount; j++) {
        if (changes[i][1] === this.endpoints[j].sourceColumn && needToRefresh.indexOf(j) === -1) {
          needToRefresh.push(j);
        }
      }
    }

    for (var i = 0, refreshListCount = needToRefresh.length; i < refreshListCount; i++) {
      this.refreshEndpoint(this.endpoints[needToRefresh[i]]);
    }
  }

  /**
   * Calculate and refresh a single endpoint
   * @param endpoint
   */
  refreshEndpoint(endpoint) {
    this.currentEndpoint = endpoint;<commit_msg>update plugin to skip empty changes<commit_after>import BasePlugin from './../_base.js';
import {registerPlugin, getPlugin} from './../../plugins.js';

/**
 * @class ColumnSummary
 * @plugin
 *
 *
 */
class ColumnSummary extends BasePlugin {
  constructor(hotInstance) {
    super(hotInstance);

    if (!this.hot.getSettings().columnSummary) {
      return;
    }

    this.endpoints = [];
    this.settings = null;
    this.currentEndpoint = null;

    this.init();
  }

  init() {
    this.settings = this.hot.getSettings().columnSummary;

    this.bindHooks();
  }

  bindHooks() {
    let _this = this;

    this.hot.addHook('afterInit', function() {
      _this.parseSettings(_this.settings);
      _this.refreshAllEndpoints(true);
    });

    this.hot.addHook('afterChange', function(changes, source) {
      if (changes && source !== 'columnSummary' && source !== 'loadData') {
        _this.refreshChangedEndpoints(changes);
      }
    });
  }

  parseSettings() {
    for (var s in this.settings) {
      if (this.settings.hasOwnProperty(s)) {
        let newEndpoint = {};

        this.assignSetting(this.settings[s], newEndpoint, 'ranges', [[0, this.hot.countRows() - 1]]);
        this.assignSetting(this.settings[s], newEndpoint, 'reversedRowCoords', false);
        this.assignSetting(this.settings[s], newEndpoint, 'destinationRow', new Error('You must provide a destination row for the Column Summary plugin in order to work properly!'));
        this.assignSetting(this.settings[s], newEndpoint, 'destinationColumn', new Error('You must provide a destination column for the Column Summary plugin in order to work properly!'));
        this.assignSetting(this.settings[s], newEndpoint, 'sourceColumn', this.settings[s].destinationColumn);
        this.assignSetting(this.settings[s], newEndpoint, 'type', 'sum');
        this.assignSetting(this.settings[s], newEndpoint, 'forceNumeric', false);
        this.assignSetting(this.settings[s], newEndpoint, 'suppressDataTypeErrors', true);
        this.assignSetting(this.settings[s], newEndpoint, 'suppressDataTypeErrors', true);
        this.assignSetting(this.settings[s], newEndpoint, 'customFunction', null);
        this.assignSetting(this.settings[s], newEndpoint, 'readOnly', true);
        this.assignSetting(this.settings[s], newEndpoint, 'roundFloat', false);

        this.endpoints.push(newEndpoint);
      }
    }
  }

  assignSetting(settings, endpoint, name, defaultValue) {
    if (name === 'ranges' && settings[name] === void 0) {
      endpoint[name] = defaultValue;
      return;
    } else if (name === 'ranges' && settings[name].length === 0) {
      return;
    }

    if (settings[name] !== void 0) {
      if (name === 'destinationRow' && endpoint.reversedRowCoords) {
        endpoint[name] = this.hot.countRows() + this.hot.getSettings().minSpareRows - settings[name] - 1;

      } else {
        endpoint[name] = settings[name];

      }
    } else {
      if (defaultValue instanceof Error) {
        throw defaultValue;

      }

      endpoint[name] = defaultValue;
    }
  }

  /**
   * Do the math for a single endpoint
   * @param endpoint
   */
  calculate(endpoint) {
    switch (endpoint.type.toLowerCase()) {
      case 'sum':
        endpoint.result = this.calculateSum(endpoint);
        break;
      case 'min':
        endpoint.result = this.calculateMinMax(endpoint, endpoint.type);
        break;
      case 'max':
        endpoint.result = this.calculateMinMax(endpoint, endpoint.type);
        break;
      case 'count':
        endpoint.result = this.countEntries(endpoint);
        break;
      case 'average':
        endpoint.result = this.calculateAverage(endpoint);
        break;
      case 'custom':
        endpoint.result = endpoint.customFunction.call(this, endpoint);
        break;
    }
  }

  /**
   * Calculate and refresh all defined endpoints
   */
  refreshAllEndpoints(init) {
    for (var i = 0; i < this.endpoints.length; i++) {
      this.currentEndpoint = this.endpoints[i];
      this.calculate(this.endpoints[i]);
      this.setEndpointValue(this.endpoints[i], 'init');
    }
    this.currentEndpoint = null;
  }

  /**
   * Calculate and refresh endpoints only in the changed columns
   * @param changes
   */
  refreshChangedEndpoints(changes) {
    let needToRefresh = [];

    for (var i = 0, changesCount = changes.length; i < changesCount; i++) {

      // if nothing changed, dont update anything
      if((changes[i][2] || '') + '' === changes[i][3] + '') {
        continue;
      }

      for (var j = 0, endpointsCount = this.endpoints.length; j < endpointsCount; j++) {
        if (changes[i][1] === this.endpoints[j].sourceColumn && needToRefresh.indexOf(j) === -1) {
          needToRefresh.push(j);
        }
      }
    }

    for (var i = 0, refreshListCount = needToRefresh.length; i < refreshListCount; i++) {
      this.refreshEndpoint(this.endpoints[needToRefresh[i]]);
    }
  }

  /**
   * Calculate and refresh a single endpoint
   * @param endpoint
   */
  refreshEndpoint(endpoint) {
    this.currentEndpoint = endpoint;
{'fraction_non_alphanumeric': 0.14120115918856802, 'fraction_numerical': 0.002598181273108824, 'mean_word_length': 2.9526066350710902, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4812516', 'n_tokens_mistral': 2978, 'n_tokens_neox': 2899, 'n_words': 637}