<commit_before>;(function(exports) {
  exports.andro = {
    // Shuts down and removes ALL behaviours from passed owner object
    tearDown: function(owner) {
      if(isSetup(owner)) {
        this.eventer(owner).unbindAll();
        delete owner.andro; // remove andro from owner object
      }
    },

    // Adds the passed behaviour to the passed owner
    augment: function(owner, behaviourMixin, settings) {
      if(behaviourMixin === undefined) {
        throw "You must pass a behaviour with which to augment the owner.";
      }

      setupIfNotSetup(owner);

      var behaviour = {};
      owner.andro.behaviours.push(behaviour);
      extend(behaviour, behaviourMixin);

      // write exports to owner
      if(behaviour.setup !== undefined) {
        settings = settings || {};
        var exports = behaviour.setup(owner, owner.andro.eventer, settings);
        for(var name in exports) {
          if(owner[name] === undefined) {
            owner[name] = makeFn(exports[name], behaviour);
          }
          else {
            throw "Behaviour export would overwrite existing attribute on owner.";
          }
        }
      }
    },

    // Returns eventer obj for passed owner object
    eventer: function(owner) {
      setupIfNotSetup(owner);
      return owner.andro.eventer;
    }
  };

    // Sets up the passed owner object to use behaviours
  var setupIfNotSetup = function(owner) {
    if (!isSetup(owner)) {
      owner.andro = {};
      owner.andro.behaviours = [];
      owner.andro.eventer = new Eventer();
    }
  };

  // Returns true if owner has andro obj on it.
  var isSetup = function(owner) {
    return owner.andro !== undefined;
  };

  var extend = function(target, extensions) {
    for(var property in extensions) {
      if(extensions[property] && extensions[property].constructor &&
         extensions[property].constructor === Object) {
        target[property] = extend(target[property] || {}, extensions[property]);
      }
      else {
        target[property] = extensions[property];
      }
    }

    return target;
  };

  var makeFn = function(fn, behaviour) {
    return function() {
      return fn.apply(behaviour, arguments);
    };
  };

  function Eventer() {
    this.callbacks = {};
  }

  Eventer.prototype = {
    bind: function(obj, event, callback) {
      this.callbacks[event] = this.callbacks[event] || [];
      this.callbacks[event].push({
        obj: obj,
        callback: callback
      });

      return this;
    },

    unbind: function(obj, event) {
      for(var boundEvent in this.callbacks) {
        for(var i = 0; i < this.callbacks[boundEvent].length; i++) {
          if(this.callbacks[boundEvent][i].obj === obj) {
            this.callbacks[boundEvent].splice(i, 1);
            break;
          }<commit_msg>Fix bug where all events unbound<commit_after>;(function(exports) {
  exports.andro = {
    // Shuts down and removes ALL behaviours from passed owner object
    tearDown: function(owner) {
      if(isSetup(owner)) {
        this.eventer(owner).unbindAll();
        delete owner.andro; // remove andro from owner object
      }
    },

    // Adds the passed behaviour to the passed owner
    augment: function(owner, behaviourMixin, settings) {
      if(behaviourMixin === undefined) {
        throw "You must pass a behaviour with which to augment the owner.";
      }

      setupIfNotSetup(owner);

      var behaviour = {};
      owner.andro.behaviours.push(behaviour);
      extend(behaviour, behaviourMixin);

      // write exports to owner
      if(behaviour.setup !== undefined) {
        settings = settings || {};
        var exports = behaviour.setup(owner, owner.andro.eventer, settings);
        for(var name in exports) {
          if(owner[name] === undefined) {
            owner[name] = makeFn(exports[name], behaviour);
          }
          else {
            throw "Behaviour export would overwrite existing attribute on owner.";
          }
        }
      }
    },

    // Returns eventer obj for passed owner object
    eventer: function(owner) {
      setupIfNotSetup(owner);
      return owner.andro.eventer;
    }
  };

    // Sets up the passed owner object to use behaviours
  var setupIfNotSetup = function(owner) {
    if (!isSetup(owner)) {
      owner.andro = {};
      owner.andro.behaviours = [];
      owner.andro.eventer = new Eventer();
    }
  };

  // Returns true if owner has andro obj on it.
  var isSetup = function(owner) {
    return owner.andro !== undefined;
  };

  var extend = function(target, extensions) {
    for(var property in extensions) {
      if(extensions[property] && extensions[property].constructor &&
         extensions[property].constructor === Object) {
        target[property] = extend(target[property] || {}, extensions[property]);
      }
      else {
        target[property] = extensions[property];
      }
    }

    return target;
  };

  var makeFn = function(fn, behaviour) {
    return function() {
      return fn.apply(behaviour, arguments);
    };
  };

  function Eventer() {
    this.callbacks = {};
  }

  Eventer.prototype = {
    bind: function(obj, event, callback) {
      this.callbacks[event] = this.callbacks[event] || [];
      this.callbacks[event].push({
        obj: obj,
        callback: callback
      });

      return this;
    },

    unbind: function(obj, event) {
      for(var i = 0; i < this.callbacks[event].length; i++) {
        if(this.callbacks[event][i].obj === obj) {
          this.callbacks[event].splice(i, 1);
          break;
{'fraction_non_alphanumeric': 0.12450450450450451, 'fraction_numerical': 0.0007207207207207207, 'mean_word_length': 2.3500301750150876, 'pattern_counts': {'":': 0, '<': 5, '<?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': '428965', 'n_tokens_mistral': 1601, 'n_tokens_neox': 1551, 'n_words': 395}