text:
/*jslint sloppy:true*/
/*global define*/

define([
//>>includeStart('strict', pragmas.strict);
    'Utils/lang/isObject',
    'Utils/lang/isFunction',
    'Utils/lang/isArray',
    'Utils/lang/isString',
    'Utils/lang/bind',
    'Utils/array/intersection',
    'Utils/array/unique',
    'Utils/array/compact',
    'Utils/object/mixIn',
    'Utils/object/keys',
    'Utils/object/forOwn',
    './common/checkKeywords',
    './common/addMethod',
    './common/isFunctionCompatible',
//>>includeEnd('strict');
    'Utils/object/hasOwn',
    'Utils/lang/toArray'
], function (
//>>includeStart('strict', pragmas.strict);
    isObject,
    isFunction,
    isArray,
    isString,
    bind,
    intersection,
    unique,
    compact,
    mixIn,
    keys,
    forOwn,
    checkKeywords,
    addMethod,
    isFunctionCompatible,
//>>includeEnd('strict');
    hasOwn,
    toArray
) {

//>>includeStart('strict', pragmas.strict);
    /**
     * Checks if an interface is well implemented in a class.
     * In order to this function to work, it must be bound to an interface definition.
     *
     * @param {Function} target The class to be checked
     */
    function checkClass(target) {

        // Check normal functions
        forOwn(this.$interface.methods, function (value, k) {
            if (!target.$class.methods[k]) {
                throw new Error('Class "' + target.prototype.Name + '" does not implement interface "' + this.prototype.Name + '" correctly, method "' + k + '" was not found.');
            }
            if (!isFunctionCompatible(target.$class.methods[k], value)) {
                throw new Error('Method "' + k + '(' + target.$class.methods[k].signature + ')" defined in class "' + target.prototype.Name + '" is not compatible with the one found in interface "' + this.prototype.Name + '": "' + k + '(' + value.signature + ').');
            }
        }, this);

        // Check static functions
        forOwn(this.$interface.staticMethods, function (value, k) {
            if (!target.$class.staticMethods[k]) {
                throw new Error('Class "' + target.prototype.Name + '" does not implement interface "' + this.prototype.Name + '" correctly, static method "' + k + '" was not found.');
            }
            if (!isFunctionCompatible(target.$class.staticMethods[k], value)) {
                throw new Error('Static method "' + k + '(' + target.$class.staticMethods[k].signature + ')" defined in class "' + target.prototype.Name + '" is not compatible with the one found in interface "' + this.prototype.Name + '": "' + k + '(' + value.signature + ').');
            }
        }, this);
    }

//>>includeEnd('strict');
    /**
     * Create an interface definition.
     *
     * @param {Object} params An object containing methods and properties
     *
     * @return {Function} The constructor
     */
    function Interface(params) {

//>>includeStart('strict', pragmas.strict);
        // Validate params as an object
        if (!isObject(params)) {
            throw new TypeError('Argument "params" must be an object.');
        }
        // Validate class name
        if (hasOwn(params, 'Name')) {
            if (!isString(params.Name)) {
                throw new TypeError('Abstract class name must be a string.');
            }
        } else {
            params.Name = 'Unnamed';
        }

        checkKeywords(params, 'normal');

//>>includeEnd('strict');
//>>excludeStart('strict', pragmas.strict);
        delete params.Name;
//>>excludeEnd('strict');

//>>includeStart('strict', pragmas.strict);
        var parents,
            current,
            k,
            i,
            duplicate,
            opts,
            optsStatic,
            interf = function () {
                throw new Error('Interfaces cannot be instantiated.');
            };

        interf.$interface = { parents: [], methods: {}, staticMethods: {}, check: bind(checkClass, interf) };
//>>includeEnd('strict');
//>>excludeStart('strict', pragmas.strict);
        var parents,
            k,
            interf = function () {};

        interf.$interface = { parents: [] };
//>>excludeEnd('strict');

        if (hasOwn(params, 'Extends')) {

            parents = toArray(params.Extends);
            k = parents.length;

//>>includeStart('strict', pragmas.strict);
            // Verify argument type
            if (!k && !isArray(params.Extends)) {
                throw new TypeError('Extends of "' + params.Name + '" seems to point to an nonexistent interface.');
            }
            // Verify duplicate entries
            if (k !== unique(parents).length && compact(parents).length === k) {
                throw new Error('There are duplicate entries defined in Extends of "' + params.Name + '".');
            }

//>>includeEnd('strict');
            for (k -= 1; k >= 0; k -= 1) {
//>>includeStart('strict', pragmas.strict);

                current = parents[k];

                // Check if it is a valid interface
                if (!isFunction(current) || !current.$interface) {
                    throw new TypeError('Specified interface in Extends at index ' +  k + ' of "' + params.Name + '" is not a valid interface.');
                }

                // Merge methods
                duplicate = intersection(keys(interf.$interface.methods), keys(current.$interface.methods));
                i = duplicate.length;
                if (i > 0) {
                    for (i -= 1; i >= 0; i -= 1) {
                        if (!isFunctionCompatible(interf.$interface.methods[duplicate[i]], current.$interface.methods[duplicate[i]])
                                && !isFunctionCompatible(current.$interface.methods[duplicate[i]], interf.$interface.methods[duplicate[i]])) {
                            throw new Error('Interface "' + params.Name + '" is inheriting method "' + duplicate[i] + '" from different parents with incompatible signatures.');
                        }
                    }
                }
                mixIn(interf.$interface.methods, current.$interface.methods);

                // Merge static methods
                duplicate = intersection(keys(interf.$interface.staticMethods), keys(current.$interface.staticMethods));
                i = duplicate.length;
                if (i > 0) {
                    for (i -= 1; i >= 0; i -= 1) {
                        if (!isFunctionCompatible(interf.$interface.staticMethods[duplicate[i]], current.$interface.staticMethods[duplicate[i]])
                                && !isFunctionCompatible(current.$interface.staticMethods[duplicate[i]], interf.$interface.staticMethods[duplicate[i]])) {
                            throw new Error('Interface "' + params.Name + '" is inheriting static method "' + duplicate[i] + '" from different parents with incompatible signatures.');
                        }
                    }
                }

                mixIn(interf.$interface.staticMethods, current.$interface.staticMethods);

                // Add interface to the parents
                interf.$interface.parents.push(current);
//>>includeEnd('strict');
//>>excludeStart('strict', pragmas.strict);
                // Add interface to the parents
                interf.$interface.parents.push(parents[k]);
//>>excludeEnd('strict');
            }

            delete params.Extends;
        }

//>>includeStart('strict', pragmas.strict);
        opts = { type: 'normal', defType: 'interface', defName: params.Name, isInterface: true };
        optsStatic = { type: 'static', defType: opts.defType, defName: params.Name, isInterface: true };

        // Check if the interface defines the initialize function
        if (hasOwn(params, 'initialize')) {
            throw new Error('Interface "' + params.Name + '" can\'t define the initialize method.');
        }

        forOwn(params, function (value, k) {

            if (k === 'Statics') {

                if (!isObject(params.Statics)) {
                    throw new TypeError('Statics definition of interface "' + params.Name + '" must be an object.');
                }

                checkKeywords(params.Statics, 'statics');

                forOwn(params.Statics, function (value, k) {

                    // Check if it is not a function
                    if (!isFunction(value) || value.$interface || value.$class) {
                        throw new Error('Static member "' + k + '" found in interface "' + params.Name + '" is not a function.');
                    }

                    addMethod(k, value, interf.$interface.staticMethods, optsStatic);
                });

            } else if (k !== 'Name') {

                // Check if it is not a function
                if (!isFunction(value) || value.$interface || value.$class) {
                    throw new Error('Member "' + k + '" found in interface "' + params.Name + '" is not a function.');
                }

                addMethod(k, value, interf.$interface.methods, opts);
            }
        });

        interf.prototype.Name = params.Name;

//>>includeEnd('strict');

        return interf;
    }

    return Interface;
});


text:
<?xml version="1.0" encoding="UTF-8"?>
<FindBugsFilter>

  <!-- As discussed with Mario Fusco, following field is used as a configuration mean
       and thus can't be changed to final. -->
  <Match>
    <Class name="~org\.drools\.reteoo\.beliefsystem\.jtms\.ReteJTMSBeliefSystem"/>
    <Field name="STRICT"/>
    <Bug pattern="MS_SHOULD_BE_FINAL"/>
  </Match>

</FindBugsFilter>

redpajama_set_name: RedPajamaGithub


text:
<?php

namespace atn\MainBundle\Menu;

use Knp\Menu\FactoryInterface;
use Symfony\Component\DependencyInjection\ContainerAware;

class Builder extends ContainerAware
{
    public function mainMenu(FactoryInterface $factory, array $options)
    {
        $menu = $factory->createItem('root');

        $menu->addChild('Home', array('route' => 'homepage'));

        // access services from the container!
        $em = $this->container->get('doctrine')->getManager();
        // findMostRecent and Blog are just imaginary examples
        $blog = '';

        $menu->addChild('Latest Blog Post', array(
            'route' => 'blog_show',
            'routeParameters' => array('id' => '$blog->getId()')
        ));

        // create another menu item
        $menu->addChild('About Me', array('route' => 'about'));
        // you can also add sub level's to your menu's as follows
        $menu['About Me']->addChild('Edit profile', array('route' => 'edit_profile'));

        // ... add more children

                return $menu;
    }
}


text:
JSON.stringify(String.fromCharCode(1, -11).toString())
gc();
var s = String.fromCharCode(1, -11)
assertEquals(65525, s.charCodeAt(1))


text:
require 'spec_helper'

