<commit_before>'use strict';

Object.defineProperty(exports, '__esModule', {
  value: true
});

var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();

var _get = function get(_x, _x2, _x3) { var _again = true; _function: while (_again) { desc = parent = getter = undefined; _again = false; var object = _x,
    property = _x2,
    receiver = _x3; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x = parent; _x2 = property; _x3 = receiver; _again = true; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } };

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }

function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) subClass.__proto__ = superClass; }

var _react = require('react');

var _react2 = _interopRequireDefault(_react);

var _moment = require('moment');

var _moment2 = _interopRequireDefault(_moment);

var _CalendarUtils = require('./CalendarUtils');

var DayPicker = (function (_Component) {
  function DayPicker(props) {
    _classCallCheck(this, DayPicker);

    _get(Object.getPrototypeOf(DayPicker.prototype), 'constructor', this).call(this, props);
    this.state = {
      month: this.props.initialMonth.clone()
    };
  }

  _inherits(DayPicker, _Component);

  _createClass(DayPicker, [{
    key: 'handleDayTouchTap',
    value: function handleDayTouchTap(day, modifiers, e) {
      if (this.props.onDayTouchTap) {
        this.props.onDayTouchTap(day, modifiers, e);
      }
    }
  }, {
    key: 'handleDayClick',
    value: function handleDayClick(day, modifiers, e) {
      if (this.props.onDayClick) {
        this.props.onDayClick(day, modifiers, e);
      }
    }
  }, {
    key: 'handleDayMouseEnter',
    value: function handleDayMouseEnter(day, modifiers, e) {
      if (this.props.onDayMouseEnter) {
        this.props.onDayMouseEnter(day, modifiers, e);
      }
    }
  }, {
    key: 'handleDayMouseLeave',
    value: function handleDayMouseLeave(day, modifiers, e) {
      if (this.props.onDayMouseLeave) {
        this.props.onDayMouseLeave(day, modifiers, e);
      }
    }
  }, {
    key: 'handleNextMonthClick',
    value: function handleNextMonthClick(e) {
      var _this2 = this;

      e.persist();
      var month = this.state.month;

      var nextMonth = month.clone().add(1, 'month');
      this.setState({ month: nextMonth }, function () {
        if (_this2.props.onNextMonthClick) {
          _this2.props.onNextMonthClick(_this2.state.month, e);
        }
      });
    }
  }, {
    key: 'handlePrevMonthClick',
    value: function handlePrevMonthClick(e) {
      var _this3 = this;

      e.persist();
      var month = this.state.month;

      var prevMonth = month.clone().subtract(1, 'month');
      this.setState({ month: prevMonth }, function () {
        if (_this3.props.onPrevMonthClick) {
          _this3.props.onPrevMonthClick(_this3.state.month, e);
        }
      });
    }
  }, {
    key: 'getModifiersForDay',
    value: function getModifiersForDay(day) {
      var modifiers = this.props.modifiers;

      var dayModifiers = [];

      if (modifiers) {
        for (var modifier in modifiers) {
          var func = modifiers[modifier];

          if (func(day)) {
            dayModifiers.push(modifier);
          }
        }
      }

      return dayModifiers;
    }
  }, {
    key: 'showMonth',
    value: function showMonth(month) {
      this.setState({ month: month });
    }
  }, {
    key: 'render',
    value: function render() {
      var month = this.state.month;

      var months = [];
      for (var i = 0; i < this.props.numberOfMonths; i++) {
        months.push(this.renderMonth(month, i));
        month = month.clone().add(1, 'month');
      }

      return _react2['default'].createElement(
        'div',
        null,
        months
      );
    }
  }, {
    key: 'renderMonth',
    value: function renderMonth(month, monthIndex) {
      var isFirstMonth = month === this.state.month;
      var isLastMonth = monthIndex === this.props.numberOfMonths - 1;
      return _react2['default'].createElement(
        'table',
        { key: monthIndex, className: 'DayPicker' },
        _react2['default'].createElement(
          'caption',
          { className: 'DayPicker-caption' },
          isFirstMonth && this.renderNavButton('left'),
          month.format('MMMM YYYY'),
          isLastMonth && this.renderNavButton('right')
        ),
        _react2['default'].createElement(
          'thead',
          null,
          this.renderWeekHeader()
        ),
        _react2['default'].createElement(
          'tbody',
          null,
          this.renderWeeks(month)
        )
      );
    }
  }, {
    key: 'renderNavButton',
    value: function renderNavButton(position) {
      var className = 'DayPicker-nav DayPicker-nav--' + position;
      var handler = position === 'left' ? this.handlePrevMonthClick : this.handleNextMonthClick;

      return _react2['default'].createElement('span', { ref: 'btn-' + position, className: className,
        style: { float: position }, onClick: handler.bind(this) });
    }
  }, {
    key: 'renderWeeks',
    value: function renderWeeks(month) {
      var _this4 = this;

      return _CalendarUtils.weeks(month).map(function (week, i) {
        return _react2['default'].createElement(
          'tr',
          { key: i, className: 'DayPicker-week' },
          _this4.renderDays(week)
        );
      });
    }
  }, {
    key: 'renderWeekHeader',
    value: function renderWeekHeader() {
      var header = [];
      for (var i = 0; i < 7; i++) {
        header.push(_react2['default'].createElement(
          'th',
          { key: i, className: 'DayPicker-weekday' },
          _moment2['default']().weekday(i).format('dd')
        ));
      }

      return header;
    }
  }, {
    key: 'renderDays',
    value: function renderDays(week) {
      var _this5 = this;

      var firstDay = week[0];
      var lastDay = week[week.length - 1];

      var days = week.map(function (day) {
        return _this5.renderDay(day);
      });

      // days belonging to the previous month
      for (var i = 0; i < firstDay.weekday(); i++) {
        var prevDay = firstDay.clone().subtract(i + 1, 'day');
        days.unshift(this.renderDay(prevDay, true));
      }

      // days belonging to the next month
      for (var j = lastDay.weekday() + 1, count = 1; j < 7; j++, count++) {
        var nextDay = lastDay.clone().add(count, 'day');
        days.push(this.renderDay(nextDay, true));
      }

      return days;
    }
  }, {
    key: 'renderDay',
    value: function renderDay(day, outside) {
      var key = '' + day.dayOfYear();
      var className = 'DayPicker-day';

      if (outside) {
        className += ' DayPicker-day--outside';
      }

      if (outside && !this.props.enableOutsideDays) {
        return _react2['default'].createElement('td', { className: className, ref: key, key: key });
      } else {
        var modifiers = this.getModifiersForDay(day);
        if (outside) {
          modifiers.push('outside');
        }
        className += modifiers.map(function (mod) {
          return ' DayPicker-day--' + mod;
        }).join('');
        return _react2['default'].createElement(
          'td',
          { ref: key, key: key,
            className: className,
            onMouseEnter: this.handleDayMouseEnter.bind(this, day, modifiers),
            onMouseLeave: this.handleDayMouseLeave.bind(this, day, modifiers),
            onTouchTap: this.handleDayTouchTap.bind(this, day, modifiers),
            onClick: this.handleDayClick.bind(this, day, modifiers) },
          day.format('D')
        );
      }
    }
  }], [{
    key: 'propTypes',
    value: {

      enableOutsideDays: _react.PropTypes.bool,

      // default is current month
      initialMonth: _react.PropTypes.object,

      // default is 1
      numberOfMonths: _react.PropTypes.number,

      modifiers: _react.PropTypes.object,

      onDayClick: _react.PropTypes.func,

      // requires react-tap-event-plugin
      onDayTouchTap: _react.PropTypes.func,

      onDayMouseEnter: _react.PropTypes.func,
      onDayMouseLeave: _react.PropTypes.func,

      onNextMonthClick: _react.PropTypes.func,
      onPrevMonthClick: _react.PropTypes.func

    },
    enumerable: true
  }, {
    key: 'defaultProps',
    value: {
      initialMonth: _moment2['default'](),
      numberOfMonths: 1,
      enableOutsideDays: false
    },
    enumerable: true
  }]);

  return DayPicker;
})(_react.Component);

exports['default'] = DayPicker;
module.exports = exports['default'];<commit_msg>Updated dist<commit_after>'use strict';

Object.defineProperty(exports, '__esModule', {
  value: true
});

var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();

var _get = function get(_x, _x2, _x3) { var _again = true; _function: while (_again) { var object = _x, property = _x2, receiver = _x3; desc = parent = getter = undefined; _again = false; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x = parent; _x2 = property; _x3 = receiver; _again = true; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } };

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }

function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) subClass.__proto__ = superClass; }

var _react = require('react');

var _react2 = _interopRequireDefault(_react);

var _moment = require('moment');

var _moment2 = _interopRequireDefault(_moment);

var _CalendarUtils = require('./CalendarUtils');

