text: 'use strict';
  
  /**
   * @ngdoc filter
   * @name limitTo
   * @kind function
   *
   * @description
   * Creates a new array or string containing only a specified number of elements. The elements
   * are taken from either the beginning or the end of the source array, string or number, as specified by
   * the value and sign (positive or negative) of `limit`. If a number is used as input, it is
   * converted to a string.
   *
   * @param {Array|string|number} input Source array, string or number to be limited.
   * @param {string|number} limit The length of the returned array or string. If the `limit` number
   *     is positive, `limit` number of items from the beginning of the source array/string are copied.
   *     If the number is negative, `limit` number  of items from the end of the source array/string
   *     are copied. The `limit` will be trimmed if it exceeds `array.length`
   * @returns {Array|string} A new sub-array or substring of length `limit` or less if input array
   *     had less than `limit` elements.
   *
   * @example
     <example module="limitToExample">
       <file name="index.html">
         <script>
           angular.module('limitToExample', [])
             .controller('ExampleController', ['$scope', function($scope) {
               $scope.numbers = [1,2,3,4,5,6,7,8,9];
               $scope.letters = "abcdefghi";
               $scope.longNumber = 2345432342;
               $scope.numLimit = 3;
               $scope.letterLimit = 3;
               $scope.longNumberLimit = 3;
             }]);
         </script>
         <div ng-controller="ExampleController">
           Limit {{numbers}} to: <input type="number" step="1" ng-model="numLimit">
           <p>Output numbers: {{ numbers | limitTo:numLimit }}</p>
           Limit {{letters}} to: <input type="number" step="1" ng-model="letterLimit">
           <p>Output letters: {{ letters | limitTo:letterLimit }}</p>
           Limit {{longNumber}} to: <input type="number" step="1" ng-model="longNumberLimit">
           <p>Output long number: {{ longNumber | limitTo:longNumberLimit }}</p>
         </div>
       </file>
       <file name="protractor.js" type="protractor">
         var numLimitInput = element(by.model('numLimit'));
         var letterLimitInput = element(by.model('letterLimit'));
         var longNumberLimitInput = element(by.model('longNumberLimit'));
         var limitedNumbers = element(by.binding('numbers | limitTo:numLimit'));
         var limitedLetters = element(by.binding('letters | limitTo:letterLimit'));
         var limitedLongNumber = element(by.binding('longNumber | limitTo:longNumberLimit'));
  
         it('should limit the number array to first three items', function() {
           expect(numLimitInput.getAttribute('value')).toBe('3');
           expect(letterLimitInput.getAttribute('value')).toBe('3');
           expect(longNumberLimitInput.getAttribute('value')).toBe('3');
           expect(limitedNumbers.getText()).toEqual('Output numbers: [1,2,3]');
           expect(limitedLetters.getText()).toEqual('Output letters: abc');
           expect(limitedLongNumber.getText()).toEqual('Output long number: 234');
         });
  
         // There is a bug in safari and protractor that doesn't like the minus key
         // it('should update the output when -3 is entered', function() {
         //   numLimitInput.clear();
         //   numLimitInput.sendKeys('-3');
         //   letterLimitInput.clear();
         //   letterLimitInput.sendKeys('-3');
         //   longNumberLimitInput.clear();
         //   longNumberLimitInput.sendKeys('-3');
         //   expect(limitedNumbers.getText()).toEqual('Output numbers: [7,8,9]');
         //   expect(limitedLetters.getText()).toEqual('Output letters: ghi');
         //   expect(limitedLongNumber.getText()).toEqual('Output long number: 342');
         // });
  
         it('should not exceed the maximum size of input array', function() {
           numLimitInput.clear();
           numLimitInput.sendKeys('100');
           letterLimitInput.clear();
           letterLimitInput.sendKeys('100');
           longNumberLimitInput.clear();
           longNumberLimitInput.sendKeys('100');
           expect(limitedNumbers.getText()).toEqual('Output numbers: [1,2,3,4,5,6,7,8,9]');
           expect(limitedLetters.getText()).toEqual('Output letters: abcdefghi');
           expect(limitedLongNumber.getText()).toEqual('Output long number: 2345432342');
         });
       </file>
     </example>
  */
  function limitToFilter(){
    return function(input, limit) {
      if (isNumber(input)) input = input.toString();
      if (!isArray(input) && !isString(input)) return input;
  
      if (Math.abs(Number(limit)) === Infinity) {
        limit = Number(limit);
      } else {
        limit = int(limit);
      }
  
      if (isString(input)) {
        //NaN check on limit
        if (limit) {
          return limit >= 0 ? input.slice(0, limit) : input.slice(limit, input.length);
        } else {
          return "";
        }
      }
  
      var out = [],
        i, n;
  
      // if abs(limit) exceeds maximum length, trim it
      if (limit > input.length)
        limit = input.length;
      else if (limit < -input.length)
        limit = -input.length;
  
      if (limit > 0) {
        i = 0;
        n = limit;
      } else {
        i = input.length + limit;
        n = input.length;
      }
  
      for (; i<n; i++) {
        out.push(input[i]);
      }
  
      return out;
    };
  }
  