<commit_before>Model.Model = function() {}

Model.Model.prototype = {
  attr: function(name, value) {
    if (arguments.length === 0) {
      // Combined attributes/changes object.
      return Model.Utils.extend({}, this.attributes, this.changes);
    } else if (arguments.length === 2) {
      // Don't write to attributes yet, store in changes for now.
      if (this.attributes[name] === value) {
        // Clean up any stale changes.
        delete this.changes[name];
      } else {
        this.changes[name] = value;
      }
      return this;
    } else if (typeof name === "object") {
      // Mass-assign attributes.
      for (var key in name) {
        this.attr(key, name[key]);
      }
      return this;
    } else {
      // Changes take precedent over attributes.
      return (name in this.changes) ?
        this.changes[name] :
        this.attributes[name];
    }
  },

  destroy: function(callback) {
    var self = this

    this.constructor.persistence().destroy(this, function(success) {
      if (success) {
        self.constructor.remove(self)
        self.trigger("destroy")
      }

      if (callback) callback.apply(this, arguments)
    })

    return this;
  },

  id: function() {
    return this.attributes[this.constructor.unique_key];
  },

  merge: function(attributes) {
    Model.Utils.extend(this.attributes, attributes);
    return this;
  },

  newRecord: function() {
    return this.constructor.persistence().newRecord(this)
  },

  reset: function() {
    this.errors.clear();
    this.changes = {};
    return this;
  },

  save: function(callback) {
    if (this.valid()) {
      var self = this

      this.constructor.persistence().save(this, function(success) {
        if (success) {
          self.merge(self.changes).reset()
          self.constructor.add(self)
          self.trigger("save")
        }

        if (callback) callback.apply(self, arguments)
      })
    } else if (callback) {
      callback(false);
    }

    return this;
  },

  toJSON: function() {
    return this.attr()
  },

  valid: function() {
    this.errors.clear();
    this.validate();
    return this.errors.size() === 0;
  },

  validate: function() {
    return this;
  }
};

Model.Utils.extend(Model.Model.prototype, Model.Callbacks)
<commit_msg>Keep the public API to a minimum.<commit_after>Model.Model = function() {}

Model.Model.prototype = {
  attr: function(name, value) {
    if (arguments.length === 0) {
      // Combined attributes/changes object.
      return Model.Utils.extend({}, this.attributes, this.changes);
    } else if (arguments.length === 2) {
      // Don't write to attributes yet, store in changes for now.
      if (this.attributes[name] === value) {
        // Clean up any stale changes.
        delete this.changes[name];
      } else {
        this.changes[name] = value;
      }
      return this;
    } else if (typeof name === "object") {
      // Mass-assign attributes.
      for (var key in name) {
        this.attr(key, name[key]);
      }
      return this;
    } else {
      // Changes take precedent over attributes.
      return (name in this.changes) ?
        this.changes[name] :
        this.attributes[name];
    }
  },

  destroy: function(callback) {
    var self = this

    this.constructor.persistence().destroy(this, function(success) {
      if (success) {
        self.constructor.remove(self)
        self.trigger("destroy")
      }

      if (callback) callback.apply(this, arguments)
    })

    return this;
  },

  id: function() {
    return this.attributes[this.constructor.unique_key];
  },

  newRecord: function() {
    return this.constructor.persistence().newRecord(this)
  },

  reset: function() {
    this.errors.clear();
    this.changes = {};
    return this;
  },

  save: function(callback) {
    if (this.valid()) {
      var self = this

      this.constructor.persistence().save(this, function(success) {
        if (success) {
          Model.Utils.extend(self.attributes, self.changes)
          self.reset()
          self.constructor.add(self)
          self.trigger("save")
        }

        if (callback) callback.apply(self, arguments)
      })
    } else if (callback) {
      callback(false);
    }

    return this;
  },

  toJSON: function() {
    return this.attr()
  },

  valid: function() {
    this.errors.clear();
    this.validate();
    return this.errors.size() === 0;
  },

  validate: function() {
    return this;
  }
};

Model.Utils.extend(Model.Model.prototype, Model.Callbacks)

{'fraction_non_alphanumeric': 0.14184710561201944, 'fraction_numerical': 0.0013256738842244808, 'mean_word_length': 2.2947598253275108, 'pattern_counts': {'":': 0, '<': 3, '<?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': '465695', 'n_tokens_mistral': 1365, 'n_tokens_neox': 1327, 'n_words': 304}