<commit_before>/**
 * Created by <NAME> on 29.01.2016.
 */
import {IAdditionalColumnDesc} from '../../desc';
import {array_diff} from '../../internal/LineUpSelectionHelper';
import {ISelectionColumn, IContext} from '../ISelectionAdapter';
import {resolveImmediately} from 'phovea_core/src/internal/promise';

export function patchDesc(desc: IAdditionalColumnDesc, selectedId: number) {
  desc.selectedId = selectedId;
  return desc;
}

export abstract class ABaseSelectionAdapter {

  protected addDynamicColumns(context: IContext, _ids: number[], ids: string[]) {
    return Promise.all(_ids.map((_id, i) => this.createColumnsFor(context, _id, ids[i]))).then((columns) => {
      // sort new columns to insert them in the correct order
      const flattenedColumns = [].concat(...columns).map((d, i) => ({d, i}));
      flattenedColumns.sort(({d: a, i: ai}, {d: b, i: bi}) => {
        if (a.position === b.position) { // equal position, sort latter element of original array to lower position in sorted array
          return bi - ai; // the latter in the array the better
        }
        return b.position - a.position; // sort descending by default
      });
      context.add(flattenedColumns.map((d) => d.d));
    });
  }

  protected removeDynamicColumns(context: IContext, _ids: number[]): void {
    const columns = context.columns;
    context.remove([].concat(..._ids.map((_id) => {
      context.freeColor(_id);
      return columns.filter((d) => (<IAdditionalColumnDesc>d.desc).selectedId === _id);
    })));
  }

  private waitingForSelection = false;
  private waitingForParameter = false;

  selectionChanged(waitForIt: PromiseLike<any> | null, context: () => IContext) {
    if (this.waitingForSelection) {
      return;
    }
    this.waitingForSelection = true;
    resolveImmediately(waitForIt).then(() => this.selectionChangedImpl(context())).then(() => {
      this.waitingForSelection = false;
    });
  }

  parameterChanged(waitForIt: PromiseLike<any> | null, context: () => IContext) {
    if (this.waitingForSelection || this.waitingForParameter) {
      return;
    }
    this.waitingForParameter = true;
    resolveImmediately(waitForIt).then(() => this.parameterChangedImpl(context())).then(() => {
      this.waitingForParameter = false;
    });
  }

  protected abstract parameterChangedImpl(context: IContext): PromiseLike<any>;

  protected selectionChangedImpl(context: IContext) {
    const selectedIds = context.selection.range.dim(0).asList();
    const usedCols = context.columns.filter((d) => (<IAdditionalColumnDesc>d.desc).selectedId !== -1 && (<IAdditionalColumnDesc>d.desc).selectedId !== undefined);
    const lineupColIds = usedCols.map((d) => (<IAdditionalColumnDesc>d.desc).selectedId);

    // compute the difference
    const diffAdded = array_diff(selectedIds, lineupColIds);
    const diffRemoved = array_diff(lineupColIds, selectedIds);

    // remove deselected columns
    if (diffRemoved.length > 0) {
      //console.log('remove columns', diffRemoved);
      this.removeDynamicColumns(context, diffRemoved);
    }
    // add new columns to the end
    if (diffAdded.length <= 0) {
      return null;
    }
    //console.log('add columns', diffAdded);
    return context.selection.idtype.unmap(diffAdded).then((names) => this.addDynamicColumns(context, diffAdded, names));
  }
<commit_msg>try to fix duplicate column restoring<commit_after>/**
 * Created by <NAME> on 29.01.2016.
 */
import {IAdditionalColumnDesc} from '../../desc';
import {array_diff} from '../../internal/LineUpSelectionHelper';
import {ISelectionColumn, IContext} from '../ISelectionAdapter';
import {resolveImmediately} from 'phovea_core/src/internal/promise';

export function patchDesc(desc: IAdditionalColumnDesc, selectedId: number) {
  desc.selectedId = selectedId;
  return desc;
}

export abstract class ABaseSelectionAdapter {

  protected addDynamicColumns(context: IContext, _ids: number[], ids: string[]) {
    return Promise.all(_ids.map((_id, i) => this.createColumnsFor(context, _id, ids[i]))).then((columns) => {
      // sort new columns to insert them in the correct order
      const flattenedColumns = [].concat(...columns).map((d, i) => ({d, i}));
      flattenedColumns.sort(({d: a, i: ai}, {d: b, i: bi}) => {
        if (a.position === b.position) { // equal position, sort latter element of original array to lower position in sorted array
          return bi - ai; // the latter in the array the better
        }
        return b.position - a.position; // sort descending by default
      });
      context.add(flattenedColumns.map((d) => d.d));
    });
  }

  protected removeDynamicColumns(context: IContext, _ids: number[]): void {
    const columns = context.columns;
    context.remove([].concat(..._ids.map((_id) => {
      context.freeColor(_id);
      return columns.filter((d) => (<IAdditionalColumnDesc>d.desc).selectedId === _id);
    })));
  }

  private waitingForSelection = false;
  private waitingForParameter = false;

  selectionChanged(waitForIt: PromiseLike<any> | null, context: () => IContext) {
    if (this.waitingForSelection) {
      return;
    }
    this.waitingForSelection = true;
    resolveImmediately(waitForIt).then(() => this.selectionChangedImpl(context())).then(() => {
      this.waitingForSelection = false;
    });
  }

  parameterChanged(waitForIt: PromiseLike<any> | null, context: () => IContext) {
    if (this.waitingForSelection || this.waitingForParameter) {
      return;
    }
    this.waitingForParameter = true;
    resolveImmediately(waitForIt).then(() => {
      if (this.waitingForSelection) {
        return; // abort selection more important
      }
      return this.parameterChangedImpl(context());
    }).then(() => {
      this.waitingForParameter = false;
    });
  }

  protected abstract parameterChangedImpl(context: IContext): PromiseLike<any>;

  protected selectionChangedImpl(context: IContext) {
    const selectedIds = context.selection.range.dim(0).asList();
    const usedCols = context.columns.filter((d) => (<IAdditionalColumnDesc>d.desc).selectedId !== -1 && (<IAdditionalColumnDesc>d.desc).selectedId !== undefined);
    const lineupColIds = usedCols.map((d) => (<IAdditionalColumnDesc>d.desc).selectedId);

    // compute the difference
    const diffAdded = array_diff(selectedIds, lineupColIds);
    const diffRemoved = array_diff(lineupColIds, selectedIds);

    // remove deselected columns
    if (diffRemoved.length > 0) {
      //console.log('remove columns', diffRemoved);
      this.removeDynamicColumns(context, diffRemoved);
    }
    // add new columns to the end
    if (diffAdded.length <= 0) {
      return null;
    }
    //console.log('add columns', diffAdded);
    return context.selection.idtype.unmap(diffAdded).then((names) => this.addDynamicColumns(context, diffAdded, names));
  }

{'fraction_non_alphanumeric': 0.1443826799297835, 'fraction_numerical': 0.003510825043885313, 'mean_word_length': 3.734764542936288, 'pattern_counts': {'":': 0, '<': 21, '<?xml version=': 0, '>': 53, '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': '3310784', 'n_tokens_mistral': 2049, 'n_tokens_neox': 1981, 'n_words': 460}