var DayPicker = (function (_Component) {
  function DayPicker(props) {
    _classCallCheck(this, DayPicker);

    _get(Object.getPrototypeOf(DayPicker.prototype), 'constructor', this).call(this, props);
    this.state = {
      month: this.props.initialMonth.clone()
    };
  }

  _inherits(DayPicker, _Component);

  _createClass(DayPicker, [{
    key: 'handleDayTouchTap',
    value: function handleDayTouchTap(day, modifiers, e) {
      if (this.props.onDayTouchTap) {
        this.props.onDayTouchTap(day, modifiers, e);
      }
    }
  }, {
    key: 'handleDayClick',
    value: function handleDayClick(day, modifiers, e) {
      if (this.props.onDayClick) {
        this.props.onDayClick(day, modifiers, e);
      }
    }
  }, {
    key: 'handleDayMouseEnter',
    value: function handleDayMouseEnter(day, modifiers, e) {
      if (this.props.onDayMouseEnter) {
        this.props.onDayMouseEnter(day, modifiers, e);
      }
    }
  }, {
    key: 'handleDayMouseLeave',
    value: function handleDayMouseLeave(day, modifiers, e) {
      if (this.props.onDayMouseLeave) {
        this.props.onDayMouseLeave(day, modifiers, e);
      }
    }
  }, {
    key: 'handleNextMonthClick',
    value: function handleNextMonthClick(e) {
      var _this = this;

      e.persist();
      var month = this.state.month;

      var nextMonth = month.clone().add(1, 'month');
      this.setState({ month: nextMonth }, function () {
        if (_this.props.onNextMonthClick) {
          _this.props.onNextMonthClick(_this.state.month, e);
        }
      });
    }
  }, {
    key: 'handlePrevMonthClick',
    value: function handlePrevMonthClick(e) {
      var _this2 = this;

      e.persist();
      var month = this.state.month;

      var prevMonth = month.clone().subtract(1, 'month');
      this.setState({ month: prevMonth }, function () {
        if (_this2.props.onPrevMonthClick) {
          _this2.props.onPrevMonthClick(_this2.state.month, e);
        }
      });
    }
  }, {
    key: 'getModifiersForDay',
    value: function getModifiersForDay(day) {
      var modifiers = this.props.modifiers;

      var dayModifiers = [];

      if (modifiers) {
        for (var modifier in modifiers) {
          var func = modifiers[modifier];

          if (func(day)) {
            dayModifiers.push(modifier);
          }
        }
      }

      return dayModifiers;
    }
  }, {
    key: 'showMonth',
    value: function showMonth(month) {
      this.setState({ month: month });
    }
  }, {
    key: 'render',
    value: function render() {
      var month = this.state.month;

      var months = [];
      for (var i = 0; i < this.props.numberOfMonths; i++) {
        months.push(this.renderMonth(month, i));
        month = month.clone().add(1, 'month');
      }

      return _react2['default'].createElement(
        'div',
        { className: this.props.className, style: this.props.style },
        months
      );
    }
  }, {
    key: 'renderMonth',
    value: function renderMonth(month, monthIndex) {
      var isFirstMonth = month === this.state.month;
      var isLastMonth = monthIndex === this.props.numberOfMonths - 1;
      return _react2['default'].createElement(
        'table',
        { key: monthIndex, className: 'DayPicker' },
        _react2['default'].createElement(
          'caption',
          { className: 'DayPicker-caption' },
          isFirstMonth && this.renderNavButton('left'),
          month.format('MMMM YYYY'),
          isLastMonth && this.renderNavButton('right')
        ),
        _react2['default'].createElement(
          'thead',
          null,
          this.renderWeekHeader()
        ),
        _react2['default'].createElement(
          'tbody',
          null,
          this.renderWeeks(month)
        )
      );
    }
  }, {
    key: 'renderNavButton',
    value: function renderNavButton(position) {
      var className = 'DayPicker-nav DayPicker-nav--' + position;
      var handler = position === 'left' ? this.handlePrevMonthClick : this.handleNextMonthClick;

      return _react2['default'].createElement('span', { ref: 'btn-' + position, className: className,
        style: { float: position }, onClick: handler.bind(this) });
    }
  }, {
    key: 'renderWeeks',
    value: function renderWeeks(month) {
      var _this3 = this;

      return (0, _CalendarUtils.weeks)(month).map(function (week, i) {
        return _react2['default'].createElement(
          'tr',
          { key: i, className: 'DayPicker-week' },
          _this3.renderDays(week)
        );
      });
    }
  }, {
    key: 'renderWeekHeader',
    value: function renderWeekHeader() {
      var header = [];
      for (var i = 0; i < 7; i++) {
        header.push(_react2['default'].createElement(
          'th',
          { key: i, className: 'DayPicker-weekday' },
          (0, _moment2['default'])().weekday(i).format('dd')
        ));
      }

      return header;
    }
  }, {
    key: 'renderDays',
    value: function renderDays(week) {
      var _this4 = this;

      var firstDay = week[0];
      var lastDay = week[week.length - 1];

      var days = week.map(function (day) {
        return _this4.renderDay(day);
      });

      // days belonging to the previous month
      for (var i = 0; i < firstDay.weekday(); i++) {
        var prevDay = firstDay.clone().subtract(i + 1, 'day');
        days.unshift(this.renderDay(prevDay, true));
      }

      // days belonging to the next month
      for (var j = lastDay.weekday() + 1, count = 1; j < 7; j++, count++) {
        var nextDay = lastDay.clone().add(count, 'day');
        days.push(this.renderDay(nextDay, true));
      }

      return days;
    }
  }, {
    key: 'renderDay',
    value: function renderDay(day, outside) {
      var key = '' + day.dayOfYear();
      var className = 'DayPicker-day';

      if (outside) {
        className += ' DayPicker-day--outside';
      }

      if (outside && !this.props.enableOutsideDays) {
        return _react2['default'].createElement('td', { className: className, ref: key, key: key });
      } else {
        var modifiers = this.getModifiersForDay(day);
        if (outside) {
          modifiers.push('outside');
        }
        className += modifiers.map(function (mod) {
          return ' DayPicker-day--' + mod;
        }).join('');
        return _react2['default'].createElement(
          'td',
          { ref: key, key: key,
            className: className,
            onMouseEnter: this.handleDayMouseEnter.bind(this, day, modifiers),
            onMouseLeave: this.handleDayMouseLeave.bind(this, day, modifiers),
            onTouchTap: this.handleDayTouchTap.bind(this, day, modifiers),
            onClick: this.handleDayClick.bind(this, day, modifiers) },
          day.format('D')
        );
      }
    }
  }], [{
    key: 'propTypes',
    value: {

      enableOutsideDays: _react.PropTypes.bool,

      // default is current month
      initialMonth: _react.PropTypes.object,

      // default is 1
      numberOfMonths: _react.PropTypes.number,

      modifiers: _react.PropTypes.object,

      onDayClick: _react.PropTypes.func,

      // requires react-tap-event-plugin
      onDayTouchTap: _react.PropTypes.func,

      onDayMouseEnter: _react.PropTypes.func,
      onDayMouseLeave: _react.PropTypes.func,

      onNextMonthClick: _react.PropTypes.func,
      onPrevMonthClick: _react.PropTypes.func

    },
    enumerable: true
  }, {
    key: 'defaultProps',
    value: {
      initialMonth: (0, _moment2['default'])(),
      numberOfMonths: 1,
      enableOutsideDays: false
    },
    enumerable: true
  }]);

  return DayPicker;
})(_react.Component);

exports['default'] = DayPicker;
module.exports = exports['default'];<|endoftext|>


<commit_before><commit_msg>set proper port number for workers on inspect<commit_after><|endoftext|>


