<commit_before>'use strict';
var angularMeteorCollections = angular.module('angular-meteor.collections', ['angular-meteor.subscribe']);

angularMeteorCollections.factory('$collection', ['$q', 'HashKeyCopier', '$subscribe',
  function ($q, HashKeyCopier, $subscribe) {
    return function (collection, selector, options) {
      if (!selector) selector = {};
      if (!(collection instanceof Meteor.Collection)) {
        throw new TypeError("The first argument of $collection must be a Meteor.Collection object.");
      }
      return {

        bindOne: function(scope, model, id, auto, publisher) {
          Tracker.autorun(function(self) {
            scope[model] = collection.findOne(id);
            if (!scope.$root.$$phase) scope.$apply(); // Update bindings in scope.
            scope.$on('$destroy', function () {
              self.stop(); // Stop computation if scope is destroyed.
            });
          });

          if (auto) { // Deep watches the model and performs autobind.
            scope.$watch(model, function (newItem, oldItem) {
              if (newItem)
                if (newItem._id)
                  collection.update({_id: newItem._id}, { $set: _.omit(newItem, '_id') });
            }, true);
          }

          var deferred = $q.defer();

          if (publisher) {  // Subscribe to a publish method
            var publishName = null;
            if (publisher === true)
              publishName = collection._name;
            else
              publishName = publisher;

            $subscribe.subscribe(publishName).then(function(){
              deferred.resolve(scope[model]);
            });

          } else { // If no subscription, resolve immediately
            deferred.resolve(scope[model]);
          }

          return deferred.promise;
        },

        bind: function (scope, model, auto, publisher, paginate) {
          auto = auto || false; // Sets default binding type.
          if (!(typeof auto === 'boolean')) { // Checks if auto is a boolean.
            throw new TypeError("The third argument of bind must be a boolean.");
          }

          var unregisterWatch = null;

          var rebind = function(){
            Tracker.autorun(function (self) {

              if (paginate){
                options = {
                  limit: parseInt(scope.perPage),
                  skip: (parseInt(scope.page) - 1) * parseInt(scope.perPage)
                };
                if (scope.sort) { options.sort = [scope.sort]; }
              }

              var ngCollection = new AngularMeteorCollection(collection, $q, selector, options);

              // Bind collection to model in scope. Transfer $$hashKey based on _id.
              var newArray = HashKeyCopier.copyHashKeys(scope[model], ngCollection, ["_id"]);
              scope[model] = updateAngularCollection(newArray, scope[model]);

              if (!scope.$root.$$phase) scope.$apply(); // Update bindings in scope.
              scope.$on('$destroy', function () {
                self.stop(); // Stop computation if scope is destroyed.
              });
            });

            if (auto) { // Deep watches the model and performs autobind.
              unregisterWatch = scope.$watch(model, function (newItems, oldItems) {
                // Remove items that don't exist in the collection anymore.
                angular.forEach(oldItems, function (oldItem) {
                  var index = newItems.map(function (item) {
                    return item._id;
                  }).indexOf(oldItem._id);
                  if (index == -1) { // To here get all objects that pushed or spliced
                    if (oldItem._id) { // This is a check to get only the spliced objects
                      newItems.remove(oldItem._id);
                    }
                  }
                });
                newItems.save(); // Saves all items.
              }, auto);
            }
          };
          rebind();

          if (paginate){
            scope.$watch("page", function(newValue, oldValue){
              if (!newValue)
                return;

              if (newValue == oldValue)
                return;

              if (unregisterWatch)
                unregisterWatch();

              rebind();
            });
          }

          var deferred = $q.defer();

          if (publisher) {  // Subscribe to a publish method
            var publishName = null;
            if (publisher === true)
              publishName = collection._name;
            else
              publishName = publisher;

            $subscribe.subscribe(publishName).then(function(){
              deferred.resolve(scope[model]);
            });

          } else { // If no subscription, resolve immediately
            deferred.resolve(scope[model]);
          }

          return deferred.promise;
        }
      };
    }
  }
]);

var AngularMeteorCollection = function (collection, $q, selector, options) {
  var self = collection.find(selector, options).fetch();

  self.__proto__ = AngularMeteorCollection.prototype;
  self.__proto__.$q = $q;
  self.$$collection = collection;

  return self;
};

AngularMeteorCollection.prototype = []; // Allows inheritance of native Array methods.<commit_msg>Suggested new API for collection<commit_after>'use strict';
var angularMeteorCollections = angular.module('angular-meteor.collections', ['angular-meteor.subscribe']);