describe IgnitionEditor::Converters::Blockquote do

  describe 'Conveter' do
    let(:input) { File.read('spec/assets/blockquote.html') }
    let(:document) { Nokogiri::HTML(input) }
    subject { IgnitionEditor.to_markdown(input) }

    it { is_expected.not_to start_with "\n\n" }
    it { is_expected.to start_with '> This is blockquote' }
    it { is_expected.to include ~<<-EOS
    ````
    This is left line blockquote
    ````
    EOS
    }
    it { is_expected.to include ~<<-EOS
    `````
    This is quotation mark blockquote
    `````
    EOS
    }

    it { is_expected.to include ~<<-EOS
    ````
    This is left line blockquote
    with break
    This is three line
    ````
    EOS
    }

  end

  describe 'Renderer' do
    let(:input) { File.read('spec/assets/blockquote.md') }
    let(:renderer) { Redcarpet::Render::IgnitionHTML.new() }
    let(:markdown) { Redcarpet::Markdown.new(renderer) }
    subject { markdown.render(input) }
    it { is_expected.to include ~<<-EOS

This is left-line blockquote

This is quotation-mark blockquote

    EOS
    }

    it { is_expected.to include ~<<-EOS

    This is normal blockquote

    EOS
    }

    it { is_expected.to include ~<<-EOS

 THE MAN WHO TURNED INTO A BUOY
    This is mixed block

    EOS
    }

    it { is_expected.to include ~<<-EOS

This is quotation mark blockquote

    with Break

    This is three line

    EOS
    }

  end
end


text:
namespace fileapi {

class MTPDeviceAsyncDelegate;

// This class provides media transfer protocol (MTP) device delegate to
// complete media file system operations. ScopedMTPDeviceMapEntry class
// manages the device map entries.
class WEBKIT_STORAGE_EXPORT MTPDeviceMapService {
 public:
  static MTPDeviceMapService* GetInstance();

  /////////////////////////////////////////////////////////////////////////////
  //   Following methods are used to manage MTPDeviceAsyncDelegate objects.  //
  /////////////////////////////////////////////////////////////////////////////
  // Adds the MTP device delegate to the map service. |device_location|
  // specifies the mount location of the MTP device.
  // Called on the IO thread.
  void AddAsyncDelegate(const base::FilePath::StringType& device_location,
                        MTPDeviceAsyncDelegate* delegate);

  // Removes the MTP device delegate from the map service. |device_location|
  // specifies the mount location of the MTP device.
  // Called on the IO thread.
  void RemoveAsyncDelegate(const base::FilePath::StringType& device_location);

  // Gets the media device delegate associated with |filesystem_id|.
  // Return NULL if the |filesystem_id| is no longer valid (e.g. because the
  // corresponding device is detached, etc).
  // Called on the IO thread.
  MTPDeviceAsyncDelegate* GetMTPDeviceAsyncDelegate(
      const std::string& filesystem_id);

 private:
  friend struct base::DefaultLazyInstanceTraits<MTPDeviceMapService>;

  // Mapping of device_location and MTPDeviceAsyncDelegate* object. It is safe
  // to store and access the raw pointer. This class operates on the IO thread.
  typedef std::map<base::FilePath::StringType, MTPDeviceAsyncDelegate*>
      AsyncDelegateMap;

  // Get access to this class using GetInstance() method.
  MTPDeviceMapService();
  ~MTPDeviceMapService();

  /////////////////////////////////////////////////////////////////////////////
  // Following member variables are used to manage asynchronous              //
  // MTP device delegate objects.                                            //
  /////////////////////////////////////////////////////////////////////////////
  // Map of attached mtp device async delegates.
  AsyncDelegateMap async_delegate_map_;
  base::ThreadChecker thread_checker_;

  DISALLOW_COPY_AND_ASSIGN(MTPDeviceMapService);
};

}  // namespace fileapi

#endif  // WEBKIT_FILEAPI_MEDIA_MTP_DEVICE_MAP_SERVICE_H_


text:
angular.module('ssAuth').controller('HomeCtrl', ['$scope', '$location',
    '$http', '$routeParams', '$window',
    function($scope, $location, $http, $routeParams, $window) {

    }]);


text:
/**
 * @ngdoc directive
 * @restrict A
 * @name collectionRepeat
 * @module ionic
 * @codepen 7ec1ec58f2489ab8f359fa1a0fe89c15
 * @description
 * `collection-repeat` allows an app to show huge lists of items much more performantly than
 * `ng-repeat`.
 *
 * It renders into the DOM only as many items as are currently visible.
 *
 * This means that on a phone screen that can fit eight items, only the eight items matching
 * the current scroll position will be rendered.
 *
 * **The Basics**:
 *
 * - The data given to collection-repeat must be an array.
 * - If the `item-height` and `item-width` attributes are not supplied, it will be assumed that
 *   every item in the list has the same dimensions as the first item.
 * - Don't use angular one-time binding (`::`) with collection-repeat. The scope of each item is
 *   assigned new data and re-digested as you scroll. Bindings need to update, and one-time bindings
 *   won't.
 *
 * **Performance Tips**:
 *
 * - The iOS webview has a performance bottleneck when switching out `<img src>` attributes.
 *   To increase performance of images on iOS, cache your images in advance and,
 *   if possible, lower the number of unique images. We're working on [a solution](https://github.com/driftyco/ionic/issues/3194).
 *
 * @usage
 * #### Basic Item List ([codepen](http://codepen.io/ionic/pen/0c2c35a34a8b18ad4d793fef0b081693))
 * ```html
 * <ion-content>
 *   <ion-item collection-repeat="item in items">
 *     {% raw %}{{item}}{% endraw %}
 *   </ion-item>
 * </ion-content>
 * ```
 *
 * #### Grid of Images ([codepen](http://codepen.io/ionic/pen/5515d4efd9d66f780e96787387f41664))
 * ```html
 * <ion-content>
 *   <img collection-repeat="photo in photos"
 *     item-width="33%"
 *     item-height="200px"
 *     ng-src="{% raw %}{{photo.url}}{% endraw %}">
 * </ion-content>
 * ```
 *
 * #### Horizontal Scroller, Dynamic Item Width ([codepen](http://codepen.io/ionic/pen/67cc56b349124a349acb57a0740e030e))
 * ```html
 * <ion-content>
 *   <h2>Available Kittens:</h2>
 *   <ion-scroll direction="x" class="available-scroller">
 *     <div class="photo" collection-repeat="photo in main.photos"
 *        item-height="250" item-width="photo.width + 30">
 *        <img ng-src="{{photo.src}}">
 *     </div>
 *   </ion-scroll>
 * </ion-content>
 * ```
 *
 * @param {expression} collection-repeat The expression indicating how to enumerate a collection,
 *   of the format  `variable in expression` – where variable is the user defined loop variable
 *   and `expression` is a scope expression giving the collection to enumerate.
 *   For example: `album in artist.albums` or `album in artist.albums | orderBy:'name'`.
 * @param {expression=} item-width The width of the repeated element. The expression must return
 *   a number (pixels) or a percentage. Defaults to the width of the first item in the list.
 *   (previously named collection-item-width)
 * @param {expression=} item-height The height of the repeated element. The expression must return
 *   a number (pixels) or a percentage. Defaults to the height of the first item in the list.
 *   (previously named collection-item-height)
 * @param {number=} item-render-buffer The number of items to load before and after the visible
 *   items in the list. Default 3. Tip: set this higher if you have lots of images to preload, but
 *   don't set it too high or you'll see performance loss.
 * @param {boolean=} force-refresh-images Force images to refresh as you scroll. This fixes a problem
 *   where, when an element is interchanged as scrolling, its image will still have the old src
 *   while the new src loads. Setting this to true comes with a small performance loss.
 */

IonicModule
.directive('collectionRepeat', CollectionRepeatDirective)
.factory('$ionicCollectionManager', RepeatManagerFactory);

var ONE_PX_TRANSPARENT_IMG_SRC = 'data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7';
var WIDTH_HEIGHT_REGEX = /height:.*?px;\s*width:.*?px/;
var DEFAULT_RENDER_BUFFER = 3;