<commit_before>//////// Module Definition ////////////
define([
	'browse/browse.module',
	'ngRoute',
	'util/util.service',
	'i18n/i18n.service',
], function() {
///////////////////////////////////////

angular.module('browse').factory('arguments', ['$http', '$route', 'util', 'i18n', function($http, $route, util, i18n){
	  var filterLimits = {
		  'instances': 10E6,
		  'subclasses': 5E6,
		  'statements': 100E6,
		  'qualifiers': 50E6,
		  'references': 20E6,
	  };

	function getFilterLimits() {
		return filterLimits;
	}

	  var args = {};
	  var statusStartValues = {
		entityType: "classes",
		activePage: 1,
		lang: i18n.getLanguage(),
		sortCriteria: {
		  classes: {
			label: "fa fa-sort",
			instances: "fa fa-sort-desc",
			subclasses: "fa fa-sort"
		  },
		  properties: {
			label: "fa fa-sort",
			datatype: "fa fa-sort",
			statements: "fa fa-sort-desc",
			qualifiers: "fa fa-sort",
			references: "fa fa-sort"
		  }
		},
		classesFilter: {
		  label: "",
		  relatedProperty: "",
		  superclass: "",
		  instances: [0, filterLimits['instances']],
		  subclasses: [0, filterLimits['subclasses']]
		},
		propertiesFilter: {
		  label: "",
		  relatedProperty: "",
		  relatedQualifier: "",
		  usedForClass: "",
		  directInstanceOf: {id: 1, name: "Any property class", qId: 0},
		  statements: [0, filterLimits['statements']],
		  qualifiers: [0, filterLimits['qualifiers']],
		  references: [0, filterLimits['references']],
		  datatypes: {id: 1, name: "Any property type"}

		}
	  };

	  var serializeDatatype = function(type){
		return type.id + ":" + type.name;
	  }

	  var deserializeDatatype = function(typeString){
		if (!typeString){
		  return typeString;
		}
		var splits = typeString.split(":");
		return {id: splits[0], name: splits[1]};
	  }

	  var serializePropertyClass = function(c){
		return c.id + ":" + c.name + ":" + c.qId;
	  }

	  var deserializePropertyClass = function(classString){
		if (!classString){
		  return classString;
		}
		var splits = classString.split(":");
		return {id: splits[0], name: splits[1], qId: splits[2]};
	  }

	  var status = util.cloneObject(statusStartValues);
	  return {
		refreshArgs: function(){
		  args = {
			type: ($route.current.params.type) ? ($route.current.params.type) : status.entityType,
			activePage: ($route.current.params.activepage) ? parseInt(($route.current.params.activepage)) : status.activePage,
			lang : ($route.current.params.lang) ? ($route.current.params.lang) : i18n.getLanguage(),
			sortCriteria: {
			  classes: {
				label: ($route.current.params.sortclasslabel) ? ($route.current.params.sortclasslabel) : status.sortCriteria.classes.label,
				instances: ($route.current.params.sortclassinstances) ? ($route.current.params.sortclassinstances) : status.sortCriteria.classes.instances,
				subclasses: ($route.current.params.sortclasssubclasses) ? ($route.current.params.sortclasssubclasses) : status.sortCriteria.classes.subclasses
			  },
			  properties: {
				label: ($route.current.params.sortpropertylabel) ? ($route.current.params.sortpropertylabel) : status.sortCriteria.properties.label,
				datatype: ($route.current.params.sortpropertydatatype) ? ($route.current.params.sortpropertydatatype) : status.sortCriteria.properties.datatype,
				statements: ($route.current.params.sortpropertystatements) ? ($route.current.params.sortpropertystatements) : status.sortCriteria.properties.statements,
				qualifiers: ($route.current.params.sortpropertyqualifiers) ? ($route.current.params.sortpropertyqualifiers) : status.sortCriteria.properties.qualifiers,
				references: ($route.current.params.sortpropertyreferences) ? ($route.current.params.sortpropertyreferences) : status.sortCriteria.properties.references
			  }
			},
			classesFilter: {
			  label:  ($route.current.params.classlabelfilter) ? ($route.current.params.classlabelfilter) : status.classesFilter.label,
			  relatedProperty: ($route.current.params.rpcfilter) ? ($route.current.params.rpcfilter) : status.classesFilter.relatedProperty,
			  superclass: ($route.current.params.supercfilter) ? ($route.current.params.supercfilter) : status.classesFilter.superclass,
			  instances: [ ($route.current.params.instancesbegin) ? ($route.current.params.instancesbegin) : status.classesFilter.instances[0], ($route.current.params.instancesend) ? ($route.current.params.instancesend) : status.classesFilter.instances[1]],
			  subclasses: [ ($route.current.params.subclassesbegin) ? ($route.current.params.subclassesbegin) : status.classesFilter.subclasses[0], ($route.current.params.subclassesend) ? ($route.current.params.subclassesend) : status.classesFilter.subclasses[1]],
			},
			propertiesFilter: {
			  label: ($route.current.params.propertylabelfilter) ? ($route.current.params.propertylabelfilter) : status.propertiesFilter.label,
			  relatedProperty: ($route.current.params.rppfilter) ? ($route.current.params.rppfilter) : status.propertiesFilter.relatedProperty,
			  relatedQualifier: ($route.current.params.rqualifierfilter) ? ($route.current.params.rqualifierfilter) : status.propertiesFilter.relatedQualifier,
			  usedForClass: ($route.current.params.usedforclassfilter) ? ($route.current.params.usedforclassfilter) : status.propertiesFilter.usedForClass,
			  directInstanceOf: ($route.current.params.dInstancefilter) ? deserializePropertyClass($route.current.params.dInstancefilter) : status.propertiesFilter.directInstanceOf,
			  statements: [ ($route.current.params.statementsbegin) ? ($route.current.params.statementsbegin) : status.propertiesFilter.statements[0], ($route.current.params.statementsend) ? ($route.current.params.statementsend) : status.propertiesFilter.statements[1]],
			  qualifiers: [ ($route.current.params.qualifiersbegin) ? ($route.current.params.qualifiersbegin) : status.propertiesFilter.qualifiers[0], ($route.current.params.qualifiersend) ? ($route.current.params.qualifiersend) : status.propertiesFilter.qualifiers[1]],
			  references: [ ($route.current.params.referencesbegin) ? ($route.current.params.referencesbegin) : status.propertiesFilter.references[0], ($route.current.params.referencesend) ? ($route.current.params.referencesend) : status.propertiesFilter.references[1]],
			  datatypes: ($route.current.params.datatypes) ? deserializeDatatype($route.current.params.datatypes) : status.propertiesFilter.datatypes
			}
		  }
		  status.entityType = args.type;
		  status.activePage = args.activePage;
		  status.lang = args.lang;
		  status.sortCriteria = args.sortCriteria;
		  status.classesFilter = args.classesFilter;
		  status.propertiesFilter = args.propertiesFilter;
		},
		getArgs: function(){
		  return args;
		},
		getStatus: function(){
		  return status;
		},
		getStatusStartValues:function(){
		  return util.cloneObject(statusStartValues);
		},
		getUrl: function(){
		  var result =  location.origin + location.pathname + "#/browse"
			+ "?activepage=" + status.activePage
			+ "&type=" + status.entityType
			+ "&lang=" + status.lang;
		  if (status.entityType == "classes"){
			result += (status.classesFilter.label ? "&classlabelfilter=" + status.classesFilter.label : "")
			  + (status.classesFilter.relatedProperty ? "&rpcfilter=" + status.classesFilter.relatedProperty : "")
			  + (status.classesFilter.superclass ? "&supercfilter=" + status.classesFilter.superclass : "")
			  + (status.classesFilter.instances[0] != 0 ? "&instancesbegin=" + status.classesFilter.instances[0] : "")
			  + (status.classesFilter.instances[1] != filterLimits['instances'] ? "&instancesend=" + status.classesFilter.instances[1] : "")
			  + (status.classesFilter.subclasses[0] != 0 ? "&subclassesbegin=" + status.classesFilter.subclasses[0] : "")
			  + (status.classesFilter.subclasses[1] != filterLimits['subclasses'] ? "&subclassesend=" + status.classesFilter.subclasses[1] : "")
			  + (status.sortCriteria.classes.label != "fa fa-sort" ? "&sortclasslabel=" + status.sortCriteria.classes.label : "")
			  + (status.sortCriteria.classes.instances != "fa fa-sort-desc" ? "&sortclassinstances=" + status.sortCriteria.classes.instances : "")
			  + (status.sortCriteria.classes.subclasses != "fa fa-sort" ? "&sortclasssubclasses=" + status.sortCriteria.classes.subclasses : "")

		  }else{
			result += (status.propertiesFilter.label ? "&propertylabelfilter=" + status.propertiesFilter.label : "")
			  + (status.propertiesFilter.relatedProperty ? "&rppfilter=" + status.propertiesFilter.relatedProperty : "")
			  + (status.propertiesFilter.relatedQualifier ? "&rqualifierfilter=" + status.propertiesFilter.relatedQualifier : "")
			  + (status.propertiesFilter.usedForClass ? "&usedforclassfilter=" + status.propertiesFilter.usedForClass : "")
			  + (status.propertiesFilter.directInstanceOf.id != 1 ? "&dInstancefilter=" + serializePropertyClass(status.propertiesFilter.directInstanceOf) : "")
			  + (status.propertiesFilter.statements[0] != 0 ? "&statementsbegin=" + status.propertiesFilter.statements[0] : "")
			  + (status.propertiesFilter.statements[1] != filterLimits['statements'] ? "&statementsend=" + status.propertiesFilter.statements[1] : "")
			  + (status.propertiesFilter.qualifiers[0] != 0 ? "&qualifiersbegin=" + status.propertiesFilter.qualifiers[0] : "")
			  + (status.propertiesFilter.qualifiers[1] != filterLimits['qualifiers'] ? "&qualifiersend=" + status.propertiesFilter.qualifiers[1] : "")
			  + (status.propertiesFilter.references[0] != 0 ? "&referencesbegin=" + status.propertiesFilter.references[0] : "")
			  + (status.propertiesFilter.references[1] != filterLimits['references']  ? "&referencesend=" + status.propertiesFilter.references[1] : "")
			  + (status.propertiesFilter.datatypes.id != 1 ? "&datatypes=" + serializeDatatype(status.propertiesFilter.datatypes) : "")
			  + (status.sortCriteria.properties.label != "fa fa-sort" ? "&sortpropertylabel=" + status.sortCriteria.properties.label : "")
			  + (status.sortCriteria.properties.datatype != "fa fa-sort" ? "&sortpropertydatatype=" + status.sortCriteria.properties.datatype : "")
			  + (status.sortCriteria.properties.statements != "fa fa-sort-desc" ? "&sortpropertystatements=" + status.sortCriteria.properties.statements : "")
			  + (status.sortCriteria.properties.qualifiers != "fa fa-sort" ? "&sortpropertyqualifiers=" + status.sortCriteria.properties.qualifiers : "")
			  + (status.sortCriteria.properties.references != "fa fa-sort" ? "&sortpropertyreferences=" + status.sortCriteria.properties.references : "");
		  }
		  return result;
		}
	  }
  }]);

return {}; }); // module definition end
<commit_msg>Actually export function<commit_after>//////// Module Definition ////////////
define([
	'browse/browse.module',
	'ngRoute',
	'util/util.service',
	'i18n/i18n.service',
], function() {
///////////////////////////////////////

angular.module('browse').factory('arguments', ['$http', '$route', 'util', 'i18n', function($http, $route, util, i18n){
	  var filterLimits = {
		  'instances': 10E6,
		  'subclasses': 5E6,
		  'statements': 100E6,
		  'qualifiers': 50E6,
		  'references': 20E6,
	  };

	  var args = {};
	  var statusStartValues = {
		entityType: "classes",
		activePage: 1,
		lang: i18n.getLanguage(),
		sortCriteria: {
		  classes: {
			label: "fa fa-sort",
			instances: "fa fa-sort-desc",
			subclasses: "fa fa-sort"
		  },
		  properties: {
			label: "fa fa-sort",
			datatype: "fa fa-sort",
			statements: "fa fa-sort-desc",
			qualifiers: "fa fa-sort",
			references: "fa fa-sort"
		  }
		},
		classesFilter: {
		  label: "",
		  relatedProperty: "",
		  superclass: "",
		  instances: [0, filterLimits['instances']],
		  subclasses: [0, filterLimits['subclasses']]
		},
		propertiesFilter: {
		  label: "",
		  relatedProperty: "",
		  relatedQualifier: "",
		  usedForClass: "",
		  directInstanceOf: {id: 1, name: "Any property class", qId: 0},
		  statements: [0, filterLimits['statements']],
		  qualifiers: [0, filterLimits['qualifiers']],
		  references: [0, filterLimits['references']],
		  datatypes: {id: 1, name: "Any property type"}

		}
	  };

	  var serializeDatatype = function(type){
		return type.id + ":" + type.name;
	  }

	  var deserializeDatatype = function(typeString){
		if (!typeString){
		  return typeString;
		}
		var splits = typeString.split(":");
		return {id: splits[0], name: splits[1]};
	  }

	  var serializePropertyClass = function(c){
		return c.id + ":" + c.name + ":" + c.qId;
	  }

	  var deserializePropertyClass = function(classString){
		if (!classString){
		  return classString;
		}
		var splits = classString.split(":");
		return {id: splits[0], name: splits[1], qId: splits[2]};
	  }

	  var status = util.cloneObject(statusStartValues);
	  return {
		getFilterLimits: function() {
		  return filterLimits;
		},
		refreshArgs: function(){
		  args = {
			type: ($route.current.params.type) ? ($route.current.params.type) : status.entityType,
			activePage: ($route.current.params.activepage) ? parseInt(($route.current.params.activepage)) : status.activePage,
			lang : ($route.current.params.lang) ? ($route.current.params.lang) : i18n.getLanguage(),
			sortCriteria: {
			  classes: {
				label: ($route.current.params.sortclasslabel) ? ($route.current.params.sortclasslabel) : status.sortCriteria.classes.label,
				instances: ($route.current.params.sortclassinstances) ? ($route.current.params.sortclassinstances) : status.sortCriteria.classes.instances,
				subclasses: ($route.current.params.sortclasssubclasses) ? ($route.current.params.sortclasssubclasses) : status.sortCriteria.classes.subclasses
			  },
			  properties: {
				label: ($route.current.params.sortpropertylabel) ? ($route.current.params.sortpropertylabel) : status.sortCriteria.properties.label,
				datatype: ($route.current.params.sortpropertydatatype) ? ($route.current.params.sortpropertydatatype) : status.sortCriteria.properties.datatype,
				statements: ($route.current.params.sortpropertystatements) ? ($route.current.params.sortpropertystatements) : status.sortCriteria.properties.statements,
				qualifiers: ($route.current.params.sortpropertyqualifiers) ? ($route.current.params.sortpropertyqualifiers) : status.sortCriteria.properties.qualifiers,
				references: ($route.current.params.sortpropertyreferences) ? ($route.current.params.sortpropertyreferences) : status.sortCriteria.properties.references
			  }
			},
			classesFilter: {
			  label:  ($route.current.params.classlabelfilter) ? ($route.current.params.classlabelfilter) : status.classesFilter.label,
			  relatedProperty: ($route.current.params.rpcfilter) ? ($route.current.params.rpcfilter) : status.classesFilter.relatedProperty,
			  superclass: ($route.current.params.supercfilter) ? ($route.current.params.supercfilter) : status.classesFilter.superclass,
			  instances: [ ($route.current.params.instancesbegin) ? ($route.current.params.instancesbegin) : status.classesFilter.instances[0], ($route.current.params.instancesend) ? ($route.current.params.instancesend) : status.classesFilter.instances[1]],
			  subclasses: [ ($route.current.params.subclassesbegin) ? ($route.current.params.subclassesbegin) : status.classesFilter.subclasses[0], ($route.current.params.subclassesend) ? ($route.current.params.subclassesend) : status.classesFilter.subclasses[1]],
			},
			propertiesFilter: {
			  label: ($route.current.params.propertylabelfilter) ? ($route.current.params.propertylabelfilter) : status.propertiesFilter.label,
			  relatedProperty: ($route.current.params.rppfilter) ? ($route.current.params.rppfilter) : status.propertiesFilter.relatedProperty,
			  relatedQualifier: ($route.current.params.rqualifierfilter) ? ($route.current.params.rqualifierfilter) : status.propertiesFilter.relatedQualifier,
			  usedForClass: ($route.current.params.usedforclassfilter) ? ($route.current.params.usedforclassfilter) : status.propertiesFilter.usedForClass,
			  directInstanceOf: ($route.current.params.dInstancefilter) ? deserializePropertyClass($route.current.params.dInstancefilter) : status.propertiesFilter.directInstanceOf,
			  statements: [ ($route.current.params.statementsbegin) ? ($route.current.params.statementsbegin) : status.propertiesFilter.statements[0], ($route.current.params.statementsend) ? ($route.current.params.statementsend) : status.propertiesFilter.statements[1]],
			  qualifiers: [ ($route.current.params.qualifiersbegin) ? ($route.current.params.qualifiersbegin) : status.propertiesFilter.qualifiers[0], ($route.current.params.qualifiersend) ? ($route.current.params.qualifiersend) : status.propertiesFilter.qualifiers[1]],
			  references: [ ($route.current.params.referencesbegin) ? ($route.current.params.referencesbegin) : status.propertiesFilter.references[0], ($route.current.params.referencesend) ? ($route.current.params.referencesend) : status.propertiesFilter.references[1]],
			  datatypes: ($route.current.params.datatypes) ? deserializeDatatype($route.current.params.datatypes) : status.propertiesFilter.datatypes
			}
		  }
		  status.entityType = args.type;
		  status.activePage = args.activePage;
		  status.lang = args.lang;
		  status.sortCriteria = args.sortCriteria;
		  status.classesFilter = args.classesFilter;
		  status.propertiesFilter = args.propertiesFilter;
		},
		getArgs: function(){
		  return args;
		},
		getStatus: function(){
		  return status;
		},
		getStatusStartValues:function(){
		  return util.cloneObject(statusStartValues);
		},
		getUrl: function(){
		  var result =  location.origin + location.pathname + "#/browse"
			+ "?activepage=" + status.activePage
			+ "&type=" + status.entityType
			+ "&lang=" + status.lang;
		  if (status.entityType == "classes"){
			result += (status.classesFilter.label ? "&classlabelfilter=" + status.classesFilter.label : "")
			  + (status.classesFilter.relatedProperty ? "&rpcfilter=" + status.classesFilter.relatedProperty : "")
			  + (status.classesFilter.superclass ? "&supercfilter=" + status.classesFilter.superclass : "")
			  + (status.classesFilter.instances[0] != 0 ? "&instancesbegin=" + status.classesFilter.instances[0] : "")
			  + (status.classesFilter.instances[1] != filterLimits['instances'] ? "&instancesend=" + status.classesFilter.instances[1] : "")
			  + (status.classesFilter.subclasses[0] != 0 ? "&subclassesbegin=" + status.classesFilter.subclasses[0] : "")
			  + (status.classesFilter.subclasses[1] != filterLimits['subclasses'] ? "&subclassesend=" + status.classesFilter.subclasses[1] : "")
			  + (status.sortCriteria.classes.label != "fa fa-sort" ? "&sortclasslabel=" + status.sortCriteria.classes.label : "")
			  + (status.sortCriteria.classes.instances != "fa fa-sort-desc" ? "&sortclassinstances=" + status.sortCriteria.classes.instances : "")
			  + (status.sortCriteria.classes.subclasses != "fa fa-sort" ? "&sortclasssubclasses=" + status.sortCriteria.classes.subclasses : "")

		  }else{
			result += (status.propertiesFilter.label ? "&propertylabelfilter=" + status.propertiesFilter.label : "")
			  + (status.propertiesFilter.relatedProperty ? "&rppfilter=" + status.propertiesFilter.relatedProperty : "")
			  + (status.propertiesFilter.relatedQualifier ? "&rqualifierfilter=" + status.propertiesFilter.relatedQualifier : "")
			  + (status.propertiesFilter.usedForClass ? "&usedforclassfilter=" + status.propertiesFilter.usedForClass : "")
			  + (status.propertiesFilter.directInstanceOf.id != 1 ? "&dInstancefilter=" + serializePropertyClass(status.propertiesFilter.directInstanceOf) : "")
			  + (status.propertiesFilter.statements[0] != 0 ? "&statementsbegin=" + status.propertiesFilter.statements[0] : "")
			  + (status.propertiesFilter.statements[1] != filterLimits['statements'] ? "&statementsend=" + status.propertiesFilter.statements[1] : "")
			  + (status.propertiesFilter.qualifiers[0] != 0 ? "&qualifiersbegin=" + status.propertiesFilter.qualifiers[0] : "")
			  + (status.propertiesFilter.qualifiers[1] != filterLimits['qualifiers'] ? "&qualifiersend=" + status.propertiesFilter.qualifiers[1] : "")
			  + (status.propertiesFilter.references[0] != 0 ? "&referencesbegin=" + status.propertiesFilter.references[0] : "")
			  + (status.propertiesFilter.references[1] != filterLimits['references']  ? "&referencesend=" + status.propertiesFilter.references[1] : "")
			  + (status.propertiesFilter.datatypes.id != 1 ? "&datatypes=" + serializeDatatype(status.propertiesFilter.datatypes) : "")
			  + (status.sortCriteria.properties.label != "fa fa-sort" ? "&sortpropertylabel=" + status.sortCriteria.properties.label : "")
			  + (status.sortCriteria.properties.datatype != "fa fa-sort" ? "&sortpropertydatatype=" + status.sortCriteria.properties.datatype : "")
			  + (status.sortCriteria.properties.statements != "fa fa-sort-desc" ? "&sortpropertystatements=" + status.sortCriteria.properties.statements : "")
			  + (status.sortCriteria.properties.qualifiers != "fa fa-sort" ? "&sortpropertyqualifiers=" + status.sortCriteria.properties.qualifiers : "")
			  + (status.sortCriteria.properties.references != "fa fa-sort" ? "&sortpropertyreferences=" + status.sortCriteria.properties.references : "");
		  }
		  return result;
		}
	  }
  }]);

return {}; }); // module definition end
<|endoftext|>