angularMeteorCollections.factory('$collection', ['$q', 'HashKeyCopier', '$subscribe',
  function ($q, HashKeyCopier, $subscribe) {
    return function (collection, selector, options) {
      if (!selector) selector = {};
      if (!(collection instanceof Meteor.Collection)) {
        throw new TypeError("The first argument of $collection must be a Meteor.Collection object.");
      }
      return {

        bindOne: function(scope, model, id, auto, publisher) {
          Tracker.autorun(function(self) {
            scope[model] = collection.findOne(id);
            if (!scope.$root.$$phase) scope.$apply(); // Update bindings in scope.
            scope.$on('$destroy', function () {
              self.stop(); // Stop computation if scope is destroyed.
            });
          });

          if (auto) { // Deep watches the model and performs autobind.
            scope.$watch(model, function (newItem, oldItem) {
              if (newItem)
                if (newItem._id)
                  collection.update({_id: newItem._id}, { $set: _.omit(newItem, '_id') });
            }, true);
          }

          var deferred = $q.defer();

          if (publisher) {  // Subscribe to a publish method
            var publishName = null;
            if (publisher === true)
              publishName = collection._name;
            else
              publishName = publisher;

            $subscribe.subscribe(publishName).then(function(){
              deferred.resolve(scope[model]);
            });

          } else { // If no subscription, resolve immediately
            deferred.resolve(scope[model]);
          }

          return deferred.promise;
        },

        bind: function (scope, model, auto, publisher, paginate) {
          auto = auto || false; // Sets default binding type.
          if (!(typeof auto === 'boolean')) { // Checks if auto is a boolean.
            throw new TypeError("The third argument of bind must be a boolean.");
          }

          var unregisterWatch = null;

          var rebind = function(){
            Tracker.autorun(function (self) {

              if (paginate){
                options = {
                  limit: parseInt(scope.perPage),
                  skip: (parseInt(scope.page) - 1) * parseInt(scope.perPage)
                };
                if (scope.sort) { options.sort = [scope.sort]; }
              }

              var ngCollection = new AngularMeteorCollection(collection, $q, selector, options);

              // Bind collection to model in scope. Transfer $$hashKey based on _id.
              var newArray = HashKeyCopier.copyHashKeys(scope[model], ngCollection, ["_id"]);
              scope[model] = updateAngularCollection(newArray, scope[model]);

              if (!scope.$root.$$phase) scope.$apply(); // Update bindings in scope.
              scope.$on('$destroy', function () {
                self.stop(); // Stop computation if scope is destroyed.
              });
            });

            if (auto) { // Deep watches the model and performs autobind.
              unregisterWatch = scope.$watch(model, function (newItems, oldItems) {
                // Remove items that don't exist in the collection anymore.
                angular.forEach(oldItems, function (oldItem) {
                  var index = newItems.map(function (item) {
                    return item._id;
                  }).indexOf(oldItem._id);
                  if (index == -1) { // To here get all objects that pushed or spliced
                    if (oldItem._id) { // This is a check to get only the spliced objects
                      newItems.remove(oldItem._id);
                    }
                  }
                });
                newItems.save(); // Saves all items.
              }, auto);
            }
          };
          rebind();

          if (paginate){
            scope.$watch("page", function(newValue, oldValue){
              if (!newValue)
                return;

              if (newValue == oldValue)
                return;

              if (unregisterWatch)
                unregisterWatch();

              rebind();
            });
          }

          var deferred = $q.defer();

          if (publisher) {  // Subscribe to a publish method
            var publishName = null;
            if (publisher === true)
              publishName = collection._name;
            else
              publishName = publisher;

            $subscribe.subscribe(publishName).then(function(){
              deferred.resolve(scope[model]);
            });

          } else { // If no subscription, resolve immediately
            deferred.resolve(scope[model]);
          }

          return deferred.promise;
        }
      };
    }
  }
]);

angularMeteorCollections.factory('$amCollection', function($rootScope) {
  return function(collection, selector, auto, options) {
    // Validate parameters
    auto = auto || false; // Sets default binding type.
    if (!(typeof auto === 'boolean')) { // Checks if auto is a boolean.
      throw new TypeError("The third argument of bind must be a boolean.");
    }

    // Data members
    var that = this;
    this.data = null; // Holds the collection fetch result

    /**
     * Fetches the latest data from Meteor and update the data variable.
     */
    Tracker.autorun(function (self) {
      var ngCollection = new AngularMeteorCollection(collection, $q, selector, options);

      // Optimized Update the data array variable
      var newArray = HashKeyCopier.copyHashKeys(this.data, ngCollection, ["_id"]);
      that.data = updateAngularCollection(newArray, this.data);
    });

    if (auto) { // Deep watches the model and performs autobind.
      var unregisterWatch = $rootScope.$watch(function() {
        return that.data;
      }, function (newItems, oldItems) {
        if (newItems !== oldItems && angular.isUndefined(newItems)) {
          return unregisterWatch();
        }

        // Remove items that don't exist in the collection anymore.
        angular.forEach(oldItems, function (oldItem) {
          var index = newItems.map(function (item) {
            return item._id;
          }).indexOf(oldItem._id);
          if (index == -1) { // To here get all objects that pushed or spliced
            if (oldItem._id) { // This is a check to get only the spliced objects
              newItems.remove(oldItem._id);
            }
          }
        });
        newItems.save(); // Saves all items.
      }, true);
    }

    return that.data;
  }
});

var AngularMeteorCollection = function (collection, $q, selector, options) {
  var self = collection.find(selector, options).fetch();

  self.__proto__ = AngularMeteorCollection.prototype;
  self.__proto__.$q = $q;
  self.$$collection = collection;

  return self;
};

AngularMeteorCollection.prototype = []; // Allows inheritance of native Array methods.
{'fraction_non_alphanumeric': 0.11599967529831967, 'fraction_numerical': 0.00040587710041399463, 'mean_word_length': 1.755535674345784, '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': '3503194', 'n_tokens_mistral': 3171, 'n_tokens_neox': 3011, 'n_words': 870}