CollectionRepeatDirective.$inject = ['$ionicCollectionManager', '$parse', '$window', '$$rAF', '$rootScope', '$timeout'];
function CollectionRepeatDirective($ionicCollectionManager, $parse, $window, $$rAF, $rootScope, $timeout) {
  return {
    restrict: 'A',
    priority: 1000,
    transclude: 'element',
    $$tlb: true,
    require: '^^$ionicScroll',
    link: postLink
  };

  function postLink(scope, element, attr, scrollCtrl, transclude) {
    var scrollView = scrollCtrl.scrollView;
    var node = element[0];
    var containerNode = angular.element('
')[0];
    node.parentNode.replaceChild(containerNode, node);

    if (scrollView.options.scrollingX && scrollView.options.scrollingY) {
      throw new Error("collection-repeat expected a parent x or y scrollView, not " +
                      "an xy scrollView.");
    }

    var repeatExpr = attr.collectionRepeat;
    var match = repeatExpr.match(/^\s*([\s\S]+?)\s+in\s+([\s\S]+?)(?:\s+track\s+by\s+([\s\S]+?))?\s*$/);
    if (!match) {
      throw new Error("collection-repeat expected expression in form of '_item_ in " +
                      "_collection_[ track by _id_]' but got '" + attr.collectionRepeat + "'.");
    }
    var keyExpr = match[1];
    var listExpr = match[2];
    var listGetter = $parse(listExpr);
    var heightData = {};
    var widthData = {};
    var computedStyleDimensions = {};
    var data = [];
    var repeatManager;

    // attr.collectionBufferSize is deprecated
    var renderBufferExpr = attr.itemRenderBuffer || attr.collectionBufferSize;
    var renderBuffer = angular.isDefined(renderBufferExpr) ?
      parseInt(renderBufferExpr) :
      DEFAULT_RENDER_BUFFER;

    // attr.collectionItemHeight is deprecated
    var heightExpr = attr.itemHeight || attr.collectionItemHeight;
    // attr.collectionItemWidth is deprecated
    var widthExpr = attr.itemWidth || attr.collectionItemWidth;

    var afterItemsContainer = initAfterItemsContainer();

    var changeValidator = makeChangeValidator();
    initDimensions();

    // Dimensions are refreshed on resize or data change.
    scrollCtrl.$element.on('scroll.resize', refreshDimensions);

    angular.element($window).on('resize', onResize);
    var unlistenToExposeAside = $rootScope.$on('$ionicExposeAside', ionic.animationFrameThrottle(function() {
      scrollCtrl.scrollView.resize();
      onResize();
    }));
    $timeout(refreshDimensions, 0, false);

    function onResize() {
      if (changeValidator.resizeRequiresRefresh(scrollView.__clientWidth, scrollView.__clientHeight)) {
        refreshDimensions();
      }
    }

    scope.$watchCollection(listGetter, function(newValue) {
      data = newValue || (newValue = []);
      if (!angular.isArray(newValue)) {
        throw new Error("collection-repeat expected an array for '" + listExpr + "', " +
          "but got a " + typeof value);
      }
      // Wait for this digest to end before refreshing everything.
      scope.$$postDigest(function() {
        getRepeatManager().setData(data);
        if (changeValidator.dataChangeRequiresRefresh(data)) refreshDimensions();
      });
    });

    scope.$on('$destroy', function() {
      angular.element($window).off('resize', onResize);
      unlistenToExposeAside();
      scrollCtrl.$element && scrollCtrl.$element.off('scroll.resize', refreshDimensions);

      computedStyleNode && computedStyleNode.parentNode &&
        computedStyleNode.parentNode.removeChild(computedStyleNode);
      computedStyleScope && computedStyleScope.$destroy();
      computedStyleScope = computedStyleNode = null;

      repeatManager && repeatManager.destroy();
      repeatManager = null;
    });

    function makeChangeValidator() {
      var self;
      return (self = {
        dataLength: 0,
        width: 0,
        height: 0,
        // A resize triggers a refresh only if we have data, the scrollView has size,
        // and the size has changed.
        resizeRequiresRefresh: function(newWidth, newHeight) {
          var requiresRefresh = self.dataLength && newWidth && newHeight &&
            (newWidth !== self.width || newHeight !== self.height);

          self.width = newWidth;
          self.height = newHeight;

          return !!requiresRefresh;
        },
        // A change in data only triggers a refresh if the data has length, or if the data's
        // length is less than before.
        dataChangeRequiresRefresh: function(newData) {
          var requiresRefresh = newData.length > 0 || newData.length < self.dataLength;

          self.dataLength = newData.length;

          return !!requiresRefresh;
        }
      });
    }

    function getRepeatManager() {
      return repeatManager || (repeatManager = new $ionicCollectionManager({
        afterItemsNode: afterItemsContainer[0],
        containerNode: containerNode,
        heightData: heightData,
        widthData: widthData,
        forceRefreshImages: !!(isDefined(attr.forceRefreshImages) && attr.forceRefreshImages !== 'false'),
        keyExpression: keyExpr,
        renderBuffer: renderBuffer,
        scope: scope,
        scrollView: scrollCtrl.scrollView,
        transclude: transclude
      }));
    }

    function initAfterItemsContainer() {
      var container = angular.element(
        scrollView.__content.querySelector('.collection-repeat-after-container')
      );
      // Put everything in the view after the repeater into a container.
      if (!container.length) {
        var elementIsAfterRepeater = false;
        var afterNodes = [].filter.call(scrollView.__content.childNodes, function(node) {
          if (ionic.DomUtil.contains(node, containerNode)) {
            elementIsAfterRepeater = true;
            return false;
          }
          return elementIsAfterRepeater;
        });
        container = angular.element('');
        if (scrollView.options.scrollingX) {
          container.addClass('horizontal');
        }
        container.append(afterNodes);
        scrollView.__content.appendChild(container[0]);
      }
      return container;
    }

    function initDimensions() {
      //Height and width have four 'modes':
      //1) Computed Mode
      //  - Nothing is supplied, so we getComputedStyle() on one element in the list and use
      //    that width and height value for the width and height of every item. This is re-computed
      //    every resize.
      //2) Constant Mode, Static Integer
      //  - The user provides a constant number for width or height, in pixels. We parse it,
      //    store it on the `value` field, and it never changes
      //3) Constant Mode, Percent
      //  - The user provides a percent string for width or height. The getter for percent is
      //    stored on the `getValue()` field, and is re-evaluated once every resize. The result
      //    is stored on the `value` field.
      //4) Dynamic Mode
      //  - The user provides a dynamic expression for the width or height.  This is re-evaluated
      //    for every item, stored on the `.getValue()` field.
      if (heightExpr) {
        parseDimensionAttr(heightExpr, heightData);
      } else {
        heightData.computed = true;
      }
      if (widthExpr) {
        parseDimensionAttr(widthExpr, widthData);
      } else {
        widthData.computed = true;
      }
    }

    function refreshDimensions() {
      var hasData = data.length > 0;

      if (hasData && (heightData.computed || widthData.computed)) {
        computeStyleDimensions();
      }

      if (hasData && heightData.computed) {
        heightData.value = computedStyleDimensions.height;
        if (!heightData.value) {
          throw new Error('collection-repeat tried to compute the height of repeated elements "' +
            repeatExpr + '", but was unable to. Please provide the "item-height" attribute. ' +
            'http://ionicframework.com/docs/api/directive/collectionRepeat/');
        }
      } else if (!heightData.dynamic && heightData.getValue) {
        // If it's a constant with a getter (eg percent), we just refresh .value after resize
        heightData.value = heightData.getValue();
      }

      if (hasData && widthData.computed) {
        widthData.value = computedStyleDimensions.width;
        if (!widthData.value) {
          throw new Error('collection-repeat tried to compute the width of repeated elements "' +
            repeatExpr + '", but was unable to. Please provide the "item-width" attribute. ' +
            'http://ionicframework.com/docs/api/directive/collectionRepeat/');
        }
      } else if (!widthData.dynamic && widthData.getValue) {
        // If it's a constant with a getter (eg percent), we just refresh .value after resize
        widthData.value = widthData.getValue();
      }
      // Dynamic dimensions aren't updated on resize. Since they're already dynamic anyway,
      // .getValue() will be used.

      getRepeatManager().refreshLayout();
    }

    function parseDimensionAttr(attrValue, dimensionData) {
      if (!attrValue) return;

      var parsedValue;
      // Try to just parse the plain attr value
      try {
        parsedValue = $parse(attrValue);
      } catch(e) {
        // If the parse fails and the value has `px` or `%` in it, surround the attr in
        // quotes, to attempt to let the user provide a simple `attr="100%"` or `attr="100px"`
        if (attrValue.trim().match(/\d+(px|%)$/)) {
          attrValue = '"' + attrValue + '"';
        }
        parsedValue = $parse(attrValue);
      }

      var constantAttrValue = attrValue.replace(/(\'|\"|px|%)/g, '').trim();
      var isConstant = constantAttrValue.length && !/([a-zA-Z]|\$|:|\?)/.test(constantAttrValue);
      dimensionData.attrValue = attrValue;

      // If it's a constant, it's either a percent or just a constant pixel number.
      if (isConstant) {
        var intValue = parseInt(parsedValue());

        // For percents, store the percent getter on .getValue()
        if (attrValue.indexOf('%') > -1) {
          var decimalValue = intValue / 100;
          dimensionData.getValue = dimensionData === heightData ?
            function() { return Math.floor(decimalValue * scrollView.__clientHeight); } :
            function() { return Math.floor(decimalValue * scrollView.__clientWidth); };
        } else {
          // For static constants, just store the static constant.
          dimensionData.value = intValue;
        }

      } else {
        dimensionData.dynamic = true;
        dimensionData.getValue = dimensionData === heightData ?
          function heightGetter(scope, locals) {
            var result = parsedValue(scope, locals);
            if (result.charAt && result.charAt(result.length - 1) === '%') {
              return Math.floor(parseInt(result) / 100 * scrollView.__clientHeight);
            }
            return parseInt(result);
          } :
          function widthGetter(scope, locals) {
            var result = parsedValue(scope, locals);
            if (result.charAt && result.charAt(result.length - 1) === '%') {
              return Math.floor(parseInt(result) / 100 * scrollView.__clientWidth);
            }
            return parseInt(result);
          };
      }
    }

    var computedStyleNode;
    var computedStyleScope;
    function computeStyleDimensions() {
      if (!computedStyleNode) {
        transclude(computedStyleScope = scope.$new(), function(clone) {
          clone[0].removeAttribute('collection-repeat'); // remove absolute position styling
          computedStyleNode = clone[0];
        });
      }

      computedStyleScope[keyExpr] = (listGetter(scope) || [])[0];
      if (!$rootScope.$$phase) computedStyleScope.$digest();
      containerNode.appendChild(computedStyleNode);

      var style = $window.getComputedStyle(computedStyleNode);
      computedStyleDimensions.width = parseInt(style.width);
      computedStyleDimensions.height = parseInt(style.height);

      containerNode.removeChild(computedStyleNode);
    }

  }

}

RepeatManagerFactory.$inject = ['$rootScope', '$window', '$$rAF'];
function RepeatManagerFactory($rootScope, $window, $$rAF) {
  var EMPTY_DIMENSION = { primaryPos: 0, secondaryPos: 0, primarySize: 0, secondarySize: 0, rowPrimarySize: 0 };

  return function RepeatController(options) {
    var afterItemsNode = options.afterItemsNode;
    var containerNode = options.containerNode;
    var forceRefreshImages = options.forceRefreshImages;
    var heightData = options.heightData;
    var widthData = options.widthData;
    var keyExpression = options.keyExpression;
    var renderBuffer = options.renderBuffer;
    var scope = options.scope;
    var scrollView = options.scrollView;
    var transclude = options.transclude;

    var data = [];

    var getterLocals = {};
    var heightFn = heightData.getValue || function() { return heightData.value; };
    var heightGetter = function(index, value) {
      getterLocals[keyExpression] = value;
      getterLocals.$index = index;
      return heightFn(scope, getterLocals);
    };

    var widthFn = widthData.getValue || function() { return widthData.value; };
    var widthGetter = function(index, value) {
      getterLocals[keyExpression] = value;
      getterLocals.$index = index;
      return widthFn(scope, getterLocals);
    };

    var isVertical = !!scrollView.options.scrollingY;

    // We say it's a grid view if we're either dynamic or not 100% width
    var isGridView = isVertical ?
      (widthData.dynamic || widthData.value !== scrollView.__clientWidth) :
      (heightData.dynamic || heightData.value !== scrollView.__clientHeight);

    var isStaticView = !heightData.dynamic && !widthData.dynamic;

    var PRIMARY = 'PRIMARY';
    var SECONDARY = 'SECONDARY';
    var TRANSLATE_TEMPLATE_STR = isVertical ?
      'translate3d(SECONDARYpx,PRIMARYpx,0)' :
      'translate3d(PRIMARYpx,SECONDARYpx,0)';
    var WIDTH_HEIGHT_TEMPLATE_STR = isVertical ?
      'height: PRIMARYpx; width: SECONDARYpx;' :
      'height: SECONDARYpx; width: PRIMARYpx;';

    var estimatedHeight;
    var estimatedWidth;

    var repeaterBeforeSize = 0;
    var repeaterAfterSize = 0;

    var renderStartIndex = -1;
    var renderEndIndex = -1;
    var renderAfterBoundary = -1;
    var renderBeforeBoundary = -1;

    var itemsPool = [];
    var itemsLeaving = [];
    var itemsEntering = [];
    var itemsShownMap = {};
    var nextItemId = 0;

    var scrollViewSetDimensions = isVertical ?
      function() { scrollView.setDimensions(null, null, null, view.getContentSize(), true); } :
      function() { scrollView.setDimensions(null, null, view.getContentSize(), null, true); };

    // view is a mix of list/grid methods + static/dynamic methods.
    // See bottom for implementations. Available methods:
    //
    // getEstimatedPrimaryPos(i), getEstimatedSecondaryPos(i), getEstimatedIndex(scrollTop),
    // calculateDimensions(toIndex), getDimensions(index),
    // updateRenderRange(scrollTop, scrollValueEnd), onRefreshLayout(), onRefreshData()
    var view = isVertical ? new VerticalViewType() : new HorizontalViewType();
    (isGridView ? GridViewType : ListViewType).call(view);
    (isStaticView ? StaticViewType : DynamicViewType).call(view);

    var contentSizeStr = isVertical ? 'getContentHeight' : 'getContentWidth';
    var originalGetContentSize = scrollView.options[contentSizeStr];
    scrollView.options[contentSizeStr] = angular.bind(view, view.getContentSize);

    scrollView.__$callback = scrollView.__callback;
    scrollView.__callback = function(transformLeft, transformTop, zoom, wasResize) {
      var scrollValue = view.getScrollValue();
      if (renderStartIndex === -1 ||
          scrollValue + view.scrollPrimarySize > renderAfterBoundary ||
          scrollValue < renderBeforeBoundary) {
        render();
      }
      scrollView.__$callback(transformLeft, transformTop, zoom, wasResize);
    };

    var isLayoutReady = false;
    var isDataReady = false;
    this.refreshLayout = function() {
      if (data.length) {
        estimatedHeight = heightGetter(0, data[0]);
        estimatedWidth = widthGetter(0, data[0]);
      } else {
        // If we don't have any data in our array, just guess.
        estimatedHeight = 100;
        estimatedWidth = 100;
      }

      // Get the size of every element AFTER the repeater. We have to get the margin before and
      // after the first/last element to fix a browser bug with getComputedStyle() not counting
      // the first/last child's margins into height.
      var style = getComputedStyle(afterItemsNode) || {};
      var firstStyle = afterItemsNode.firstElementChild && getComputedStyle(afterItemsNode.firstElementChild) || {};
      var lastStyle = afterItemsNode.lastElementChild && getComputedStyle(afterItemsNode.lastElementChild) || {};
      repeaterAfterSize = (parseInt(style[isVertical ? 'height' : 'width']) || 0) +
        (firstStyle && parseInt(firstStyle[isVertical ? 'marginTop' : 'marginLeft']) || 0) +
        (lastStyle && parseInt(lastStyle[isVertical ? 'marginBottom' : 'marginRight']) || 0);

      // Get the offsetTop of the repeater.
      repeaterBeforeSize = 0;
      var current = containerNode;
      do {
        repeaterBeforeSize += current[isVertical ? 'offsetTop' : 'offsetLeft'];
      } while( ionic.DomUtil.contains(scrollView.__content, current = current.offsetParent) );

      var containerPrevNode = containerNode.previousElementSibling;
      var beforeStyle = containerPrevNode ? $window.getComputedStyle(containerPrevNode) : {};
      var beforeMargin = parseInt(beforeStyle[isVertical ? 'marginBottom' : 'marginRight'] || 0);

      // Because we position the collection container with position: relative, it doesn't take
      // into account where to position itself relative to the previous element's marginBottom.
      // To compensate, we translate the container up by the previous element's margin.
      containerNode.style[ionic.CSS.TRANSFORM] = TRANSLATE_TEMPLATE_STR
        .replace(PRIMARY, -beforeMargin)
        .replace(SECONDARY, 0);
      repeaterBeforeSize -= beforeMargin;

      if (!scrollView.__clientHeight || !scrollView.__clientWidth) {
        scrollView.__clientWidth = scrollView.__container.clientWidth;
        scrollView.__clientHeight = scrollView.__container.clientHeight;
      }

      (view.onRefreshLayout || angular.noop)();
      view.refreshDirection();
      scrollViewSetDimensions();

      // Create the pool of items for reuse, setting the size to (estimatedItemsOnScreen) * 2,
      // plus the size of the renderBuffer.
      if (!isLayoutReady) {
        var poolSize = Math.max(20, renderBuffer * 3);
        for (var i = 0; i < poolSize; i++) {
          itemsPool.push(new RepeatItem());
        }
      }

      isLayoutReady = true;
      if (isLayoutReady && isDataReady) {
        // If the resize or latest data change caused the scrollValue to
        // now be out of bounds, resize the scrollView.
        if (scrollView.__scrollLeft > scrollView.__maxScrollLeft ||
            scrollView.__scrollTop > scrollView.__maxScrollTop) {
          scrollView.resize();
        }
        forceRerender(true);
      }
    };

    this.setData = function(newData) {
      data = newData;
      (view.onRefreshData || angular.noop)();
      isDataReady = true;
    };

    this.destroy = function() {
      render.destroyed = true;

      itemsPool.forEach(function(item) {
        item.scope.$destroy();
        item.scope = item.element = item.node = item.images = null;
      });
      itemsPool.length = itemsEntering.length = itemsLeaving.length = 0;
      itemsShownMap = {};

      //Restore the scrollView's normal behavior and resize it to normal size.
      scrollView.options[contentSizeStr] = originalGetContentSize;
      scrollView.__callback = scrollView.__$callback;
      scrollView.resize();

      (view.onDestroy || angular.noop)();
    };

    function forceRerender() {
      return render(true);
    }
    function render(forceRerender) {
      if (render.destroyed) return;
      var i;
      var ii;
      var item;
      var dim;
      var scope;
      var scrollValue = view.getScrollValue();
      var scrollValueEnd = scrollValue + view.scrollPrimarySize;

      view.updateRenderRange(scrollValue, scrollValueEnd);

      renderStartIndex = Math.max(0, renderStartIndex - renderBuffer);
      renderEndIndex = Math.min(data.length - 1, renderEndIndex + renderBuffer);

      for (i in itemsShownMap) {
        if (i < renderStartIndex || i > renderEndIndex) {
          item = itemsShownMap[i];
          delete itemsShownMap[i];
          itemsLeaving.push(item);
          item.isShown = false;
        }
      }

      // Render indicies that aren't shown yet
      //
      // NOTE(ajoslin): this may sound crazy, but calling any other functions during this render
      // loop will often push the render time over the edge from less than one frame to over
      // one frame, causing visible jank.
      // DON'T call any other functions inside this loop unless it's vital.
      for (i = renderStartIndex; i <= renderEndIndex; i++) {
        // We only go forward with render if the index is in data, the item isn't already shown,
        // or forceRerender is on.
        if (i >= data.length || (itemsShownMap[i] && !forceRerender)) continue;

        item = itemsShownMap[i] || (itemsShownMap[i] = itemsLeaving.length ? itemsLeaving.pop() :
                                    itemsPool.length ? itemsPool.shift() :
                                    new RepeatItem());
        itemsEntering.push(item);
        item.isShown = true;

        scope = item.scope;
        scope.$index = i;
        scope[keyExpression] = data[i];
        scope.$first = (i === 0);
        scope.$last = (i === (data.length - 1));
        scope.$middle = !(scope.$first || scope.$last);
        scope.$odd = !(scope.$even = (i & 1) === 0);

        if (scope.$$disconnected) ionic.Utils.reconnectScope(item.scope);

        dim = view.getDimensions(i);
        if (item.secondaryPos !== dim.secondaryPos || item.primaryPos !== dim.primaryPos) {
          item.node.style[ionic.CSS.TRANSFORM] = TRANSLATE_TEMPLATE_STR
            .replace(PRIMARY, (item.primaryPos = dim.primaryPos))
            .replace(SECONDARY, (item.secondaryPos = dim.secondaryPos));
        }
        if (item.secondarySize !== dim.secondarySize || item.primarySize !== dim.primarySize) {
          item.node.style.cssText = item.node.style.cssText
            .replace(WIDTH_HEIGHT_REGEX, WIDTH_HEIGHT_TEMPLATE_STR
              //TODO fix item.primarySize + 1 hack
              .replace(PRIMARY, (item.primarySize = dim.primarySize) + 1)
              .replace(SECONDARY, (item.secondarySize = dim.secondarySize))
            );
        }

      }

      // If we reach the end of the list, render the afterItemsNode - this contains all the
      // elements the developer placed after the collection-repeat
      if (renderEndIndex === data.length - 1) {
        dim = view.getDimensions(data.length - 1) || EMPTY_DIMENSION;
        afterItemsNode.style[ionic.CSS.TRANSFORM] = TRANSLATE_TEMPLATE_STR
          .replace(PRIMARY, dim.primaryPos + dim.primarySize)
          .replace(SECONDARY, 0);
      }

      while (itemsLeaving.length) {
        item = itemsLeaving.pop();
        item.scope.$broadcast('$collectionRepeatLeave');
        ionic.Utils.disconnectScope(item.scope);
        itemsPool.push(item);
        item.node.style[ionic.CSS.TRANSFORM] = 'translate3d(-9999px,-9999px,0)';
        item.primaryPos = item.secondaryPos = null;
      }

      if (forceRefreshImages) {
        for (i = 0, ii = itemsEntering.length; i < ii && (item = itemsEntering[i]); i++) {
          if (!item.images) continue;
          for (var j = 0, jj = item.images.length, img; j < jj && (img = item.images[j]); j++) {
            var src = img.src;
            img.src = ONE_PX_TRANSPARENT_IMG_SRC;
            img.src = src;
          }
        }
      }
      if (forceRerender) {
        var rootScopePhase = $rootScope.$$phase;
        while (itemsEntering.length) {
          item = itemsEntering.pop();
          if (!rootScopePhase) item.scope.$digest();
        }
      } else {
        digestEnteringItems();
      }
    }

    function digestEnteringItems() {
      var item;
      if (digestEnteringItems.running) return;
      digestEnteringItems.running = true;

      $$rAF(function process() {
        var rootScopePhase = $rootScope.$$phase;
        while (itemsEntering.length) {
          item = itemsEntering.pop();
          if (item.isShown) {
            if (!rootScopePhase) item.scope.$digest();
          }
        }
        digestEnteringItems.running = false;
      });
    }

    function RepeatItem() {
      var self = this;
      this.scope = scope.$new();
      this.id = 'item' + (nextItemId++);
      transclude(this.scope, function(clone) {
        self.element = clone;
        self.element.data('$$collectionRepeatItem', self);
        // TODO destroy
        self.node = clone[0];
        // Batch style setting to lower repaints
        self.node.style[ionic.CSS.TRANSFORM] = 'translate3d(-9999px,-9999px,0)';
        self.node.style.cssText += ' height: 0px; width: 0px;';
        ionic.Utils.disconnectScope(self.scope);
        containerNode.appendChild(self.node);
        self.images = clone[0].getElementsByTagName('img');
      });
    }

    function VerticalViewType() {
      this.getItemPrimarySize = heightGetter;
      this.getItemSecondarySize = widthGetter;

      this.getScrollValue = function() {
        return Math.max(0, Math.min(scrollView.__scrollTop - repeaterBeforeSize,
          scrollView.__maxScrollTop - repeaterBeforeSize - repeaterAfterSize));
      };

      this.refreshDirection = function() {
        this.scrollPrimarySize = scrollView.__clientHeight;
        this.scrollSecondarySize = scrollView.__clientWidth;

        this.estimatedPrimarySize = estimatedHeight;
        this.estimatedSecondarySize = estimatedWidth;
        this.estimatedItemsAcross = isGridView &&
          Math.floor(scrollView.__clientWidth / estimatedWidth) ||
          1;
      };
    }
    function HorizontalViewType() {
      this.getItemPrimarySize = widthGetter;
      this.getItemSecondarySize = heightGetter;

      this.getScrollValue = function() {
        return Math.max(0, Math.min(scrollView.__scrollLeft - repeaterBeforeSize,
          scrollView.__maxScrollLeft - repeaterBeforeSize - repeaterAfterSize));
      };

      this.refreshDirection = function() {
        this.scrollPrimarySize = scrollView.__clientWidth;
        this.scrollSecondarySize = scrollView.__clientHeight;

        this.estimatedPrimarySize = estimatedWidth;
        this.estimatedSecondarySize = estimatedHeight;
        this.estimatedItemsAcross = isGridView &&
          Math.floor(scrollView.__clientHeight / estimatedHeight) ||
          1;
      };
    }

    function GridViewType() {
      this.getEstimatedSecondaryPos = function(index) {
        return (index % this.estimatedItemsAcross) * this.estimatedSecondarySize;
      };
      this.getEstimatedPrimaryPos = function(index) {
        return Math.floor(index / this.estimatedItemsAcross) * this.estimatedPrimarySize;
      };
      this.getEstimatedIndex = function(scrollValue) {
        return Math.floor(scrollValue / this.estimatedPrimarySize) *
          this.estimatedItemsAcross;
      };
    }

    function ListViewType() {
      this.getEstimatedSecondaryPos = function() {
        return 0;
      };
      this.getEstimatedPrimaryPos = function(index) {
        return index * this.estimatedPrimarySize;
      };
      this.getEstimatedIndex = function(scrollValue) {
        return Math.floor((scrollValue) / this.estimatedPrimarySize);
      };
    }

    function StaticViewType() {
      this.getContentSize = function() {
        return this.getEstimatedPrimaryPos(data.length - 1) + this.estimatedPrimarySize +
          repeaterBeforeSize + repeaterAfterSize;
      };
      // static view always returns the same object for getDimensions, to avoid memory allocation
      // while scrolling. This could be dangerous if this was a public function, but it's not.
      // Only we use it.
      var dim = {};
      this.getDimensions = function(index) {
        dim.primaryPos = this.getEstimatedPrimaryPos(index);
        dim.secondaryPos = this.getEstimatedSecondaryPos(index);
        dim.primarySize = this.estimatedPrimarySize;
        dim.secondarySize = this.estimatedSecondarySize;
        return dim;
      };
      this.updateRenderRange = function(scrollValue, scrollValueEnd) {
        renderStartIndex = Math.max(0, this.getEstimatedIndex(scrollValue));

        // Make sure the renderEndIndex takes into account all the items on the row
        renderEndIndex = Math.min(data.length - 1,
          this.getEstimatedIndex(scrollValueEnd) + this.estimatedItemsAcross - 1);

        renderBeforeBoundary = Math.max(0,
          this.getEstimatedPrimaryPos(renderStartIndex));
        renderAfterBoundary = this.getEstimatedPrimaryPos(renderEndIndex) +
          this.estimatedPrimarySize;
      };
    }

    function DynamicViewType() {
      var self = this;
      var debouncedScrollViewSetDimensions = ionic.debounce(scrollViewSetDimensions, 25, true);
      var calculateDimensions = isGridView ? calculateDimensionsGrid : calculateDimensionsList;
      var dimensionsIndex;
      var dimensions = [];

      // Get the dimensions at index. {width, height, left, top}.
      // We start with no dimensions calculated, then any time dimensions are asked for at an
      // index we calculate dimensions up to there.
      function calculateDimensionsList(toIndex) {
        var i, prevDimension, dim;
        for (i = Math.max(0, dimensionsIndex); i <= toIndex && (dim = dimensions[i]); i++) {
          prevDimension = dimensions[i - 1] || EMPTY_DIMENSION;
          dim.primarySize = self.getItemPrimarySize(i, data[i]);
          dim.secondarySize = self.scrollSecondarySize;
          dim.primaryPos = prevDimension.primaryPos + prevDimension.primarySize;
          dim.secondaryPos = 0;
        }
      }
      function calculateDimensionsGrid(toIndex) {
        var i, prevDimension, dim;
        for (i = Math.max(dimensionsIndex, 0); i <= toIndex && (dim = dimensions[i]); i++) {
          prevDimension = dimensions[i - 1] || EMPTY_DIMENSION;
          dim.secondarySize = Math.min(
            self.getItemSecondarySize(i, data[i]),
            self.scrollSecondarySize
          );
          dim.secondaryPos = prevDimension.secondaryPos + prevDimension.secondarySize;

          if (i === 0 || dim.secondaryPos + dim.secondarySize > self.scrollSecondarySize) {
            dim.secondaryPos = 0;
            dim.primarySize = self.getItemPrimarySize(i, data[i]);
            dim.primaryPos = prevDimension.primaryPos + prevDimension.rowPrimarySize;

            dim.rowStartIndex = i;
            dim.rowPrimarySize = dim.primarySize;
          } else {
            dim.primarySize = self.getItemPrimarySize(i, data[i]);
            dim.primaryPos = prevDimension.primaryPos;
            dim.rowStartIndex = prevDimension.rowStartIndex;

            dimensions[dim.rowStartIndex].rowPrimarySize = dim.rowPrimarySize = Math.max(
              dimensions[dim.rowStartIndex].rowPrimarySize,
              dim.primarySize
            );
            dim.rowPrimarySize = Math.max(dim.primarySize, dim.rowPrimarySize);
          }
        }
      }

      this.getContentSize = function() {
        var dim = dimensions[dimensionsIndex] || EMPTY_DIMENSION;
        return ((dim.primaryPos + dim.primarySize) || 0) +
          this.getEstimatedPrimaryPos(data.length - dimensionsIndex - 1) +
          repeaterBeforeSize + repeaterAfterSize;
      };
      this.onDestroy = function() {
        dimensions.length = 0;
      };

      this.onRefreshData = function() {
        var i;
        var ii;
        // Make sure dimensions has as many items as data.length.
        // This is to be sure we don't have to allocate objects while scrolling.
        for (i = dimensions.length, ii = data.length; i < ii; i++) {
          dimensions.push({});
        }
        dimensionsIndex = -1;
      };
      this.onRefreshLayout = function() {
        dimensionsIndex = -1;
      };
      this.getDimensions = function(index) {
        index = Math.min(index, data.length - 1);

        if (dimensionsIndex < index) {
          // Once we start asking for dimensions near the end of the list, go ahead and calculate
          // everything. This is to make sure when the user gets to the end of the list, the
          // scroll height of the list is 100% accurate (not estimated anymore).
          if (index > data.length * 0.9) {
            calculateDimensions(data.length - 1);
            dimensionsIndex = data.length - 1;
            scrollViewSetDimensions();
          } else {
            calculateDimensions(index);
            dimensionsIndex = index;
            debouncedScrollViewSetDimensions();
          }

        }
        return dimensions[index];
      };

      var oldRenderStartIndex = -1;
      var oldScrollValue = -1;
      this.updateRenderRange = function(scrollValue, scrollValueEnd) {
        var i;
        var len;
        var dim;

        // Calculate more dimensions than we estimate we'll need, to be sure.
        this.getDimensions( this.getEstimatedIndex(scrollValueEnd) * 2 );

        // -- Calculate renderStartIndex
        // base case: start at 0
        if (oldRenderStartIndex === -1 || scrollValue === 0) {
          i = 0;
        // scrolling down
        } else if (scrollValue >= oldScrollValue) {
          for (i = oldRenderStartIndex, len = data.length; i < len; i++) {
            if ((dim = this.getDimensions(i)) && dim.primaryPos + dim.rowPrimarySize >= scrollValue) {
              break;
            }
          }
        // scrolling up
        } else {
          for (i = oldRenderStartIndex; i >= 0; i--) {
            if ((dim = this.getDimensions(i)) && dim.primaryPos <= scrollValue) {
              // when grid view, make sure the render starts at the beginning of a row.
              i = isGridView ? dim.rowStartIndex : i;
              break;
            }
          }
        }

        renderStartIndex = Math.min(Math.max(0, i), data.length - 1);
        renderBeforeBoundary = renderStartIndex !== -1 ? this.getDimensions(renderStartIndex).primaryPos : -1;

        // -- Calculate renderEndIndex
        var lastRowDim;
        for (i = renderStartIndex + 1, len = data.length; i < len; i++) {
          if ((dim = this.getDimensions(i)) && dim.primaryPos + dim.rowPrimarySize > scrollValueEnd) {

            // Go all the way to the end of the row if we're in a grid
            if (isGridView) {
              lastRowDim = dim;
              while (i < len - 1 &&
                    (dim = this.getDimensions(i + 1)).primaryPos === lastRowDim.primaryPos) {
                i++;
              }
            }
            break;
          }
        }

        renderEndIndex = Math.min(i, data.length - 1);
        renderAfterBoundary = renderEndIndex !== -1 ?
          ((dim = this.getDimensions(renderEndIndex)).primaryPos + (dim.rowPrimarySize || dim.primarySize)) :
          -1;

        oldScrollValue = scrollValue;
        oldRenderStartIndex = renderStartIndex;
      };
    }

  };

}


text:
<?xml version="1.0" encoding="UTF-8"?>
<assembly xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/assembly-1.0.0.xsd">
	<id>package</id>

	<formats>
		<format>tar.gz</format>
	</formats>
	<includeBaseDirectory>false</includeBaseDirectory>

	<dependencySets>
		<dependencySet>
			<outputDirectory>lib</outputDirectory>
			<useProjectArtifact>true</useProjectArtifact>
			<scope>runtime</scope>
		</dependencySet>
	</dependencySets>

</assembly>


text:
<?xml version="1.0"?>
<object name="InvoiceFolder"
        meta_type="Factory-based Type Information with dynamic views"
        xmlns:i18n="http://xml.zope.org/namespaces/i18n"
        i18n:domain="plone"
        purge="True">
 <property name="title" i18n:translate="">Statements</property>
 <property name="description"></property>
 <property name="content_icon">++resource++bika.lims.images/invoice.png</property>
 <property name="content_meta_type">InvoiceFolder</property>
 <property name="product">bika.lims</property>
 <property name="factory">addInvoiceFolder</property>
 <property name="add_view_expr"></property>
 <property name="link_target"></property>
 <property name="global_allow">False</property>
 <property name="filter_content_types">True</property>
 <property name="allowed_content_types">
  <element value="InvoiceBatch"/>
 </property>
 <property name="allow_discussion">False</property>
 <property name="default_view_fallback">False</property>

 <alias from="(Default)" to="base_view"/>
 <alias from="view" to="base_view"/>

</object>


text:
<?php
namespace Cms\Form;

use Zend\InputFilter\Factory as InputFactory;
use Zend\InputFilter\InputFilter;

class TagFilter extends InputFilter
{
    public function __construct()
    {
        // self::__construct(); // parnt::__construct(); - trows and error
        $this->add(array(
            'name'     => 'tag_name',
            'required' => false,
            'filters'  => array(
                array('name' => 'StripTags'),
                array('name' => 'StringTrim'),
            ),
            'validators' => array(
                array(
                    'name'    => 'StringLength',
                    'options' => array(
                        'encoding' => 'UTF-8',
                        'min'      => 1,
                        'max'      => 128,
                    ),
                ),
            ),
        ));
    }
}


text:
#include "htslib/hts.h"

#include <errno.h>
#include <stdlib.h>
#include <string>

#include "tensorflow/core/platform/test.h"
#include "absl/strings/str_cat.h"
#include "htslib/hts_log.h"
#include "htslib/kstring.h"
#include "third_party/nucleus/io/hts_path.h"
#include "third_party/nucleus/platform/types.h"
#include "third_party/nucleus/testing/test_utils.h"
#include "third_party/nucleus/util/port.h"

using absl::StrCat;

namespace nucleus {

// This tests minimal htslib functionality.
TEST(FileTest, HtsOpen) {
  hts_set_log_level(HTS_LOG_TRACE);

  string path = GetTestData("test.fasta");
  errno = 0;
  htsFile* f = hts_open(path.c_str(), "rb");
  EXPECT_EQ(errno, 0);
  ASSERT_NE(f, nullptr);

  kstring_t str = {0, 0, nullptr};
  int n = hts_getline(f, '\n', &str);
  EXPECT_GT(n, 0);
  EXPECT_EQ(ks_len(&str), 5);
  EXPECT_EQ(ks_str(&str), string(">chrM"));
  free(str.s);

  int close_ok = hts_close(f);
  EXPECT_EQ(close_ok, 0);
}

}  // namespace nucleus


text:
title: mixed css
layout: page
favicon: red
background: gray
---

    mixed css

  This page triggershas triggered insecure CSS.

<link rel="stylesheet" href="http://{{ site.http-domain }}/resources/stylesheet.css">


text:
/********************************************************************************
*
* File CALLTEST.C
*
* Modification History:
*   Creation:   Madhu Katragadda
*********************************************************************************
*/
/* THE FILE WHERE ALL C API TESTS ARE ADDED TO THE ROOT */

#include "cintltst.h"

void addUtility(TestNode** root);
void addBreakIter(TestNode** root);
void addStandardNamesTest(TestNode **root);
void addFormatTest(TestNode** root);
void addConvert(TestNode** root);
void addCollTest(TestNode** root);
void addComplexTest(TestNode** root);
void addUDataTest(TestNode** root);
void addUTF16Test(TestNode** root);
void addUTF8Test(TestNode** root);
void addUTransTest(TestNode** root);
void addPUtilTest(TestNode** root);
void addUCharTransformTest(TestNode** root);
void addUSetTest(TestNode** root);
void addUStringPrepTest(TestNode** root);
void addIDNATest(TestNode** root);
void addHeapMutexTest(TestNode **root);
void addUTraceTest(TestNode** root);
void addURegexTest(TestNode** root);
void addUTextTest(TestNode** root);
void addUCsdetTest(TestNode** root);
void addCnvSelTest(TestNode** root);
void addUSpoofTest(TestNode** root);

void addAllTests(TestNode** root)
{
    addCnvSelTest(root);
    addUDataTest(root);
    addHeapMutexTest(root);
    addUTF16Test(root);
    addUTF8Test(root);
    addUtility(root);
    addUTraceTest(root);
    addUTextTest(root);
    addConvert(root);
    addUCharTransformTest(root);
    addStandardNamesTest(root);
    addUCsdetTest(root);
    addComplexTest(root);
    addUSetTest(root);
#if !UCONFIG_NO_IDNA
    addUStringPrepTest(root);
    addIDNATest(root);
#endif
#if !UCONFIG_NO_REGULAR_EXPRESSIONS
    addURegexTest(root);
#endif
#if !UCONFIG_NO_BREAK_ITERATION
    addBreakIter(root);
#endif
#if !UCONFIG_NO_FORMATTING
    addFormatTest(root);
#endif
#if !UCONFIG_NO_COLLATION
    addCollTest(root);
#endif
#if !UCONFIG_NO_TRANSLITERATION
    addUTransTest(root);
#endif
#if !UCONFIG_NO_REGULAR_EXPRESSIONS && !UCONFIG_NO_NORMALIZATION
    addUSpoofTest(root);
#endif
    addPUtilTest(root);
}


text:
import logging
import os
import io
from datetime import datetime
import boto3
import botocore

class LoggingController(object):
    """
    A class for logging code output and mathplotlib plots in aws s3. Only ONE
    object should be instantiated for a script for consolidated results.
    """
    def __init__(self, profile_name = 'default', s3_bucket = 'emr-related-files',s3_bucket_path='job_logs/',app_name='MyApp'):
        self.init_datetime_string = self.get_datetime_str()                     #Used to create an s3 directory so multiple scripts don't overwrite the same files
        self.s3_bucket = s3_bucket                                              # S3 Bucket to use for storage
        self.profile_name = profile_name                                        # Define IAM profile name (see: http://boto3.readthedocs.io/en/latest/guide/configuration.html)(config file located at user folder .aws directory)
        self.s3_bucket_path = s3_bucket_path                                    #The path to store the logs on your bucket (must end in a / b/c its a directory)
        self.app_name = app_name                                                #The name of your app

    def get_datetime_str(self):
        """
        Gets a formated datetime string for naming purposes.
        """
        return datetime.now().strftime("%Y%m%d.%H:%M:%S.%f")
    def get_path_for_new_log(self):
        """
        Gets path to store new log message.
        """
        return str(self.s3_bucket_path + 'unbuilt/'+ self.app_name + '&&&' + self.init_datetime_string + '/' + self.get_datetime_str())
    def log_matplotlib_plot(self,plot, format = 'png'):
        """
        Uploads matplotlib plot to an s3 bucket.

        :param plot: The plot object to upload to s3.
        :param image_name: The image name (should be unique to prevent overwrite)
        :param format: The file type to plot.savefig as.
        :return:
        """
        img_data = io.BytesIO()
        try:
            plot.savefig(img_data, format='png')
        except:
            #Some plots throw an error which is fixed by this
            fig = plot.get_figure()
            fig.savefig(img_data)

        img_data.seek(0)

        s3 = boto3.resource('s3')
        bucket = s3.Bucket(self.s3_bucket)
        path = self.get_path_for_new_log() + '.png'
        bucket.put_object(Body=img_data, ContentType='image/png', Key=path)
    def log_string(self,string):
        s3 = boto3.resource('s3')
        bucket = s3.Bucket(self.s3_bucket)
        path = self.get_path_for_new_log() + '.txt'
        bucket.put_object(Body=string, ContentType='text/plain', Key=path)


text:
jdub
====

*A damn simple JDBC wrapper. Y'know. For databases.*

Requirements
------------

* Java SE 8 or above
* Scala 2.12.x

How To Use
----------

**First**, specify Jdub as a dependency:

```xml
<dependencies>
  <dependency>
    <groupId>com.simple</groupId>
    <artifactId>jdub_${scala.major.version}</artifactId>
    <version>${jdub.version}</version>
  </dependency>
</dependencies>
```

(Don't forget to include your JDBC driver!)

**Second**, connect to a database:

```scala
val db = Database.connect("jdbc:postgresql://localhost/wait_what", "myaccount", "mypassword")
```

**Third**, run some queries:

```scala
// Query returning an optional single result.
case class GetAge(name: String) extends FlatSingleRowQuery[Int] {

  val sql = trim("""
      SELECT age /* Use C-style comments in trimmed queries */
      FROM people
      WHERE name = ?
      """)

  val values = Seq(name)

  def flatMap(row: Row) = {
    // Returns Option[Int]
    row.int(0) // 0 gets the first column
  }

}

val age = db(GetAge("Old Guy")).getOrElse(-1) // 402
```

```scala
// Query returning a Person object for each row.
case object GetPeople extends CollectionQuery[Seq, Person] {

  val sql = trim("""
      SELECT name, email, age
      FROM people
      """)

  val values = Seq()

  def map(row: Row) = {
    val name = row.string("name").get
    val email = row.string("email").getOrElse("")
    val age = row.int("age").getOrElse(0)
    Person(name, email, age)
  }

}

val person = db(GetPeople).head // Person(Coda Hale,chale@example.com,29)
```

You can also use the sql string interpolator:

```scala
class PersonQueries(val database: Database) {
  // Query returning an optional single result.
  def getAge(name: String): Option[Int] = database {
    sql"""
      SELECT age
      FROM people
      WHERE name = ${name}
    """.map { row =>
      row.int("age")
    }
  }.headOption
}

val personQueries = new PersonQueries(database)
val age = personQueries.getAge("Old Guy").getOrElse(-1) // 402
```

```scala
object PersonQueries {
  def mapper(row: Row): String = {
    Person(
      name = row.string("name").get
      email = row.string("email").getOrElse("")
      age = row.int("age").getOrElse(0)
    )
  }
}

class PersonQueries(val database: Database) {
  // Query returning Person objects for each row.
  def getPeople(): Seq[Person] = database {
    sql"""
      SELECT name, email, age
      FROM people
    """.map(PersonQueries.mapper)
  }
}

val personQueries = new PersonQueries(database)
val people = personQueries.getPeople.head // Person(Coda Hale,chale@example.com,29)
```

**Fourth**, execute some statements:

```scala
case class UpdateEmail(name: String, newEmail: String) extends Statement {
  val sql = trim("""
      UPDATE people
      SET email = ?
      WHERE name = ?
      """)
  val values = Seq(newEmail, name)
}

// Execute the statement.
db.execute(UpdateEmail("Old Guy", "oldguy@example.com"))

// Or return the number of rows updated.
val count = db.update(UpdateEmail("Old Guy", "oldguy@example.com")) // 1
```

You can also use the sql string interpolator:

```scala
object PersonQueries {
  def mapper(row: Row): String = {
    Person(
      name = row.string("name").get
      email = row.string("email").getOrElse("")
      age = row.int("age").getOrElse(0)
    )
  }
}

class PersonQueries(val database: Database) {
  // Update a Person's email
  def updateEmail(name: String, newEmail: String): Option[Person] = database {
    sql"""
      UPDATE people
      SET email = ${newEmail}
      WHERE name = ${name}
      RETURNING people.*
    """.map(PersonQueries.mapper)
  }.headOption
}

val personQueries = new PersonQueries(database)
val updatedPerson = personQueries.updateEmail("Old Guy", "oldguy@example.com")
```

**Fifth**, read up on all the details in the [Jdub tour](tour.md).

License
-------

Copyright (c) 2011-2012 Coda Hale
Copyright (c) 2012-2017 Simple Finance Technology Corp. All rights reserved.

Published under The MIT License, see [LICENSE.md](LICENSE.md)


text:
import ipaddr

from django.core.exceptions import ValidationError
from django.test import TestCase

from cyder.cydns.address_record.models import AddressRecord
from cyder.cydns.cname.models import CNAME
from cyder.cydns.ptr.models import PTR
from cyder.cydns.domain.models import Domain
from cyder.cydns.domain.models import ValidationError, _name_to_domain
from cyder.cydns.ip.models import ipv6_to_longs, Ip
from cyder.cydns.nameserver.nameserver.models import Nameserver
from cyder.cydns.reverse_domain.models import ReverseDomain
from cyder.cydns.reverse_domain.models import boot_strap_ipv6_reverse_domain
from cyder.cydns.soa.models import SOA

class DomainTests(TestCase):

    def setUp(self):
        ReverseDomain.objects.get_or_create(name="128")

    def test_remove_domain(self):
        c = Domain( name = 'com')
        c.save()
        f_c = Domain( name = 'foo.com')
        f_c.save()
        f_c.delete()
        foo = Domain( name = 'foo.com' )
        str(foo)
        foo.__repr__()

    def test_add_domain(self):
        c = Domain( name = 'com')
        c.save()

        f_c = Domain( name = 'foo.com')
        f_c.save()
        f_c.save()
        self.assertTrue( f_c.get_absolute_url() )
        self.assertTrue( f_c.get_edit_url() )
        self.assertTrue( f_c.get_delete_url() )
        self.assertTrue( f_c.master_domain == c)

        b_c = Domain( name = 'bar.com')
        b_c.save()
        self.assertTrue( b_c.master_domain == c)

        b_b_c = Domain( name = 'baz.bar.com')
        b_b_c.save()
        self.assertTrue( b_b_c.master_domain == b_c)

    def test_soa_validators(self):
        m = Domain( name = 'moo')
        m.save()

        f_m = Domain( name = 'foo.moo')
        f_m.save()

        n_f_m = Domain( name = 'noo.foo.moo')
        n_f_m.save()

        b_m = Domain( name = 'baz.moo')
        b_m.save()

        s = SOA( primary="ns1.foo.com", contact="asdf", comment="test")
        s.save()

        f_m.soa = s
        f_m.save()

        b_m.soa = s
        self.assertRaises(ValidationError, b_m.save)

        n_f_m = Domain.objects.get(pk=n_f_m.pk) #Refresh object
        n_f_m.soa = s
        n_f_m.save()

        m.soa = s
        m.save()

        b_m.soa = s
        b_m.save()

        m.soa = None
        self.assertRaises(ValidationError, m.save)

        s2 = SOA( primary="ns1.foo.com", contact="asdf", comment="test2")
        s2.save()

        m.soa = s2
        self.assertRaises(ValidationError, m.save)

    def test_2_soa_validators(self):
        s1, _ = SOA.objects.get_or_create(primary = "ns1.foo.gaz", contact = "hostmaster.foo", comment="foo.gaz2")
        d, _ = Domain.objects.get_or_create(name="gaz")
        d.soa = None
        d.save()
        d1, _ = Domain.objects.get_or_create(name="foo.gaz")
        d1.soa = s1
        d1.save()

    def test_3_soa_validators(self):
        s1, _ = SOA.objects.get_or_create(primary = "ns1.foo2.gaz", contact = "hostmaster.foo", comment="foo.gaz2")

        r, _ = ReverseDomain.objects.get_or_create(name='9')
        r.soa = s1
        r.save()

        d, _ = Domain.objects.get_or_create(name="gaz")
        d.soa = s1
        self.assertRaises(ValidationError, d.save)

    def test__name_to_master_domain(self):
        try:
            Domain( name = 'foo.cn' ).save()
        except ValidationError, e:
            pass
        self.assertEqual( ValidationError, type(e))
        str(e)
        e = None

        Domain( name = 'cn' ).save()
        d = Domain( name = 'foo.cn')
        d.save()
        d = Domain( name = 'foo.cn')
        self.assertRaises(ValidationError, d.save)

    def test_create_domain(self):
        edu = Domain( name = 'edu')
        Domain( name = 'oregonstate.edu' )
        try:
            Domain( name = 'foo.bar.oregonstate.edu' ).save()
        except ValidationError, e:
            pass
        self.assertEqual( ValidationError, type(e))
        e = None

    def test_remove_has_child_domain(self):
        Domain( name = 'com').save()
        f_c = Domain( name = 'foo.com')
        f_c.save()
        Domain( name = 'boo.foo.com').save()
        self.assertRaises(ValidationError, f_c.delete)

    def test_invalid_add(self):

        bad = "asfda.as df"
        dom = Domain( name = bad )
        self.assertRaises(ValidationError, dom.save)

        bad = "."
        dom = Domain( name = bad )
        self.assertRaises(ValidationError, dom.save)

        bad = "edu. "
        dom = Domain( name = bad )
        self.assertRaises(ValidationError, dom.save)

        bad = ""
        dom = Domain( name = bad )
        self.assertRaises(ValidationError, dom.save)

        bad = "!@#$"
        dom = Domain( name = bad )
        self.assertRaises(ValidationError, dom.save)

    def test_remove_has_child_records(self):
        pass
        # Make sure deleting a domain doesn't leave stuff hanging.
        # TODO A records, Mx, TXT... all of the records!!

    def test_delegation_add_domain(self):
        name = "boom1"
        dom = Domain( name = name, delegated=True )
        dom.save()

        name = "boom.boom1"
        dom = Domain( name = name, delegated=False )
        self.assertRaises(ValidationError, dom.save)

    def test_delegation(self):
        name = "boom"
        dom = Domain( name = name, delegated=True )
        dom.save()

        # Creating objects in the domain should be locked.
        arec = AddressRecord(label="ns1", domain=dom, ip_str="128.193.99.9", ip_type='4')
        self.assertRaises(ValidationError, arec.save)

        ns = Nameserver(domain=dom, server="ns1."+dom.name)
        self.assertRaises(ValidationError, ns.save)

        cn = CNAME(label = "999asdf", domain = dom, data = "asdf.asdf")
        self.assertRaises(ValidationError, cn.full_clean)

        # Undelegate (unlock) the domain.
        dom.delegated = False
        dom.save()

        # Add glue and ns record.
        arec.save()
        ns.save()

        # Re delegate the domain.
        dom.delegated = True
        dom.save()

        # Creation should still be locked
        arec1 = AddressRecord(label="ns2", domain=dom, ip_str="128.193.99.9", ip_type='4')
        self.assertRaises(ValidationError, arec1.save)

        cn1 = CNAME(label = "1000asdf", domain = dom, data = "asdf.asdf")
        self.assertRaises(ValidationError, cn1.full_clean)

        # Editing should be allowed.
        arec = AddressRecord.objects.get(pk=arec.pk)
        arec.ip_str = "129.193.88.2"
        arec.save()

        # Adding new A records that have the same name as an NS should
        # be allows.
        arec1 = AddressRecord(label="ns1", domain=dom, ip_str="128.193.100.10", ip_type='4')
        arec1.save()

    def test_existing_record_new_domain(self):
        name = "bo"
        b_dom,_ = Domain.objects.get_or_create( name = name, delegated=False )

        name = "to.bo"
        t_dom,_ = Domain.objects.get_or_create( name = name, delegated=False )

        arec1 = AddressRecord(label="no", domain=t_dom, ip_str="128.193.99.9", ip_type='4')
        arec1.save()

        name = "no.to.bo"
        n_dom = Domain( name = name, delegated=False )
        self.assertRaises(ValidationError, n_dom.save)

    def test_existing_cname_new_domain(self):
        name = "bo"
        b_dom,_ = Domain.objects.get_or_create( name = name, delegated=False )

        name = "to.bo"
        t_dom,_ = Domain.objects.get_or_create( name = name, delegated=False )

        cn = CNAME(domain=t_dom, label="no", data="asdf")
        cn.full_clean()
        cn.save()

        name = "no.to.bo"
        n_dom = Domain( name = name, delegated=False )
        self.assertRaises(ValidationError, n_dom.save)

    def test_remove_domain_with_child_objects(self):
        """Removing a domain should remove CNAMES and PTR records that
        have data in that domain."""

        name = "sucks"
        a_dom,_ = Domain.objects.get_or_create( name = name, delegated=False )
        a_dom.save()

        name = "teebow.sucks"
        b_dom,_ = Domain.objects.get_or_create( name = name, delegated=False )
        b_dom.save()

        name = "adsfme"
        c_dom,_ = Domain.objects.get_or_create( name = name, delegated=False )
        c_dom.save()

        cn, _ = CNAME.objects.get_or_create(domain=c_dom, label="nddo",
                data="really.teebow.sucks")
        cn.full_clean()
        cn.save()

        ptr = PTR(ip_str="128.193.2.1", name="seriously.teebow.sucks", ip_type='4')
        ptr.full_clean()
        ptr.save()

        self.assertTrue( cn.data_domain == b_dom )
        self.assertTrue( ptr.data_domain == b_dom )

        b_dom,_ = Domain.objects.get_or_create( name = "teebow.sucks", delegated=False )
        b_dom.delete()

        try:
            cn = CNAME.objects.get(pk=cn.pk)
        except:
            self.fail("CNAME was deleted.")
        self.assertTrue(cn.data_domain == a_dom)

        try:
            ptr = PTR.objects.get(pk=ptr.pk)
        except:
            self.fail("PTR was deleted")
        self.assertTrue(ptr.data_domain == a_dom)

    def test_look_for_cnames_ptrs(self):
        name = "sucks1"
        a_dom,_ = Domain.objects.get_or_create( name = name, delegated=False )
        a_dom.save()

        name = "adsfme1"
        c_dom,_ = Domain.objects.get_or_create( name = name, delegated=False )
        c_dom.save()

        cn, _ = CNAME.objects.get_or_create(domain=c_dom, label="nddo",
                data="really.teebow.sucks1")
        cn.full_clean()
        cn.save()

        ptr = PTR(ip_str="128.193.2.1", name="seriously.teebow.sucks1", ip_type='4')
        ptr.full_clean()
        ptr.save()

        name = "teebow.sucks1"
        b_dom,_ = Domain.objects.get_or_create( name = name, delegated=False )
        b_dom.save()

        cn = CNAME.objects.get(pk=cn.pk)
        ptr = PTR.objects.get(pk=ptr.pk)
        self.assertTrue( cn.data_domain == b_dom )
        self.assertTrue( ptr.data_domain == b_dom )


text:
const uuid = require('node-uuid');
const moment = require('moment');
const config = require('nconf');

module.exports = {
    add,
    update,
    addVersionInfoToObject,
    updateVersionInfoOnObject
};

function add(req, res, next) {
    const correlationIdOptions = config.get('logging').correlationId;
    addVersionInfoToObject(req.body, req.user, req.get(correlationIdOptions.reqHeader));
    return next();
}

function addVersionInfoToObject(object, user, requestId) {
    object.versionInfo = {
        dateCreated: moment.utc().toDate(),
        versionTag: uuid.v4(),
        dateUpdated: moment.utc().toDate(),
        createdBy: user._id,
        lastUpdatedBy: user._id,
        updatedByRequestId: requestId
    };
}

function update(req, res, next) {
    const correlationIdOptions = config.get('logging').correlationId;
    updateVersionInfoOnObject(req.body, req.user, req.get(correlationIdOptions.reqHeader));
    next();
}

function updateVersionInfoOnObject(object, user, requestId) {
    object.versionInfo.versionTag = uuid.v4();
    object.versionInfo.dateUpdated = moment.utc().toDate();
    object.versionInfo.lastUpdatedBy = user._id;
    object.versionInfo.updatedByRequestId = requestId;
}


text:
/* ProgressBar
 *
 * Styling of the ProgressBar consists of the following:
 *
 * 1. the base progress bar
 *		.duiProgressBar -	sets margins for the progress bar
 *
 * 2. the empty bar
 *		.duiProgressBarEmpty  - sets background img and color for bar or parts of bar that are not finished yet
 *		Also sets border color for whole bar
 *
 * 3. tile mode
 * 		.duiProgressBarTile
 *		inner container for finished portion when in 'tile' (image) mode
 *
 * 4. full bar mode
 * 		.duiProgressBarFull
 *		adds border to right side of the filled portion of bar
 *
 * 5. text for label of  bar
 *		.duiProgressBarLabel - sets text color, which must contrast with both the "Empty" and "Full" parts.
 *
 * 6. indeterminate mode
 *		.duiProgressBarIndeterminate .duiProgressBarTile
 * 		sets animated gif for the progress bar in 'indeterminate' mode
 */
.duiProgressBar {
  z-index: 0;
  /* so z-index settings below have no effect outside of the ProgressBar */

}
.duiProgressBarEmpty {
  /* outer container and background of the bar that's not finished yet*/

  position: relative;
  overflow: hidden;
  border: 1px solid black;
  /* a11y: border necessary for high-contrast mode */

  z-index: 0;
  /* establish a stacking context for this progress bar */

}
.duiProgressBarFull {
  /* outer container for background of bar that is finished */

  position: absolute;
  overflow: hidden;
  z-index: -1;
  top: 0;
  width: 100%;
}
.duiProgressBarTile {
  /* inner container for finished portion */

  position: absolute;
  overflow: hidden;
  top: 0;
  left: 0;
  bottom: 0;
  right: 0;
  margin: 0;
  padding: 0;
  height: auto;
  background-color: #aaa;
  background-attachment: fixed;
}
.dj_a11y .duiProgressBarTile {
  /* a11y:  The border provides visibility in high-contrast mode */

  border-width: 2px;
  border-style: solid;
  background-color: transparent !important;
}
.duiProgressBarIndeterminate .duiProgressBarTile {
  /* animated gif for 'indeterminate' mode */

}
.duiProgressBarIndeterminateHighContrastImage {
  display: none;
}
.dj_a11y .duiProgressBarIndeterminate .duiProgressBarIndeterminateHighContrastImage {
  display: block;
  position: absolute;
  top: 0;
  bottom: 0;
  margin: 0;
  padding: 0;
  width: 100%;
  height: auto;
}
.duiProgressBarLabel {
  display: block;
  position: static;
  width: 100%;
  text-align: center;
  background-color: transparent !important;
}
.claro .duiProgressBar {
  margin: 2px 0 2px 0;
}
.claro .duiProgressBarEmpty {
  /* outer container and background of the bar that's not finished yet*/

  background-color: #ffffff;
  border-color: #759dc0;
}
.claro .duiProgressBarTile {
  /* inner container for finished portion when in 'tile' (image) mode */

  background-color: #abd6ff;
  background-image: url("images/progressBarFull.png");
  background-repeat: repeat-x;
  background-image: -moz-linear-gradient(rgba(255, 255, 255, 0.93) 0px, rgba(255, 255, 255, 0.41) 1px, rgba(255, 255, 255, 0.7) 2px, rgba(255, 255, 255, 0) 100%);
  background-image: -webkit-linear-gradient(rgba(255, 255, 255, 0.93) 0px, rgba(255, 255, 255, 0.41) 1px, rgba(255, 255, 255, 0.7) 2px, rgba(255, 255, 255, 0) 100%);
  background-image: -o-linear-gradient(rgba(255, 255, 255, 0.93) 0px, rgba(255, 255, 255, 0.41) 1px, rgba(255, 255, 255, 0.7) 2px, rgba(255, 255, 255, 0) 100%);
  background-image: linear-gradient(rgba(255, 255, 255, 0.93) 0px, rgba(255, 255, 255, 0.41) 1px, rgba(255, 255, 255, 0.7) 2px, rgba(255, 255, 255, 0) 100%);
  background-attachment: scroll;
}
.claro .duiProgressBarFull {
  border: 0px solid #759dc0;
  border-right-width: 1px;
  -webkit-transition-property: width;
  -moz-transition-property: width;
  transition-property: width;
  -webkit-transition-duration: 0.25s;
  -moz-transition-duration: 0.25s;
  transition-duration: 0.25s;
}
.claro .duiProgressBarLabel {
  /* Set to a color that contrasts with both the "Empty" and "Full" parts. */

  color: #000000;
}
.claro .duiProgressBarIndeterminate .duiProgressBarTile {
  /* use an animated gif for the progress bar in 'indeterminate' mode;
		background-color won't appear unless user has turned off background images */

  background: #efefef url("images/progressBarAnim.gif") repeat-x top;
}