<commit_before>import Ember from 'ember';

var A = Ember.A;
var computed = Ember.computed;
var get = Ember.get;
var isPresent = Ember.isPresent;

export default function groupBy(collection, property) {
  var dependentKey = collection + '.@each.' + property;

  return computed(dependentKey, function() {
    var groups = new A();
    var items = get(this, collection);

    items.forEach(function(item) {
      var value = get(item, property);
      var group = groups.findBy('value', value);

      if (isPresent(group)) {
        get(group, 'items').push(item);
      } else {
        group = { property: property, value: value, items: [item] };
        groups.push(group);
      }
    });

    return groups;
  }).readOnly();
}
<commit_msg>Fix empty array<commit_after>import Ember from 'ember';

var A = Ember.A;
var computed = Ember.computed;
var get = Ember.get;
var isPresent = Ember.isPresent;

export default function groupBy(collection, property) {
  var dependentKey = collection + '.@each.' + property;

  return computed(dependentKey, function() {
    var groups = new A();
    var items = get(this, collection);

    if (items) {
      items.forEach(function(item) {
        var value = get(item, property);
        var group = groups.findBy('value', value);

        if (isPresent(group)) {
          get(group, 'items').push(item);
        } else {
          group = { property: property, value: value, items: [item] };
          groups.push(group);
        }
      });
    }

    return groups;
  }).readOnly();
}
<|endoftext|>


<commit_before>/**
 * Has Vowels
 *
 * hasVowel tests if the String calling the function has a vowels
 *
 * @param {void}
 * @return {Boolean} returns true or false indicating if the string
 * has a vowel or not
 */
String.prototype.hasVowels = function() {
    var inputString = this;
    return /[aeiou]/i.test(inputString);
};

/**
 * To Upper
 *
 * toUpper converts its calling string to all uppercase characters
 *
 * @param {void}
 * @return {String} returns an upperCase version of the calling string
 */
String.prototype.toUpper = function() {
    // the 'this' keyword represents the string calling the function
    return this.replace(/[a-z]/g, function(item, position, string) {
        return String.fromCharCode(string.charCodeAt(position) - 32);
    });
};

String.prototype.toLower = function() {
    // the 'this' keyword represents the string calling the function
    return this.replace(/[A-Z]/g, function(item, position, string) {
        return String.fromCharCode(string.charCodeAt(position) + 32);
    });
};

/**
 * Uc First
 *
 * ucFirst capitalises the first character of its calling string
 *
 * @param {void}
 * @return {String} returns the calling string with the first character
 * capitalised
 */
String.prototype.ucFirst = function() {
    // get the first character
    return this.toLower().replace(/^[a-z]/, function(item) {
        return item.toUpper();
    });
};

/**
 * Is Question
 *
 * isQuestion checks if a string is a question. It does this by
 * checking if it contains a question mark at the end of the
 * string
 *
 * @param {void}
 * @return {Boolean}returns a true or false indicating if the
 * string is a question or not
 */
String.prototype.isQuestion = function() {
    return /(((\w( )*)+\?)$)/g.test(this);
};

/**
 * Words
 *
 * words returns an array of words in the calling string
 *
 * @param {void}
 * @return {Object | Array} returns an array of strings
 */
