<commit_before>interface Parameter {
  id: number;
  key: string;
  value: string;
  project_id: number;
  remove: boolean;
  changed: boolean;
}

interface Project {
  id: number;
}

declare const PROJECT_PARAMETERS: Parameter[];
declare const PROJECT: Project;

PROJECT_PARAMETERS.forEach((p) => {
  p.remove  = false;
  p.changed = false;
});

const editable_div = Vue.extend({
  template: '<div contenteditable @blur="on_blur">{{text}}</div>',
  data: () => {return {}; },
  props: {
    text: {
      twoWay: true,
      required: true,
      type: String,
    },
  },

  methods: {
    on_blur: function (e: any) { this.text = e.target.textContent; },
  },
});

Vue.component('param-tr', {
  template: '#param-tr-template',
  components: {
    'editable-div': editable_div,
  },
  data: () => {return {}; },
  props: {
    param: {
      twoWay: true,
      required: true,
      type: Object,
    },
  },

  methods: {
    remove:   function () { this.param.remove = true; },
    unremove: function () { this.param.remove = false; },
  },

  computed: {
    isNew: function () { return this.param.id === null; },
    klass: function () {
      if (this.param.remove) {
        return ['danger'];
      } else if (this.isNew) {
        return ['success'];
      } else if (this.changed) {
        return ['info'];
      }
    },
  },

  watch: {
    param: function () {
      console.log('changed!');
      this.param.changed = true;
    },
  }
});

const ProjectParamApp = new Vue({
  el: '#project-parameter-index',
  data: {
    params: PROJECT_PARAMETERS,
    project: PROJECT,
  },
  methods: {<commit_msg>bg-color for changed<commit_after>interface Parameter {
  id: number;
  key: string;
  value: string;
  project_id: number;
  remove: boolean;
  changed: boolean;
}

interface Project {
  id: number;
}

declare const PROJECT_PARAMETERS: Parameter[];
declare const PROJECT: Project;

PROJECT_PARAMETERS.forEach((p) => {
  p.remove  = false;
  p.changed = false;
});

const editable_div = Vue.extend({
  template: '<div contenteditable @blur="on_blur">{{text}}</div>',
  data: () => {return {}; },
  props: {
    text: {
      twoWay: true,
      required: true,
      type: String,
    },
  },

  methods: {
    on_blur: function (e: any) { this.text = e.target.textContent; },
  },
});

Vue.component('param-tr', {
  template: '#param-tr-template',
  components: {
    'editable-div': editable_div,
  },
  data: () => {return {}; },
  props: {
    param: {
      twoWay: true,
      required: true,
      type: Object,
    },
  },

  methods: {
    remove:   function () { this.param.remove = true; },
    unremove: function () { this.param.remove = false; },
    change:   function () { this.param.changed = true; },
  },

  computed: {
    isNew: function () { return this.param.id === null; },

    klass: function () {
      if (this.param.remove) {
        return ['danger'];
      } else if (this.isNew) {
        return ['success'];
      } else if (this.param.changed) {
        return ['info'];
      }
    },
  },

  watch: {
    "param.key":   function () { this.change(); },
    "param.value": function () { this.change(); },
  },
});

const ProjectParamApp = new Vue({
  el: '#project-parameter-index',
  data: {
    params: PROJECT_PARAMETERS,
    project: PROJECT,
  },
  methods: {
{'fraction_non_alphanumeric': 0.1731523378582202, 'fraction_numerical': 0.0, 'mean_word_length': 2.6280087527352296, 'pattern_counts': {'":': 2, '<': 7, '<?xml version=': 0, '>': 13, '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': '5696453', 'n_tokens_mistral': 1141, 'n_tokens_neox': 1127, 'n_words': 247}