String.prototype.words = function() {
    // tests for words that have a hyphen between them
    // like a compound name, also tests for words that
    // have an apostrophe
    var result = this.match(/(\w+([-']\w+)*)/g);

    // checks if result is null
    if(result) {
        return result;
    }

    // return an empty array if there are no words
    // in the string
    return [];
};

/**
 * Word Count
 *
 * wordCount returns the number of words in the string
 *
 * @param {void}
 * @return {Number} returns the number of words in the calling
 * string
 */
String.prototype.wordCount = function() {
    return this.words().length;
};

/**
 * To Currency
 *
 * toCurrency returns a string of digits formatted as a
 * currency type string. Example 1111111.00 to 1,111,111.00
 *
 * @param {void}
 * @return {String} returns the currency formatted string of
 * its calling string
 */
String.prototype.toCurrency = function() {
    var splitString = this.split('.');

    // this regex searches for a digit that has exactly three
    // digits after it and adds a comma after the digit. $
    // makes sure the pattern starts at the end of the string.
    // ?= and {3} asserts that there are exactly three digits
    splitString[0] = splitString[0]
        .replace(/\d(?=([\d]{3})+$)/g, function(item){
        return item + ',';
    });

    var result = splitString[0];

    if(splitString.length > 1) {
        // if the length of the digit after the decimal point
        // more than 2 then truncate the other digits
        splitString[1] = splitString[1].match(/(\d{1,2})/)[0];
        result = splitString.join('.');
    }

    return result;
};

/**
 * From Currency
 *
 * fromCurrency converts from currency formatted string to a
 * number
 *
 * @param {void}
 * @return {Number} returns a number representing the number
 * form of it calling string.
 */
String.prototype.fromCurrency = function() {
    return Number(this.replace(/,/g, ''));
};

/**
 * Inverse Case
 *
 * inverseCase takes its calling string and inverses the
 * cases of its characters.
 *
 * @param {void}
 * @return {String} returns a string which is in inverse case
 * of its calling string
 */
String.prototype.inverseCase = function() {
    var splitString = this.split('');
    var inverseSplitString = splitString.map(function(item) {
        if(/[a-z]/.test(item)) {
            return item.toUpper();
        } else if(/[A-Z]/.test(item)) {
            return item.toLower();
        }
        return item;
    });
    return inverseSplitString.join('');
};

/**
 * Alternating Case
 *
 * alternatingCase takes its calling string and returns it with
 * all its characters in alternating case
 *
 * @param {void}
 * @return{String} returns the calling string with its characters in
 * alternating cases.
 */
String.prototype.alternatingCase = function() {
    return this.replace(/[a-zA-Z]/gi, function(item, position){
        if(position % 2 === 0) {
            return item.toLower();
        } else if (position % 2 !== 0) {
            return item.toUpper();
        }
    });
};

/**
 * Get Middle
 *
 * getMiddle gets its calling string. It returns the 2 middle
 * characters if the string's length is even
 *
 * @param {void}
 * @return {String} returns the middle word(s) of the string
 */
String.prototype.getMiddle = function() {
    // split the string just after any character, the regex matches
    // null after any character(including space) in the string
    var value = this. split(/(?=)/g);

    var half = value.length / 2;
    if (value.length % 2 === 0) {
        return value.slice(half - 1, half + 1).join('');
    }
    return value[parseInt(half)];
};

/**
 * Number Words
 *
 * numberWords returns the digits contained in the string
 * in their word form. For example 1 to one, 2 to two.
 *
 * @param {void}
 * @return {String} return the word representation on the digits
 * in the string
 */
String.prototype.numberWords = function() {
    // array of numbers in their digit form, with each number
    // the same as the index position of the array
    var words = [
        'zero', 'one', 'two', 'three', 'four',
        'five', 'six', 'seven', 'eight', 'nine'
    ];

    // split the string just after any character, the regex matches
    // null after any character(including space) in the string
    return this.split(/(?=)/g).map(function(item) {
        if(/\d/.test(item)) {
            return words[parseInt(item, 10)];
        }
        return item;
    }).join(' ').replace(/\s+/g, ' ');
};

/**
 * Is Digit
 *
 * isDigit tests if its calling string contains only one digit
 * or not.
 *
 * @param {void}
 * @return {Boolean} returns true for single digit strings and
 * false for otherwise
 */
String.prototype.isDigit = function() {
    // the regex tests for strings that start with non-alphanumeric,
    // alphanumeric and digit values and have other values after
    // them. It matched double digits and more, digits with alphabets
    // before and after them. The second regex checks if the value is
    // a digit, the first check doesn't catch single alphabets thus
    // necessitating the second regex
    return (!/[\W\w\d]+([\w\W\d]+)/.test(this) && /\d/.test(this));
};

/**
 * Double Check
 *
 * doubleCheck checks if its calling sring contains a double character
 * following after itself
 *
 * @param {void}
 * @return {Boolean} returns true if the string has a double character
 * and false if not
 */
String.prototype.doubleCheck = function() {
    // checks if the samealphanumeric and non-alphanumeric characters
    // exists side by side. \1 checks if the preceding group is repeated
    // after itself
    return /([\w\W])\1/gi.test(this);
};
<commit_msg>Change isDigit() regex<commit_after>/**
 * Has Vowels
 *
 * hasVowel tests if the String calling the function has a vowels
 *
 * @param {void}
 * @return {Boolean} returns true or false indicating if the string
 * has a vowel or not
 */
String.prototype.hasVowels = function() {
    var inputString = this;
    return /[aeiou]/i.test(inputString);
};

/**
 * To Upper
 *
 * toUpper converts its calling string to all uppercase characters
 *
 * @param {void}
 * @return {String} returns an upperCase version of the calling string
 */
String.prototype.toUpper = function() {
    // the 'this' keyword represents the string calling the function
    return this.replace(/[a-z]/g, function(item, position, string) {
        return String.fromCharCode(string.charCodeAt(position) - 32);
    });
};

String.prototype.toLower = function() {
    // the 'this' keyword represents the string calling the function
    return this.replace(/[A-Z]/g, function(item, position, string) {
        return String.fromCharCode(string.charCodeAt(position) + 32);
    });
};

/**
 * Uc First
 *
 * ucFirst capitalises the first character of its calling string
 *
 * @param {void}
 * @return {String} returns the calling string with the first character
 * capitalised
 */
String.prototype.ucFirst = function() {
    // get the first character
    return this.toLower().replace(/^[a-z]/, function(item) {
        return item.toUpper();
    });
};

/**
 * Is Question
 *
 * isQuestion checks if a string is a question. It does this by
 * checking if it contains a question mark at the end of the
 * string
 *
 * @param {void}
 * @return {Boolean}returns a true or false indicating if the
 * string is a question or not
 */
String.prototype.isQuestion = function() {
    return /(((\w( )*)+\?)$)/g.test(this);
};

/**
 * Words
 *
 * words returns an array of words in the calling string
 *
 * @param {void}
 * @return {Object | Array} returns an array of strings
 */
String.prototype.words = function() {
    // tests for words that have a hyphen between them
    // like a compound name, also tests for words that
    // have an apostrophe
    var result = this.match(/(\w+([-']\w+)*)/g);

    // checks if result is null
    if(result) {
        return result;
    }

    // return an empty array if there are no words
    // in the string
    return [];
};

/**
 * Word Count
 *
 * wordCount returns the number of words in the string
 *
 * @param {void}
 * @return {Number} returns the number of words in the calling
 * string
 */
String.prototype.wordCount = function() {
    return this.words().length;
};

/**
 * To Currency
 *
 * toCurrency returns a string of digits formatted as a
 * currency type string. Example 1111111.00 to 1,111,111.00
 *
 * @param {void}
 * @return {String} returns the currency formatted string of
 * its calling string
 */
String.prototype.toCurrency = function() {
    var splitString = this.split('.');

    // this regex searches for a digit that has exactly three
    // digits after it and adds a comma after the digit. $
    // makes sure the pattern starts at the end of the string.
    // ?= and {3} asserts that there are exactly three digits
    splitString[0] = splitString[0]
        .replace(/\d(?=([\d]{3})+$)/g, function(item){
        return item + ',';
    });

    var result = splitString[0];

    if(splitString.length > 1) {
        // if the length of the digit after the decimal point
        // more than 2 then truncate the other digits
        splitString[1] = splitString[1].match(/(\d{1,2})/)[0];
        result = splitString.join('.');
    }

    return result;
};

/**
 * From Currency
 *
 * fromCurrency converts from currency formatted string to a
 * number
 *
 * @param {void}
 * @return {Number} returns a number representing the number
 * form of it calling string.
 */
String.prototype.fromCurrency = function() {
    return Number(this.replace(/,/g, ''));
};

/**
 * Inverse Case
 *
 * inverseCase takes its calling string and inverses the
 * cases of its characters.
 *
 * @param {void}
 * @return {String} returns a string which is in inverse case
 * of its calling string
 */
String.prototype.inverseCase = function() {
    var splitString = this.split('');
    var inverseSplitString = splitString.map(function(item) {
        if(/[a-z]/.test(item)) {
            return item.toUpper();
        } else if(/[A-Z]/.test(item)) {
            return item.toLower();
        }
        return item;
    });
    return inverseSplitString.join('');
};

/**
 * Alternating Case
 *
 * alternatingCase takes its calling string and returns it with
 * all its characters in alternating case
 *
 * @param {void}
 * @return{String} returns the calling string with its characters in
 * alternating cases.
 */
String.prototype.alternatingCase = function() {
    return this.replace(/[a-zA-Z]/gi, function(item, position){
        if(position % 2 === 0) {
            return item.toLower();
        } else if (position % 2 !== 0) {
            return item.toUpper();
        }
    });
};

/**
 * Get Middle
 *
 * getMiddle gets its calling string. It returns the 2 middle
 * characters if the string's length is even
 *
 * @param {void}
 * @return {String} returns the middle word(s) of the string
 */
String.prototype.getMiddle = function() {
    // split the string just after any character, the regex matches
    // null after any character(including space) in the string
    var value = this. split(/(?=)/g);

    var half = value.length / 2;
    if (value.length % 2 === 0) {
        return value.slice(half - 1, half + 1).join('');
    }
    return value[parseInt(half)];
};

/**
 * Number Words
 *
 * numberWords returns the digits contained in the string
 * in their word form. For example 1 to one, 2 to two.
 *
 * @param {void}
 * @return {String} return the word representation on the digits
 * in the string
 */
String.prototype.numberWords = function() {
    // array of numbers in their digit form, with each number
    // the same as the index position of the array
    var words = [
        'zero', 'one', 'two', 'three', 'four',
        'five', 'six', 'seven', 'eight', 'nine'
    ];

    // split the string just after any character, the regex matches
    // null after any character(including space) in the string
    return this.split(/(?=)/g).map(function(item) {
        if(/\d/.test(item)) {
            return words[parseInt(item, 10)];
        }
        return item;
    }).join(' ').replace(/\s+/g, ' ');
};

/**
 * Is Digit
 *
 * isDigit tests if its calling string contains only one digit
 * or not.
 *
 * @param {void}
 * @return {Boolean} returns true for single digit strings and
 * false for otherwise
 */
String.prototype.isDigit = function() {
    /* the regex tests for strings that start with non-alphanumeric,
       alphanumeric and digit values and have other values after
       them. It matched double digits and more, digits with alphabets
       before and after them. The second regex checks if the value is
       a digit, the first check doesn't catch single alphabets thus
       necessitating the second regex */
    return (/^(\d)$/.test(this) && /\d/.test(this));
};

/**
 * Double Check
 *
 * doubleCheck checks if its calling sring contains a double character
 * following after itself
 *
 * @param {void}
 * @return {Boolean} returns true if the string has a double character
 * and false if not
 */
String.prototype.doubleCheck = function() {
    // checks if the samealphanumeric and non-alphanumeric characters
    // exists side by side. \1 checks if the preceding group is repeated
    // after itself
    return /([\w\W])\1/gi.test(this);
};
<|endoftext|>


<commit_before><commit_msg>Download data about one location<commit_after><|endoftext|>


<commit_before>/**
  @module ember-jsonapi-resources
  @submodule resource
**/

import Ember from 'ember';
import { pluralize, singularize } from 'ember-inflector';
import attr from 'ember-jsonapi-resources/utils/attr';
import hasOne from 'ember-jsonapi-resources/utils/has-one';
import hasMany from 'ember-jsonapi-resources/utils/has-many';
import { isType } from 'ember-jsonapi-resources/utils/is';

/**
  A Resource class to create JSON API resource objects

  See <http://jsonapi.org/format/#document-resource-objects>

  @class Resource
  @requires Ember.Inflector
  @static
*/
const Resource = Ember.Object.extend({

  /**
    The service object for the entity (adapter with cache and serializer)

    @property service
    @type Object
    @required
  */
  service: null,

  /**
    Extending Prototypes Must define a `type` value for the entity, e.g. `posts`

    @property type
    @type String
    @required
  */
  type: null,

  /**
    Persisted resource ID value

    @property id
    @type String
    @required
  */
  id: null,

  /**
    An optional `attributes` property of for a JSON API Resource object, setup in create()

    This object will keep the values from the response object and may be mutable
    Use this as a refence for creating computed properties

    For example the `attr()` helper sets up a properties based on this content

    @protected
    @property attributes
    @type Object
  */
  attributes: null,

  /**
    An optional `relationships` property of for a JSON API Resource object, setup in create()

    @protected
    @property relationships
    @type Object
  */
  relationships: null,

  /**
    An optional `links` property of for a JSON API Resource object, setup in create()

    @protected
    @property links
    @type Object
  */
  links: null,

  /**
    An optional property of for a JSON API Resource object, setup in create()

    @protected
    @property meta
    @type Object
  */
  meta: null,

  /**
    Hash of attributes for changed/previous values

    @private
    @property _attributes
    @type Object
  */
  _attributes: null,

  /**
    Flag for new instance, e.g. not peristed

    @property isNew
    @type Boolean
  */
  isNew: false,

  /**
    Custom `toString` method used for clarity that the instance is a JSON API Resource kind of object

    @method toString
  */
  toString() {
    let type = this.get('type') || 'null';
    let id = this.get('id') || 'null';
    return `[JSONAPIResource|${type}:${id}]`;
  },

  /**
    Update a relation by adding or removing using a list, id, or null. When
    adding an id for a to-many relation send one or more ids, include the
    existing ids as well. When removing from a to-many relation pass the ids
    that should remain, missing ids will be removed, or remove all with an empty
    array. When operating on a to-one relation just use the id to change the
    relation, or null to remove.

    This is not a replace operation, but rather support for editing as a set.

    @method updateRelationship
    @param {String} relation
    @param {Array|String|null} ids
  */
  updateRelationship(relation, ids) {
    let relationshipData = 'relationships.' + relation + '.data';
    let existing;
    if (!Array.isArray(ids)) {
      existing = this.get(relationshipData).id;
      this.removeRelationship(relation, existing);
      if (isType('string', ids)) {
        this.addRelationship(relation, ids);
      }
    } else {
      existing = this.get(relationshipData).map(function(rel) { return rel.id; });
      if (!existing.length) {
        this.addRelations(relation, ids);
      } else if (ids.length > existing.length) {
        this.addRelationships(relation, unique(ids, existing));
      } else if (existing.length > ids.length) {
        this.removeRelationships(relation, unique(existing, ids));
      }
    }
    return this.get('service').patchRelationship(this, relation);
  },

  /**
    @method addRelationships
    @param {String} related - resource name
    @param {Array} ids
  */
  addRelationships(related, ids) {
    for (let i = 0; i < ids.length; i++) {
      this.addRelationship(related, ids[i]);
    }
  },

  /**
    @method removeRelationships
    @param {String} related - resource name
    @param {Array} ids
  */
  removeRelationships(related, ids) {
    for (let i = 0; i < ids.length; i++) {
      this.removeRelationship(related, ids[i]);
    }
  },

  /**
    Adds related links object on the relationship hash

    @method addRelationship
    @param {String} related - resource name
    @param {String} id
  */
  addRelationship(related, id) {
    const key = ['relationships', related, 'data'].join('.');
    let data = this.get(key);
    const type = pluralize(related);
    const linkage = { type: type, id: id };
    if (Array.isArray(data)) {
      data.push(linkage);
    } else {
      data = linkage;
    }
    return this.set(key, data);
  },

  /**
    Remove related links object on the relationship hash to have `null` data

    @method removeRelationship
    @param {String} related - resource name
    @param {String} id
  */
  removeRelationship(related, id) {
    let relation = this.get('relationships.' + related);
    if (Array.isArray(relation.data)) {
      for (let i = 0; i < relation.data.length; i++) {
        if (relation.data[i].id === id) {
          relation.data.splice(i, 1);
          break;
        }
      }
    } else if (typeof relation === 'object') {
      relation.data = null;
    }
  },

  /**
    @method changedAttributes
    @return {Object} the changed attributes
  */
  changedAttributes: Ember.computed('attributes', {
    get: function () {
      const attrs = {};
      for (let key in this._attributes) {
        if (this._attributes.hasOwnProperty(key)) {
          if (this._attributes[key].changed !== this._attributes[key].previous) {
            attrs[key] = this._attributes[key].changed;
          }
        }
      }
      return attrs;
    }
  }).volatile(),

  /**
    @method previousAttributes
    @return {Object} the previous attributes
  */
  previousAttributes: Ember.computed('attributes', {
    get: function () {
      const attrs = {};
      for (let key in this._attributes) {
        if (this._attributes.hasOwnProperty(key)) {
          if (this._attributes[key].changed !== this._attributes[key].previous) {
            attrs[key] = this._attributes[key].previous;
          }
        }
      }
      return attrs;
    }
  }).volatile(),

  /**
    Initialize events to communicate with the service object, listen for `didUpdateResource`

    @method initEvents
  */
  initEvents: Ember.on('init', function () {
    const service = this.get('service');
    if (service) {
      service.on('didUpdateResource', this, this.didUpdateResource);
    }
  }),

  /**
    Handler for `didUpdateResource` event, resets private _attributes used for changed/previous tracking

    @method didUpdateResource
    @param json the updated data for the resource
  */
  didUpdateResource(json) {
    if (this.get('id') !== json.id) { return; }
    this.setProperties(json);
    for (let attr in this._attributes) {
      if (this._attributes.hasOwnProperty(attr)) {
        delete this._attributes[attr];
      }
    }
  },

  /**
    A local cache duration, to minimize duplicate fetch requests

    @property cacheDuration
    @type Number
  */
  cacheDuration: /* minutes */ 7 * /* seconds */ 60 * /* milliseconds */ 1000,

  /**
    @property isCacheExpired
    @type Boolean
  */
  isCacheExpired: Ember.computed('meta.timeStamps.local', 'cacheDuration', function () {
    const localTime = this.get('meta.timeStamps.local');
    const expiresTime = localTime + this.get('cacheDuration');
    return (localTime) ? Date.now() >= expiresTime : false;
  })
});

Resource.reopenClass({
  /**
    To protect the JSON API Resource properties for attributes, links and
    relationships these objects are setup during create(). This has to be
    defined since the attr() helper needs to have new objects for each instance,
    to project from keeping a reference on the prototype.

    The create method should only be called after looking up a factory from the
    container, for example in a route's model hook:

    ```
    model() {
      return this.container.lookupFactory('model:posts').create({
        attributes: {
          title: 'The JSON API 1.0 Spec Rocks!'
        }
      });
    }
    ```

    The create method uses the container to lookup the factory's prototype and
    find the computed properties used for relations to setup the relationships
    for the Resource instance you create. Calling Resource#create without using
    the factory lookup will result in an instance without a reference to the
    application's container and you will have to manually setup the relationships
    object prior to adding a relationship.

    @method create
    @return {Resource} instance with protected objects:
      `attributes`, `links` and `relationships`
  */
  create(properties) {
    const prototype = {};
    const attrs = Ember.String.w('_attributes attributes links meta relationships');
    for (let i = 0; i < attrs.length; i++) {
      prototype[attrs[i]] = {};
    }
    const instance = this._super(prototype);
    if (properties) {
      instance.setProperties(properties);
    }
    let type = instance.get('type');
    let msg = (type) ? Ember.String.capitalize(singularize(type)) : 'Resource';
    let factory = 'model:' + type;
    if (!type) {
      Ember.Logger.warn(msg + '#create called, instead you should first use ' + msg + '.extend({type:"entity"})');
    } else {
      if (instance.container) {
        useComputedPropsMetaToSetupRelationships(factory, instance);
      } else {
        msg += '#create should only be called from a container lookup (relationships not setup) ';
        msg += 'use this.container.lookupFactory("' + factory + '").create() instead.';
        Ember.Logger.warn(msg);
      }
    }
    return instance;
  }
});

export default Resource;

export { attr, hasOne, hasMany };

let _rp = 'service type id attributes relationships links meta _attributes isNew cacheDuration isCacheExpired';
const ignoredMetaProps = _rp.split(' ');

function useComputedPropsMetaToSetupRelationships(factory, instance) {
  factory = instance.container.lookupFactory(factory);
  factory.eachComputedProperty(function(prop) {
    if (ignoredMetaProps.indexOf(prop) > -1) { return; }
    try {
      let meta = factory.metaForProperty(prop);
      if (meta && meta.kind) {
        if (meta.kind === 'hasOne') {
          setupRelationship.call(instance, prop);
        } else if (meta.kind === 'hasMany') {
          setupRelationship.call(instance, prop, Ember.A([]));
        }
      }
    } catch (e) {
      return; // metaForProperty has an assertion that may throw
    }
  });
}

function setupRelationship(relation, data = null) {
  if (!this.relationships[relation]) {
    this.relationships[relation] = { links: {}, data: data };
  }
  if (!this.relationships[relation].links) {
    this.relationships[relation].links = {};
  }
  if (!this.relationships[relation].data) {
    this.relationships[relation].data = data;
  }
}

function unique(superSet, subSet) {
  let intersection = superSet.filter(function (item) {
    return subSet.indexOf(item) !== -1;
  });
  let _unique = superSet.filter(function (item) {
    return intersection.indexOf(item) === -1;
  });
  return (unique.length) ? _unique : subSet;
}
<commit_msg>Fix updating an resource relations when empty<commit_after>/**
  @module ember-jsonapi-resources
  @submodule resource
**/

import Ember from 'ember';
import { pluralize, singularize } from 'ember-inflector';
import attr from 'ember-jsonapi-resources/utils/attr';
import hasOne from 'ember-jsonapi-resources/utils/has-one';
import hasMany from 'ember-jsonapi-resources/utils/has-many';
import { isType } from 'ember-jsonapi-resources/utils/is';

/**
  A Resource class to create JSON API resource objects

  See <http://jsonapi.org/format/#document-resource-objects>

  @class Resource
  @requires Ember.Inflector
  @static
*/
const Resource = Ember.Object.extend({

  /**
    The service object for the entity (adapter with cache and serializer)

    @property service
    @type Object
    @required
  */
  service: null,

  /**
    Extending Prototypes Must define a `type` value for the entity, e.g. `posts`

    @property type
    @type String
    @required
  */
  type: null,

  /**
    Persisted resource ID value

    @property id
    @type String
    @required
  */
  id: null,

  /**
    An optional `attributes` property of for a JSON API Resource object, setup in create()

    This object will keep the values from the response object and may be mutable
    Use this as a refence for creating computed properties

    For example the `attr()` helper sets up a properties based on this content

    @protected
    @property attributes
    @type Object
  */
  attributes: null,

  /**
    An optional `relationships` property of for a JSON API Resource object, setup in create()

    @protected
    @property relationships
    @type Object
  */
  relationships: null,

  /**
    An optional `links` property of for a JSON API Resource object, setup in create()

    @protected
    @property links
    @type Object
  */
  links: null,

  /**
    An optional property of for a JSON API Resource object, setup in create()

    @protected
    @property meta
    @type Object
  */
  meta: null,

  /**
    Hash of attributes for changed/previous values

    @private
    @property _attributes
    @type Object
  */
  _attributes: null,

  /**
    Flag for new instance, e.g. not peristed

    @property isNew
    @type Boolean
  */
  isNew: false,

  /**
    Custom `toString` method used for clarity that the instance is a JSON API Resource kind of object

    @method toString
  */
  toString() {
    let type = this.get('type') || 'null';
    let id = this.get('id') || 'null';
    return `[JSONAPIResource|${type}:${id}]`;
  },

  /**
    Update a relation by adding or removing using a list, id, or null. When
    adding an id for a to-many relation send one or more ids, include the
    existing ids as well. When removing from a to-many relation pass the ids
    that should remain, missing ids will be removed, or remove all with an empty
    array. When operating on a to-one relation just use the id to change the
    relation, or null to remove.

    This is not a replace operation, but rather support for editing as a set.

    @method updateRelationship
    @param {String} relation
    @param {Array|String|null} ids
  */
  updateRelationship(relation, ids) {
    let relationshipData = 'relationships.' + relation + '.data';
    let existing;
    if (!Array.isArray(ids)) {
      existing = this.get(relationshipData).id;
      this.removeRelationship(relation, existing);
      if (isType('string', ids)) {
        this.addRelationship(relation, ids);
      }
    } else {
      existing = this.get(relationshipData).map(function(rel) { return rel.id; });
      if (!existing.length) {
        this.addRelationship(relation, ids);
      } else if (ids.length > existing.length) {
        this.addRelationships(relation, unique(ids, existing));
      } else if (existing.length > ids.length) {
        this.removeRelationships(relation, unique(existing, ids));
      }
    }
    return this.get('service').patchRelationship(this, relation);
  },

  /**
    @method addRelationships
    @param {String} related - resource name
    @param {Array} ids
  */
  addRelationships(related, ids) {
    for (let i = 0; i < ids.length; i++) {
      this.addRelationship(related, ids[i]);
    }
  },

  /**
    @method removeRelationships
    @param {String} related - resource name
    @param {Array} ids
  */
  removeRelationships(related, ids) {
    for (let i = 0; i < ids.length; i++) {
      this.removeRelationship(related, ids[i]);
    }
  },

  /**
    Adds related links object on the relationship hash

    @method addRelationship
    @param {String} related - resource name
    @param {String} id
  */
  addRelationship(related, id) {
    const key = ['relationships', related, 'data'].join('.');
    let data = this.get(key);
    const type = pluralize(related);
    const linkage = { type: type, id: id };
    if (Array.isArray(data)) {
      data.push(linkage);
    } else {
      data = linkage;
    }
    return this.set(key, data);
  },

  /**
    Remove related links object on the relationship hash to have `null` data

    @method removeRelationship
    @param {String} related - resource name
    @param {String} id
  */
  removeRelationship(related, id) {
    let relation = this.get('relationships.' + related);
    if (Array.isArray(relation.data)) {
      for (let i = 0; i < relation.data.length; i++) {
        if (relation.data[i].id === id) {
          relation.data.splice(i, 1);
          break;
        }
      }
    } else if (typeof relation === 'object') {
      relation.data = null;
    }
  },

  /**
    @method changedAttributes
    @return {Object} the changed attributes
  */
  changedAttributes: Ember.computed('attributes', {
    get: function () {
      const attrs = {};
      for (let key in this._attributes) {
        if (this._attributes.hasOwnProperty(key)) {
          if (this._attributes[key].changed !== this._attributes[key].previous) {
            attrs[key] = this._attributes[key].changed;
          }
        }
      }
      return attrs;
    }
  }).volatile(),

  /**
    @method previousAttributes
    @return {Object} the previous attributes
  */
  previousAttributes: Ember.computed('attributes', {
    get: function () {
      const attrs = {};
      for (let key in this._attributes) {
        if (this._attributes.hasOwnProperty(key)) {
          if (this._attributes[key].changed !== this._attributes[key].previous) {
            attrs[key] = this._attributes[key].previous;
          }
        }
      }
      return attrs;
    }
  }).volatile(),

  /**
    Initialize events to communicate with the service object, listen for `didUpdateResource`

    @method initEvents
  */
  initEvents: Ember.on('init', function () {
    const service = this.get('service');
    if (service) {
      service.on('didUpdateResource', this, this.didUpdateResource);
    }
  }),

  /**
    Handler for `didUpdateResource` event, resets private _attributes used for changed/previous tracking

    @method didUpdateResource
    @param json the updated data for the resource
  */
  didUpdateResource(json) {
    if (this.get('id') !== json.id) { return; }
    this.setProperties(json);
    for (let attr in this._attributes) {
      if (this._attributes.hasOwnProperty(attr)) {
        delete this._attributes[attr];
      }
    }
  },

  /**
    A local cache duration, to minimize duplicate fetch requests

    @property cacheDuration
    @type Number
  */
  cacheDuration: /* minutes */ 7 * /* seconds */ 60 * /* milliseconds */ 1000,

  /**
    @property isCacheExpired
    @type Boolean
  */
  isCacheExpired: Ember.computed('meta.timeStamps.local', 'cacheDuration', function () {
    const localTime = this.get('meta.timeStamps.local');
    const expiresTime = localTime + this.get('cacheDuration');
    return (localTime) ? Date.now() >= expiresTime : false;
  })
});

Resource.reopenClass({
  /**
    To protect the JSON API Resource properties for attributes, links and
    relationships these objects are setup during create(). This has to be
    defined since the attr() helper needs to have new objects for each instance,
    to project from keeping a reference on the prototype.

    The create method should only be called after looking up a factory from the
    container, for example in a route's model hook:

    ```
    model() {
      return this.container.lookupFactory('model:posts').create({
        attributes: {
          title: 'The JSON API 1.0 Spec Rocks!'
        }
      });
    }
    ```

    The create method uses the container to lookup the factory's prototype and
    find the computed properties used for relations to setup the relationships
    for the Resource instance you create. Calling Resource#create without using
    the factory lookup will result in an instance without a reference to the
    application's container and you will have to manually setup the relationships
    object prior to adding a relationship.

    @method create
    @return {Resource} instance with protected objects:
      `attributes`, `links` and `relationships`
  */
  create(properties) {
    const prototype = {};
    const attrs = Ember.String.w('_attributes attributes links meta relationships');
    for (let i = 0; i < attrs.length; i++) {
      prototype[attrs[i]] = {};
    }
    const instance = this._super(prototype);
    if (properties) {
      instance.setProperties(properties);
    }
    let type = instance.get('type');
    let msg = (type) ? Ember.String.capitalize(singularize(type)) : 'Resource';
    let factory = 'model:' + type;
    if (!type) {
      Ember.Logger.warn(msg + '#create called, instead you should first use ' + msg + '.extend({type:"entity"})');
    } else {
      if (instance.container) {
        useComputedPropsMetaToSetupRelationships(factory, instance);
      } else {
        msg += '#create should only be called from a container lookup (relationships not setup) ';
        msg += 'use this.container.lookupFactory("' + factory + '").create() instead.';
        Ember.Logger.warn(msg);
      }
    }
    return instance;
  }
});

export default Resource;

export { attr, hasOne, hasMany };

let _rp = 'service type id attributes relationships links meta _attributes isNew cacheDuration isCacheExpired';
const ignoredMetaProps = _rp.split(' ');

function useComputedPropsMetaToSetupRelationships(factory, instance) {
  factory = instance.container.lookupFactory(factory);
  factory.eachComputedProperty(function(prop) {
    if (ignoredMetaProps.indexOf(prop) > -1) { return; }
    try {
      let meta = factory.metaForProperty(prop);
      if (meta && meta.kind) {
        if (meta.kind === 'hasOne') {
          setupRelationship.call(instance, prop);
        } else if (meta.kind === 'hasMany') {
          setupRelationship.call(instance, prop, Ember.A([]));
        }
      }
    } catch (e) {
      return; // metaForProperty has an assertion that may throw
    }
  });
}

function setupRelationship(relation, data = null) {
  if (!this.relationships[relation]) {
    this.relationships[relation] = { links: {}, data: data };
  }
  if (!this.relationships[relation].links) {
    this.relationships[relation].links = {};
  }
  if (!this.relationships[relation].data) {
    this.relationships[relation].data = data;
  }
}

function unique(superSet, subSet) {
  let intersection = superSet.filter(function (item) {
    return subSet.indexOf(item) !== -1;
  });
  let _unique = superSet.filter(function (item) {
    return intersection.indexOf(item) === -1;
  });
  return (unique.length) ? _unique : subSet;
}
<|endoftext|>


<commit_before>var async      = require('async');
var mongoose   = require('mongoose');
var _          = require('underscore');
var sha1       = require('sha1');
var merkle     = require('merkle');
var Membership = mongoose.model('Membership');
var Amendment  = mongoose.model('Amendment');
var PublicKey  = mongoose.model('PublicKey');
var Merkle     = mongoose.model('Merkle');
var vucoin     = require('vucoin');

module.exports = function Synchroniser (host, port, authenticated, currency) {

  var VoteService       = require('../service/VoteService')(currency);
  var MembershipService = require('../service/MembershipService').get(currency);
  var StrategyService   = require('../service/StrategyService')();
  var that = this;

  this.sync = function (done) {
    console.log('Connecting remote host...');
    vucoin(host, port, authenticated, function (err, node) {
      if(err){
        done('Cannot sync: ' + err);
        return;
      }

      // Global sync vars
      var amendments = {};
      var remoteCurrentNumber;

      async.waterfall([
        function (next){
          console.log('Sync started.');
          next();
        },

        //============
        // Public Keys
        //============
        function (next){
          Merkle.forPublicKeys(next);
        },
        function (merkle, next) {
          node.pks.all({}, function (err, json) {
            var rm = new NodesMerkle(json);
            if(rm.root() != merkle.root()){
              // console.log('Merkles for public keys: differences !');
              var indexesToAdd = [];
              node.pks.all({ extract: true }, function (err, json) {
                _(json.merkle.leaves).keys().forEach(function(key){
                  var leaf = json.merkle.leaves[key];
                  if(merkle.leaves().indexOf(leaf.hash) == -1){
                    indexesToAdd.push(key);
                  }
                });
                var hashes = [];
                async.forEachSeries(indexesToAdd, function(index, callback){
                  hashes.push(json.merkle.leaves[index].hash);
                  PublicKey.persistFromRaw(json.merkle.leaves[index].value.pubkey, callback);
                }, function(err, result){
                  next(err);
                });
              });
            }
            else next();
          });
        },

        //============
        // Amendments
        //============
        function (next){
          Amendment.nextNumber(next);
        },
        function (number, next) {
          node.hdc.amendments.current(function (err, json) {
            if(err){
              next();
              return;
            }
            remoteCurrentNumber = parseInt(json.number);
            amendments[remoteCurrentNumber] = json.raw;
            var toGetNumbers = _.range(number, remoteCurrentNumber);
            async.forEachSeries(toGetNumbers, function(amNumber, callback){
              console.log("Fetching amendment #%s ...", amNumber);
              async.waterfall([
                function (cb){
                  if(!amendments[amNumber])
                    node.hdc.amendments.promoted(amNumber, cb);
                  else
                    cb(null, { raw: amendments[amNumber] });
                },
                function (am, cb){
                  amendments[amNumber] = am.raw;
                  // console.log('ID: %s-%s', amNumber, sha1(amendments[amNumber]).toUpperCase());
                  node.hdc.amendments.promoted(amNumber + 1, cb);
                },
                function (am, cb){
                  amendments[amNumber + 1] = am.raw;
                  // _(amendments).keys().forEach(function (key) {
                  //   console.log('=====> AM %s = %s', key, amendments[key] ? 'OK' : amendments[key]);
                  // });
                  cb();
                },
                function (cb) {
                  applyMemberships(amendments, amNumber, node, cb);
                },
                function (cb) {
                  node.hdc.amendments.view.signatures(amNumber + 1, sha1(amendments[amNumber + 1]).toUpperCase(), { extract: true }, cb);
                },
                function (json, cb){
                  applyVotes(amendments, amNumber, number, json, node, cb);
                },
                function (nextNumber, cb) {
                  number = nextNumber;
                  cb();
                }
              ], function (err, result) {
                callback(err);
              });
            }, function(err, result){
              next(err, number);
            });
          });
        },
        function (number, next) {
          if(number == remoteCurrentNumber){
            console.log('Synchronise current #%s ...', remoteCurrentNumber);
            // console.log(amendments[remoteCurrentNumber] + '---------------');
            // Synchronise remote's current
            async.waterfall([
              function (callback){
                applyMemberships(amendments, number, node, callback);
              },
              function (callback){
                node.hdc.community.votes({ extract: true }, callback);
              },
              function (json, callback) {
                applyVotes(amendments, number, number, json, node, callback);
              }
            ], function (err) {
              next(err);
            });
          }
          else next();
        },
        function (next) {
          node.hdc.community.memberships({ extract: true }, next);
        },
        function (json, next) {
          applyTargetedMemberships(json.merkle.leaves, function () { return true; }, next);
        }
      ], function (err, result) {
        console.log('Sync finished.');
        done(err);
      });
    })
  }

  function applyMemberships(amendments, amNumber, node, cb) {
    // console.log('Applying memberships for amendment #%s', amNumber);
    async.waterfall([
      function (next) {
        Merkle.forMembership(amNumber - 1, next);
      },
      function (prevMerkle, next) {
        Merkle.updateManyForNextMembership(prevMerkle.leaves(), next);
      },
      function (next) {
        node.hdc.amendments.view.memberships(amNumber, sha1(amendments[amNumber]).toUpperCase(), {}, next);
      },
      function (json, next){
        Merkle.forMembership(amNumber - 1, function (err, prevMerkle) {
          if(prevMerkle.root() != json.merkle.levels[0][0]){
            // console.log('MS CHANGES (%s != %s)', prevMerkle.root(), json.merkle.levels[0][0]);
            var difff = [];
            async.waterfall([
              function (callback2) {
                node.hdc.amendments.view.memberships(amNumber, sha1(amendments[amNumber]).toUpperCase(), { lstart: json.merkle.depth, lend: json.merkle.levelsCount }, callback2);
              },
              function (json2, callback2){
                var leaves = json2.merkle.levels[json2.merkle.levelsCount -1];
                difff = _(leaves).difference(prevMerkle.leaves());
                node.hdc.amendments.view.memberships(amNumber, sha1(amendments[amNumber]).toUpperCase(), { extract: true }, callback2);
              },
              function (json, callback2) {
                applyTargetedMemberships(json.merkle.leaves, function (hash) {
                  return ~difff.indexOf(hash);
                }, callback2);
              }
            ], cb);
          }
          else cb();
        });
      }
    ], function (err, result) {
    });
  }

  function applyTargetedMemberships(merkleUrlLeaves, isToApply, done) {
    // console.log("Source memberships: %s", _(merkleUrlLeaves).size());
    async.forEachSeries(_(merkleUrlLeaves).keys(), function(key, callback){
      var msObj = merkleUrlLeaves[key];
      if(isToApply(msObj.hash)){
        var ms = new Membership({});
        _(msObj.value.request).keys().forEach(function (field) {
          ms[field] = msObj.value.request[field];
        });
        var signedMSR = ms.getRaw() + msObj.value.signature;
        MembershipService.submit(signedMSR, callback);
      }
      else callback();
    }, function(err, result){
      if(err){
        done(err);
        return;
      }
      done();
    });
  }

  function applyVotes(amendments, amNumber, number, json, node, cb) {
    // console.log('Applying votes for amendment #%s', amNumber);
    // console.log("Signatures: %s", _(json.merkle.leaves).size());
    async.forEachSeries(_(json.merkle.leaves).keys(), function(key, callback){
      var vote = json.merkle.leaves[key];
      VoteService.submit(amendments[amNumber] + vote.value.signature, function (err, am) {
        // Promotion time
        StrategyService.tryToPromote(am, function (err) {
          if(!err)
            number++;
          callback();
        });
      });
    }, function(err, result){
      cb(err, number);
    });
  }
}

function NodesMerkle (json) {

  var that = this;
  ["depth", "nodesCount", "leavesCount", "levelsCount"].forEach(function (key) {
    that[key] = json.merkle[key];
  });

  var i = 0;
  this.levels = [];
  while(json.merkle && json.merkle.levels[i]){
    this.levels.push(json.merkle.levels[i]);
    i++;
  }

  this.root = function () {
    return this.levels.length > 0 ? this.levels[0][0] : '';
  }
}
<commit_msg>Adapt to new Merkle URLs<commit_after>var async      = require('async');
var mongoose   = require('mongoose');
var _          = require('underscore');
var sha1       = require('sha1');
var merkle     = require('merkle');
var Membership = mongoose.model('Membership');
var Amendment  = mongoose.model('Amendment');
var PublicKey  = mongoose.model('PublicKey');
var Merkle     = mongoose.model('Merkle');
var vucoin     = require('vucoin');

module.exports = function Synchroniser (host, port, authenticated, currency) {

  var VoteService       = require('../service/VoteService')(currency);
  var MembershipService = require('../service/MembershipService').get(currency);
  var StrategyService   = require('../service/StrategyService')();
  var that = this;

  this.sync = function (done) {
    console.log('Connecting remote host...');
    vucoin(host, port, authenticated, function (err, node) {
      if(err){
        done('Cannot sync: ' + err);
        return;
      }

      // Global sync vars
      var amendments = {};
      var remoteCurrentNumber;

      async.waterfall([
        function (next){
          console.log('Sync started.');
          next();
        },

        //============
        // Public Keys
        //============
        function (next){
          Merkle.forPublicKeys(next);
        },
        function (merkle, next) {
          node.pks.all({}, function (err, json) {
            var rm = new NodesMerkle(json);
            if(rm.root() != merkle.root()){
              // console.log('Merkles for public keys: differences !');
              var indexesToAdd = [];
              node.pks.all({ extract: true }, function (err, json) {
                _(json.leaves).keys().forEach(function(key){
                  var leaf = json.leaves[key];
                  if(merkle.leaves().indexOf(leaf.hash) == -1){
                    indexesToAdd.push(key);
                  }
                });
                var hashes = [];
                async.forEachSeries(indexesToAdd, function(index, callback){
                  hashes.push(json.leaves[index].hash);
                  PublicKey.persistFromRaw(json.leaves[index].value.pubkey, callback);
                }, function(err, result){
                  next(err);
                });
              });
            }
            else next();
          });
        },

        //============
        // Amendments
        //============
        function (next){
          Amendment.nextNumber(next);
        },
        function (number, next) {
          node.hdc.amendments.current(function (err, json) {
            if(err){
              next();
              return;
            }
            remoteCurrentNumber = parseInt(json.number);
            amendments[remoteCurrentNumber] = json.raw;
            var toGetNumbers = _.range(number, remoteCurrentNumber);
            async.forEachSeries(toGetNumbers, function(amNumber, callback){
              console.log("Fetching amendment #%s ...", amNumber);
              async.waterfall([
                function (cb){
                  if(!amendments[amNumber])
                    node.hdc.amendments.promoted(amNumber, cb);
                  else
                    cb(null, { raw: amendments[amNumber] });
                },
                function (am, cb){
                  amendments[amNumber] = am.raw;
                  // console.log('ID: %s-%s', amNumber, sha1(amendments[amNumber]).toUpperCase());
                  node.hdc.amendments.promoted(amNumber + 1, cb);
                },
                function (am, cb){
                  amendments[amNumber + 1] = am.raw;
                  // _(amendments).keys().forEach(function (key) {
                  //   console.log('=====> AM %s = %s', key, amendments[key] ? 'OK' : amendments[key]);
                  // });
                  cb();
                },
                function (cb) {
                  applyMemberships(amendments, amNumber, node, cb);
                },
                function (cb) {
                  node.hdc.amendments.view.signatures(amNumber + 1, sha1(amendments[amNumber + 1]).toUpperCase(), { extract: true }, cb);
                },
                function (json, cb){
                  applyVotes(amendments, amNumber, number, json, node, cb);
                },
                function (nextNumber, cb) {
                  number = nextNumber;
                  cb();
                }
              ], function (err, result) {
                callback(err);
              });
            }, function(err, result){
              next(err, number);
            });
          });
        },
        function (number, next) {
          if(number == remoteCurrentNumber){
            console.log('Synchronise current #%s ...', remoteCurrentNumber);
            // console.log(amendments[remoteCurrentNumber] + '---------------');
            // Synchronise remote's current
            async.waterfall([
              function (callback){
                applyMemberships(amendments, number, node, callback);
              },
              function (callback){
                node.hdc.community.votes({ extract: true }, callback);
              },
              function (json, callback) {
                applyVotes(amendments, number, number, json, node, callback);
              }
            ], function (err) {
              next(err);
            });
          }
          else next();
        },
        function (next) {
          node.hdc.community.memberships({ extract: true }, next);
        },
        function (json, next) {
          applyTargetedMemberships(json.leaves, function () { return true; }, next);
        }
      ], function (err, result) {
        console.log('Sync finished.');
        done(err);
      });
    })
  }

  function applyMemberships(amendments, amNumber, node, cb) {
    // console.log('Applying memberships for amendment #%s', amNumber);
    async.waterfall([
      function (next) {
        Merkle.forMembership(amNumber - 1, next);
      },
      function (prevMerkle, next) {
        Merkle.updateManyForNextMembership(prevMerkle.leaves(), next);
      },
      function (next) {
        node.hdc.amendments.view.memberships(amNumber, sha1(amendments[amNumber]).toUpperCase(), {}, next);
      },
      function (json, next){
        Merkle.forMembership(amNumber - 1, function (err, prevMerkle) {
          if(prevMerkle.root() != json.levels[0][0]){
            // console.log('MS CHANGES (%s != %s)', prevMerkle.root(), json.levels[0][0]);
            var difff = [];
            async.waterfall([
              function (callback2) {
                node.hdc.amendments.view.memberships(amNumber, sha1(amendments[amNumber]).toUpperCase(), { lstart: json.depth, lend: json.levelsCount }, callback2);
              },
              function (json2, callback2){
                var leaves = json2.levels[json2.levelsCount -1];
                difff = _(leaves).difference(prevMerkle.leaves());
                node.hdc.amendments.view.memberships(amNumber, sha1(amendments[amNumber]).toUpperCase(), { extract: true }, callback2);
              },
              function (json, callback2) {
                applyTargetedMemberships(json.leaves, function (hash) {
                  return ~difff.indexOf(hash);
                }, callback2);
              }
            ], cb);
          }
          else cb();
        });
      }
    ], function (err, result) {
    });
  }

  function applyTargetedMemberships(merkleUrlLeaves, isToApply, done) {
    // console.log("Source memberships: %s", _(merkleUrlLeaves).size());
    async.forEachSeries(_(merkleUrlLeaves).keys(), function(key, callback){
      var msObj = merkleUrlLeaves[key];
      if(isToApply(msObj.hash)){
        var ms = new Membership({});
        _(msObj.value.request).keys().forEach(function (field) {
          ms[field] = msObj.value.request[field];
        });
        var signedMSR = ms.getRaw() + msObj.value.signature;
        MembershipService.submit(signedMSR, callback);
      }
      else callback();
    }, function(err, result){
      if(err){
        done(err);
        return;
      }
      done();
    });
  }

  function applyVotes(amendments, amNumber, number, json, node, cb) {
    // console.log('Applying votes for amendment #%s', amNumber);
    // console.log("Signatures: %s", _(json.leaves).size());
    async.forEachSeries(_(json.leaves).keys(), function(key, callback){
      var vote = json.leaves[key];
      VoteService.submit(amendments[amNumber] + vote.value.signature, function (err, am) {
        // Promotion time
        StrategyService.tryToPromote(am, function (err) {
          if(!err)
            number++;
          callback();
        });
      });
    }, function(err, result){
      cb(err, number);
    });
  }
}

function NodesMerkle (json) {

  var that = this;
  ["depth", "nodesCount", "leavesCount", "levelsCount"].forEach(function (key) {
    that[key] = json[key];
  });

  var i = 0;
  this.levels = [];
  while(json && json.levels[i]){
    this.levels.push(json.levels[i]);
    i++;
  }

  this.root = function () {
    return this.levels.length > 0 ? this.levels[0][0] : '';
  }
}
<|endoftext|>