<commit_before>'use strict';

angular.module('arachne.controllers')

/**
 * Handles the layout for viewing a catalog.
 *
 * @author: Sebastian Cuy
 */
 .controller('CatalogController', ['$scope','$routeParams',
 	function($scope, $routeParams) {
 		$scope.id = $routeParams.id;
 	}
 ])

/**
 * Handles the layout for editing the catalog structure.
 *
 * @author: Sebastian Cuy, Oliver Bensch
 */
.controller('CatalogsController',['$scope', '$modal', 'authService', 'Entity', 'Catalog', 'CatalogEntry', '$http', 'arachneSettings',
	function ($scope, $modal, authService, Entity, Catalog, CatalogEntry, $http, arachneSettings) {

		$scope.catalogs = [];
		$scope.user = authService.getUser();

		$http.get(arachneSettings.dataserviceUri + '/userinfo/' + $scope.user.username).success(function(user) {
			$scope.user = user;
		});

		$scope.loading = 0;

		$scope.treeOptions = {
			dropped: function(event) {
				updateActiveCatalog();
			}
		}

		$scope.refreshCatalogs = function(){
			$scope.loading++;
			Catalog.query({full:false}, function(result) {
				$scope.loading--;
				$scope.catalogs = result;
				if (!$scope.activeCatalog) {
					$scope.setActiveCatalog($scope.catalogs[0]);
				}
			});
		}

		$scope.refreshCatalogs();

		$scope.setActiveCatalog = function(catalog) {
			createChildrenArray(catalog.root);
			$scope.activeCatalog = catalog;
		}

		$scope.addChild = function(entry) {
			if (!entry.children) {
				entry.children = [];
			}
			var editEntryModal = $modal.open({
				templateUrl: 'partials/Modals/editEntry.html'
			});
			editEntryModal.close = function(newEntry) {
				entry.children.push(newEntry);
				updateActiveCatalog();
				//$http.post(arachneSettings.dataserviceUri + "/catalogentry/" + entry.id +"/add", newEntry)
				editEntryModal.dismiss();
			}
		}

		$scope.toggle = function(scope) {
			scope.toggle();
		}

		$scope.remove = function(scope) {
			var deleteModal = $modal.open({
				templateUrl: 'partials/Modals/delete.html'
			});
			deleteModal.close = function() {
				scope.remove();
				updateActiveCatalog();
				deleteModal.dismiss();
			}
		}

		$scope.editEntry = function(entry) {
			var editEntryModal = $modal.open({
				templateUrl: 'partials/Modals/editEntry.html',
				controller: 'EditCatalogEntryController',
				resolve: { entry: function() { return entry } }
			});
			editEntryModal.close = function(newEntry) {
				entry = newEntry;
				updateActiveCatalog();
				editEntryModal.dismiss();
			}
		}

		$scope.createCatalog = function() {
			var catalogBuffer = {
				author: $scope.user.username
			};
			if($scope.user.firstname && $scope.user.lastname) {
				catalogBuffer.author = $scope.user.firstname + " " + $scope.user.lastname;
			}
			var editCatalogModal = $modal.open({
				templateUrl: 'partials/Modals/editCatalog.html',
				controller: 'EditCatalogController',
				resolve: { catalog: function() { return catalogBuffer } }
			});
			editCatalogModal.close = function(newCatalog) {
				newCatalog.public = false;
				Catalog.save({}, newCatalog, function(result) {
					$scope.catalogs.push(result);
					$scope.activeCatalog = result;
				});
				editCatalogModal.dismiss();
			}
		}

		$scope.editCatalog = function() {
			var editCatalogModal = $modal.open({
				templateUrl: 'partials/Modals/editCatalog.html',
				controller: 'EditCatalogController',
				resolve: { catalog: function() { return $scope.activeCatalog } }
			});
			editCatalogModal.close = function(newCatalog) {
				$scope.activeCatalog = newCatalog;
				Catalog.update({id: $scope.activeCatalog.id}, newCatalog);
				editCatalogModal.dismiss();
			}
		}

		$scope.removeCatalog = function() {
			var deleteModal = $modal.open({
				templateUrl: 'partials/Modals/delete.html'
			});
			deleteModal.close = function() {
				var index = $scope.catalogs.indexOf($scope.activeCatalog);
				$scope.catalogs.splice(index, 1);
				Catalog.remove({id: $scope.activeCatalog.id});
				$scope.activeCatalog = $scope.catalogs[0];
				deleteModal.dismiss();
			}
		}

		$scope.expandAll = function() {
			getRootNodesScope().expandAll();
		}

		$scope.collapseAll = function(entry) {
			getRootNodesScope().collapseAll();
		}

		function updateActiveCatalog() {
			for(var i = $scope.offset; i<=($scope.offset+$scope.pageSize); i++){
				$scope.originalCatalog.root.children[i] = $scope.activeCatalog.root.children[i-$scope.offset];
			}
			Catalog.update({ id: $scope.activeCatalog.id }, $scope.activeCatalog);
		}

		function getRootNodesScope() {
			return angular.element(document.getElementById("tree-root")).scope();
		}

		// recursively creates empty children arrays
		// needed to enable dragging to entries without children
		// see https://github.com/angular-ui-tree/angular-ui-tree/issues/203
		function createChildrenArray(entry) {
			if (entry.children) {
				entry.children.forEach(function(child) {
					if (!child.hasChildren) child.children = [];
					else createChildrenArray(child);
				});
			}
		}

	}
])<commit_msg>fixed catalog entry creation (closes #2347)<commit_after>'use strict';

angular.module('arachne.controllers')

/**
 * Handles the layout for viewing a catalog.
 *
 * @author: Sebastian Cuy
 */
 .controller('CatalogController', ['$scope','$routeParams',
 	function($scope, $routeParams) {
 		$scope.id = $routeParams.id;
 	}
 ])

/**
 * Handles the layout for editing the catalog structure.
 *
 * @author: Sebastian Cuy, Oliver Bensch
 */
.controller('CatalogsController',['$scope', '$modal', 'authService', 'Entity', 'Catalog', 'CatalogEntry', '$http', 'arachneSettings',
	function ($scope, $modal, authService, Entity, Catalog, CatalogEntry, $http, arachneSettings) {

		$scope.catalogs = [];
		$scope.user = authService.getUser();

		$http.get(arachneSettings.dataserviceUri + '/userinfo/' + $scope.user.username).success(function(user) {
			$scope.user = user;
		});

		$scope.loading = 0;

		$scope.treeOptions = {
			dropped: function(event) {
				updateActiveCatalog();
			}
		}

		$scope.refreshCatalogs = function(){
			$scope.loading++;
			Catalog.query({full:false}, function(result) {
				$scope.loading--;
				$scope.catalogs = result;
				if (!$scope.activeCatalog) {
					$scope.setActiveCatalog($scope.catalogs[0]);
				}
			});
		}

		$scope.refreshCatalogs();

		$scope.setActiveCatalog = function(catalog) {
			createChildrenArray(catalog.root);
			$scope.activeCatalog = catalog;
		}

		$scope.addChild = function(entry) {
			if (!entry.children) {
				entry.children = [];
			}
			var editEntryModal = $modal.open({
				templateUrl: 'partials/Modals/editEntry.html'
			});
			editEntryModal.close = function(newEntry) {
				entry.children.push(newEntry);
				$http.post(arachneSettings.dataserviceUri + "/catalogentry/" + entry.id +"/add", newEntry);
				editEntryModal.dismiss();
			}
		}

		$scope.toggle = function(scope) {
			scope.toggle();
		}

		$scope.remove = function(scope) {
			var deleteModal = $modal.open({
				templateUrl: 'partials/Modals/delete.html'
			});
			deleteModal.close = function() {
				scope.remove();
				updateActiveCatalog();
				deleteModal.dismiss();
			}
		}

		$scope.editEntry = function(entry) {
			var editEntryModal = $modal.open({
				templateUrl: 'partials/Modals/editEntry.html',
				controller: 'EditCatalogEntryController',
				resolve: { entry: function() { return entry } }
			});
			editEntryModal.close = function(newEntry) {
				entry = newEntry;
				updateActiveCatalog();
				editEntryModal.dismiss();
			}
		}

		$scope.createCatalog = function() {
			var catalogBuffer = {
				author: $scope.user.username
			};
			if($scope.user.firstname && $scope.user.lastname) {
				catalogBuffer.author = $scope.user.firstname + " " + $scope.user.lastname;
			}
			var editCatalogModal = $modal.open({
				templateUrl: 'partials/Modals/editCatalog.html',
				controller: 'EditCatalogController',
				resolve: { catalog: function() { return catalogBuffer } }
			});
			editCatalogModal.close = function(newCatalog) {
				newCatalog.public = false;
				Catalog.save({}, newCatalog, function(result) {
					$scope.catalogs.push(result);
					$scope.activeCatalog = result;
				});
				editCatalogModal.dismiss();
			}
		}

		$scope.editCatalog = function() {
			var editCatalogModal = $modal.open({
				templateUrl: 'partials/Modals/editCatalog.html',
				controller: 'EditCatalogController',
				resolve: { catalog: function() { return $scope.activeCatalog } }
			});
			editCatalogModal.close = function(newCatalog) {
				$scope.activeCatalog = newCatalog;
				Catalog.update({id: $scope.activeCatalog.id}, newCatalog);
				editCatalogModal.dismiss();
			}
		}

		$scope.removeCatalog = function() {
			var deleteModal = $modal.open({
				templateUrl: 'partials/Modals/delete.html'
			});
			deleteModal.close = function() {
				var index = $scope.catalogs.indexOf($scope.activeCatalog);
				$scope.catalogs.splice(index, 1);
				Catalog.remove({id: $scope.activeCatalog.id});
				$scope.activeCatalog = $scope.catalogs[0];
				deleteModal.dismiss();
			}
		}

		$scope.expandAll = function() {
			getRootNodesScope().expandAll();
		}

		$scope.collapseAll = function(entry) {
			getRootNodesScope().collapseAll();
		}

		function updateActiveCatalog() {
			for(var i = $scope.offset; i<=($scope.offset+$scope.pageSize); i++){
				$scope.originalCatalog.root.children[i] = $scope.activeCatalog.root.children[i-$scope.offset];
			}
			Catalog.update({ id: $scope.activeCatalog.id }, $scope.activeCatalog);
		}

		function getRootNodesScope() {
			return angular.element(document.getElementById("tree-root")).scope();
		}

		// recursively creates empty children arrays
		// needed to enable dragging to entries without children
		// see https://github.com/angular-ui-tree/angular-ui-tree/issues/203
		function createChildrenArray(entry) {
			if (entry.children) {
				entry.children.forEach(function(child) {
					if (!child.hasChildren) child.children = [];
					else createChildrenArray(child);
				});
			}
		}

	}
])<|endoftext|>


<commit_before>import get from 'lodash/get';

const isFunction = val => typeof val === 'function';

export default (
  hooks = {
    before: {},
    after: {},
    beforeAll: null,
    afterAll: null,
  },
) => repository => {
  [
    'findById',
    'findOne',
    'findMany',
    'createOne',
    'createMany',
    'updateOne',
    'updateMany',
    'replaceOne',
    'deleteOne',
    'deleteMany',
    'save',
    'count',
    'query',
    'aggregate',
  ].forEach(method => {
    const previous = repository[method];
    const hasHooksForMethod =
      isFunction(hooks.beforeAll) ||
      isFunction(hooks.afterAll) ||
      ['before', 'after'].some(
        hookName =>
          Object.keys(hooks[hookName]).includes(method) && isFunction(hooks[hookName][method]),
      );

    if (!hasHooksForMethod) {
      return;
    }

    Object.assign(repository, {
      [method]: async (...args) => {
        if (typeof get(hooks, `before.${method}`) === 'function') {
          await hooks.before[method](...args);
        }

        if (typeof hooks.beforeAll === 'function') {
          await hooks.beforeAll(method, ...args);
        }

        const result = await previous.call(repository, ...args);

        if (typeof hooks.afterAll === 'function') {
          await hooks.afterAll(method, result, ...args);
        }

        if (typeof get(hooks, `after.${method}`) === 'function') {
          await hooks.after[method](result, ...args);
        }

        return result;
      },
    });
  });

  return repository;
};
<commit_msg>[oors-mongoDb] bugfix when checking if there is a hook method<commit_after>import get from 'lodash/get';

const isFunction = val => typeof val === 'function';

export default (
  hooks = {
    before: {},
    after: {},
    beforeAll: null,
    afterAll: null,
  },
) => repository => {
  [
    'findById',
    'findOne',
    'findMany',
    'createOne',
    'createMany',
    'updateOne',
    'updateMany',
    'replaceOne',
    'deleteOne',
    'deleteMany',
    'save',
    'count',
    'query',
    'aggregate',
  ].forEach(method => {
    const previous = repository[method];
    const hasHooksForMethod =
      isFunction(hooks.beforeAll) ||
      isFunction(hooks.afterAll) ||
      ['before', 'after'].some(
        hookName =>
          typeof hooks[hookName] === 'object' &&
          Object.keys(hooks[hookName]).includes(method) &&
          isFunction(hooks[hookName][method]),
      );

    if (!hasHooksForMethod) {
      return;
    }

    Object.assign(repository, {
      [method]: async (...args) => {
        if (typeof get(hooks, `before.${method}`) === 'function') {
          await hooks.before[method](...args);
        }

        if (typeof hooks.beforeAll === 'function') {
          await hooks.beforeAll(method, ...args);
        }

        const result = await previous.call(repository, ...args);

        if (typeof hooks.afterAll === 'function') {
          await hooks.afterAll(method, result, ...args);
        }

        if (typeof get(hooks, `after.${method}`) === 'function') {
          await hooks.after[method](result, ...args);
        }

        return result;
      },
    });
  });

  return repository;
};
<|endoftext|>


<commit_before>import _ from 'lodash';
import Promise from 'bluebird';
import Joi from 'joi';
import CustomError from 'customerror';

import UUIDType from './datatypes/UUID';
import StringType from './datatypes/String';
import EnumType from './datatypes/Enum';
import NumberType from './datatypes/Number';
import FloatType from './datatypes/Float';
import IntegerType from './datatypes/Integer';
import DateType from './datatypes/Date';

const Types = {
  uuid: UUIDType,
  string: StringType,
  enum: EnumType,
  number: NumberType,
  float: FloatType,
  integer: IntegerType,
  date: DateType
};

class Schema {

  /**
   * Creates a new Schema based on the specified definition object.
   * @param {Object} definition the definition object.
   * @constructor
   * @throws {TypeError} if definition object is invalid or unspecified.
   */
  constructor(definition: Object) {
    this.definition = _.mapValues(definition, (obj, key) => {
      // make sure obj is plain object
      if (!_.isPlainObject(obj)) {
        throw new TypeError(`Invalid schema definition for ${key}; expected plain object`);
      }

      // make sure obj is of valid type
      if (!Types.hasOwnProperty(obj.type)) {
        throw new TypeError(`Invalid datatype ${obj.type} for ${key}`);
      }

      // create new datatype
      const type = new Types[obj.type];

      // update datatype props
      _.forOwn(obj, (v, k) => {
        if (k === 'type') return;
        type[k] = v;
      });

      return type;
    });
  }

  toJSON() {
    return _.mapValues(this.definition, (datatype) => datatype.toJSON());
  }

  toJoi() {
    return Joi.object().strict(true).keys(_.mapValues(this.definition, (datatype) => datatype.toJoi()));
  }

  validate(record: Object, callback: ?Function) {
    if (!this.joi) this.joi = this.toJoi();

    return new Promise((resolve, reject) => {
      Joi.validate(record, this.joi, {convert: false}, (err, value) => {
        if (err) return reject(new CustomError(err, 'ValidationError'));
        resolve(value);
      });
    }).nodeify(callback);
  }

  toMetaData(): Object {
    return this.definition;
  }

  static fromMetaData(obj: Object): Schema {
    return new Schema(obj);
  }

}

export default Schema;
<commit_msg>Create method to expose the column names of the schema.<commit_after>import _ from 'lodash';
import Promise from 'bluebird';
import Joi from 'joi';
import CustomError from 'customerror';

import UUIDType from './datatypes/UUID';
import StringType from './datatypes/String';
import EnumType from './datatypes/Enum';
import NumberType from './datatypes/Number';
import FloatType from './datatypes/Float';
import IntegerType from './datatypes/Integer';
import DateType from './datatypes/Date';

const Types = {
  uuid: UUIDType,
  string: StringType,
  enum: EnumType,
  number: NumberType,
  float: FloatType,
  integer: IntegerType,
  date: DateType
};

class Schema {

  /**
   * Creates a new Schema based on the specified definition object.
   * @param {Object} definition the definition object.
   * @constructor
   * @throws {TypeError} if definition object is invalid or unspecified.
   */
  constructor(definition: Object) {
    this.definition = _.mapValues(definition, (obj, key) => {
      // make sure obj is plain object
      if (!_.isPlainObject(obj)) {
        throw new TypeError(`Invalid schema definition for ${key}; expected plain object`);
      }

      // make sure obj is of valid type
      if (!Types.hasOwnProperty(obj.type)) {
        throw new TypeError(`Invalid datatype ${obj.type} for ${key}`);
      }

      // create new datatype
      const type = new Types[obj.type];

      // update datatype props
      _.forOwn(obj, (v, k) => {
        if (k === 'type') return;
        type[k] = v;
      });

      return type;
    });
  }

  getColumnNames() {
    return _.keys(this.definition);
  }

  toJSON() {
    return _.mapValues(this.definition, (datatype) => datatype.toJSON());
  }

  toJoi() {
    return Joi.object().strict(true).keys(_.mapValues(this.definition, (datatype) => datatype.toJoi()));
  }

  validate(record: Object, callback: ?Function) {
    if (!this.joi) this.joi = this.toJoi();

    return new Promise((resolve, reject) => {
      Joi.validate(record, this.joi, {convert: false}, (err, value) => {
        if (err) return reject(new CustomError(err, 'ValidationError'));
        resolve(value);
      });
    }).nodeify(callback);
  }

  toMetaData(): Object {
    return this.definition;
  }

  static fromMetaData(obj: Object): Schema {
    return new Schema(obj);
  }

}

export default Schema;
<|endoftext|>


<commit_before>const User = require("../models/user");

function UserActivityController(app) {
    var controller = {
        userActivityTimes: {},

        update: function() {
            var pastTime = new Date().getTime() - (1000 * 60 * 3); // active users last did something in three minute span
            this.userActivityTimes = Object.keys(this.userActivityTimes).filter(u => this.userActivityTimes[u] > pastTime).reduce((obj, key) => {
                obj[key] = raw[key];
                return obj;
            }, {}).splice(0, 25);
            console.log("Updated user activity controller stored data.")
        },

        recordActivity: function(user) {
            this.userActivityTimes[user.id] = new Date().getTime();
        },

        getInfo: function() {
            return new Promise((resolve, reject) => {
                User.find({_id: { $in: Object.keys(this.userActivityTimes.splice(0, 25)) }}).then(users => {
                    var info = users.sort((a, b) => this.userActivityTimes[b._id] > this.userActivityTimes[a._id] ? 1 : -1).map(u => u.toInfo(app));
                    resolve(info);
                }).catch(err => reject(err));
            });
        }
    }
    setInterval(() => controller.update(), 1000 * 15); // 15 second update intervals
    return controller;
}

UserActivityController.prototype = Object.create(UserActivityController.prototype);

module.exports = UserActivityController;<commit_msg>lol fuck me and fuck last minute 'fixes'<commit_after>const User = require("../models/user");

function UserActivityController(app) {
    var controller = {
        userActivityTimes: {},

        update: function() {
            var pastTime = new Date().getTime() - (1000 * 60 * 3); // active users last did something in three minute span
            this.userActivityTimes = Object.keys(this.userActivityTimes).filter(u => this.userActivityTimes[u] > pastTime).splice(0, 25).reduce((obj, key) => {
                obj[key] = raw[key];
                return obj;
            }, {});
            console.log("Updated user activity controller stored data.")
        },

        recordActivity: function(user) {
            this.userActivityTimes[user.id] = new Date().getTime();
        },

        getInfo: function() {
            return new Promise((resolve, reject) => {
                User.find({_id: { $in: Object.keys(this.userActivityTimes).splice(0, 25) }}).then(users => {
                    var info = users.sort((a, b) => this.userActivityTimes[b._id] > this.userActivityTimes[a._id] ? 1 : -1).map(u => u.toInfo(app));
                    resolve(info);
                }).catch(err => reject(err));
            });
        }
    }
    setInterval(() => controller.update(), 1000 * 15); // 15 second update intervals
    return controller;
}

UserActivityController.prototype = Object.create(UserActivityController.prototype);

module.exports = UserActivityController;<|endoftext|>


<commit_before>import Code from '../../components/code'
import Layout from '../../components/layout'
import Link from '../../components/link'
import Subtitle from '../../components/subtitle'
import Title from '../../components/title'

export default () => (
  <Layout title="Installing Wilderness">
    <Title>
      Installation
    </Title>

      Wilderness is free and {' '}
      <Link href="https://github.com/colinmeinke/wilderness">open-source</Link>.

      It can be used as <Link href="#es2015-module">an ES2015 module</Link>,
      {' '} <Link href="#commonjs">required with commonjs</Link> or
      {' '} <Link href="#umd">loaded with a script element</Link>.

      Get Wilderness by installing the npm distribution:

    {`
yarn add wilderness
    `}

      or

    {`
npm --save wilderness
    `}

      Alternatively you can link to, or download, the distribution from
      the <Link href="https://unpkg.com/wilderness-core/">unpkg CDN</Link>.

    <Subtitle id="es2015-module">
      ES2015 module
    </Subtitle>

    {`
import { shape, timeline, render, play } from 'wilderness'
    `}

    <Subtitle id="commonjs">
      commonjs
    </Subtitle>

    {`
const { shape, timeline, render, play } = require('wilderness')
    `}

    <Subtitle id="umd">
      UMD
    </Subtitle>

      If you just want to drop a javascript file onto your page, then this is
      the method for you.

      Look in the dist directory of the distribution and
      select either the {' '}
      <Link href="https://unpkg.com/wilderness/dist/wilderness.development.js">development</Link>
      {' '} or {' '}
      <Link href="https://unpkg.com/wilderness/dist/wilderness.production.js">production</Link>
      {' '} file.

      Add a script tag linking to the file into your HTML layout,
      and you will then have access to the global Wilderness {' '}
      object.

    {`
const shape = Wilderness.shape
const timeline = Wilderness.timeline
const render = Wilderness.render
const play = Wilderness.play
    `}

      Now that we have Wilderness all ready to go, it's about time we learned
      how to use it!

    <Link href="/getting-started/create-a-shape" prefetch button>
      Next lesson: Create a shape
    </Link>
  </Layout>
)
<commit_msg>add code example of umd script installation<commit_after>import Code from '../../components/code'
import Layout from '../../components/layout'
import Link from '../../components/link'
import Subtitle from '../../components/subtitle'
import Title from '../../components/title'

export default () => (
  <Layout title="Installing Wilderness">
    <Title>
      Installation
    </Title>

      Wilderness is free and {' '}
      <Link href="https://github.com/colinmeinke/wilderness">open-source</Link>.

      It can be used as <Link href="#es2015-module">an ES2015 module</Link>,
      {' '} <Link href="#commonjs">required with commonjs</Link> or
      {' '} <Link href="#umd">loaded with a script element</Link>.

      Get Wilderness by installing the npm distribution:

    {`
yarn add wilderness
    `}

      or

    {`
npm --save wilderness
    `}

      Alternatively you can link to, or download, the distribution from
      the <Link href="https://unpkg.com/wilderness-core/">unpkg CDN</Link>.

    <Subtitle id="es2015-module">
      ES2015 module
    </Subtitle>

    {`
import { shape, timeline, render, play } from 'wilderness'
    `}

    <Subtitle id="commonjs">
      commonjs
    </Subtitle>

    {`
const { shape, timeline, render, play } = require('wilderness')
    `}

    <Subtitle id="umd">
      UMD
    </Subtitle>

      If you just want to drop a javascript file onto your page, then this is
      the method for you.

      Look in the dist directory of the distribution and
      select either the {' '}
      <Link href="https://unpkg.com/wilderness/dist/wilderness.development.js">development</Link>
      {' '} or {' '}
      <Link href="https://unpkg.com/wilderness/dist/wilderness.production.js">production</Link>
      {' '} file.

      Add a script tag linking to the file into your HTML
      layout.

    {`

    `}

      You will then have access to the global Wilderness {' '}
      object.

    {`
const shape = Wilderness.shape
const timeline = Wilderness.timeline
const render = Wilderness.render
const play = Wilderness.play
    `}

      Now that we have Wilderness all ready to go, it's about time we learned
      how to use it!

    <Link href="/getting-started/create-a-shape" prefetch button>
      Next lesson: Create a shape
    </Link>
  </Layout>
)
<|endoftext|>


<commit_before>// Copyright 2013-2016, University of Colorado Boulder

/**
 * A DerivedProperty is computed based on other Properties.  This implementation inherits from Property to (a) simplify
 * implementation and (b) ensure it remains consistent. Note that the setters should not be called directly, so the
 * setters (set, reset and es5 setter) throw an error if used directly.
 *
 * @author Sam Reid (PhET Interactive Simulations)
 */

define( function( require ) {
  'use strict';

  // modules
  var axon = require( 'AXON/axon' );
  var inherit = require( 'PHET_CORE/inherit' );
  var Property = require( 'AXON/Property' );
  var Tandem = require( 'TANDEM/Tandem' );
  var TDerivedProperty = require( 'AXON/TDerivedProperty' );

  function equalsFunction( a, b ) {
    return a === b;
  }

  function conjunctionWithProperty( value, property ) {
    return value && property.value;
  }

  function disjunctionWithProperty( value, property ) {
    return value || property.value;
  }

  /**
   * @param {Property[]} dependencies - Properties that this Property's value is derived from
   * @param {function} derivation - function that derives this Property's value, expects args in the same order as dependencies
   * @param {Object} [options] - see Property
   * @constructor
   */
  function DerivedProperty( dependencies, derivation, options ) {

    options = _.extend( {
      tandem: Tandem.tandemOptional()
    }, options );

    this.dependencies = dependencies; // @private

    var initialValue = derivation.apply( null, dependencies.map( function( property ) {return property.get();} ) );

    // We must pass supertype tandem to parent class so addInstance is called only once in the subclassiest constructor.
    Property.call( this, initialValue, _.extend( {}, options, {
      tandem: options.tandem && options.tandem.createSupertypeTandem()
    } ) );

    // @private - for disposal
    this.derivedPropertyTandem = options.tandem;

    var self = this;

    // @private Keep track of listeners so they can be detached
    this.dependencyListeners = [];

    for ( var i = 0; i < dependencies.length; i++ ) {
      var dependency = dependencies[ i ];
      (function( dependency ) {
        var listener = function() {
          Property.prototype.set.call( self, derivation.apply( null, dependencies.map( function( property ) {return property.get();} ) ) );
        };
        self.dependencyListeners.push( listener );
        dependency.lazyLink( listener );
      })( dependency, i );
    }

    // If running as phet-io and a tandem is supplied, register with tandem.
    options.tandem.supplied && options.tandem.addInstance( this, TDerivedProperty( options.phetioValueType ), options );
  }

  axon.register( 'DerivedProperty', DerivedProperty );

  return inherit( Property, DerivedProperty, {

    // @public
    dispose: function() {

      // Unlink from dependent Properties
      for ( var i = 0; i < this.dependencies.length; i++ ) {
        var dependency = this.dependencies[ i ];
        dependency.unlink( this.dependencyListeners[ i ] );
      }
      this.dependencies = null;
      this.dependencyListeners = null;

      this.derivedPropertyTandem.removeInstance( this );

      Property.prototype.dispose.call( this );
    },

    /**
     * Override the mutators to provide an error message.  These should not be called directly,
     * the value should only be modified when the dependencies change.
     * @param value
     * @override
     * @public
     */
    set: function( value ) { throw new Error( 'Cannot set values directly to a DerivedProperty, tried to set: ' + value ); },

    /**
     * Override the mutators to provide an error message.  These should not be called directly, the value should only be modified
     * when the dependencies change. Keep the newValue output in the string so the argument won't be stripped by minifier
     * (which would cause crashes like https://github.com/phetsims/axon/issues/15)
     * @param newValue
     * @override
     * @public
     */
    set value( newValue ) { throw new Error( 'Cannot es5-set values directly to a DerivedProperty, tried to set: ' + newValue ); },

    /**
     * Override get value as well to satisfy the linter which wants get/set pairs (even though it just uses the same code as the superclass).
     * @returns {*}
     * @override
     * @public
     */
    get value() {return Property.prototype.get.call( this );},

    /**
     * Override the mutators to provide an error message.  These should not be called directly,
     * the value should only be modified when the dependencies change.
     * @override
     * @public
     */
    reset: function() { throw new Error( 'Cannot reset a DerivedProperty directly' ); }
  }, {

    /**
     * Creates a derived boolean Property whose value is true iff firstProperty's value is equal to secondProperty's
     * value.
     * @public
     *
     * @param {Property.<*>} firstProperty
     * @param {Property.<*>} secondProperty
     * @param {Object} [options] - Forwarded to the DerivedProperty
     * @returns {DerivedProperty.<boolean>}
     */
    valueEquals: function( firstProperty, secondProperty, options ) {
      return new DerivedProperty( [ firstProperty, secondProperty ], equalsFunction, options );
    },

    /**
     * Creates a derived boolean Property whose value is true iff every input Property value is true.
     * @public
     *
     * @param {Array.<Property.<boolean>>} properties
     * @param {Object} [options] - Forwarded to the DerivedProperty
     * @returns {DerivedProperty.<boolean>}
     */
    and: function( properties, options ) {
      return new DerivedProperty( properties, _.reduce.bind( null, properties, conjunctionWithProperty, true ), options ); // TODO: fix
    },

    /**
     * Creates a derived boolean Property whose value is true iff any input Property value is true.
     * @public
     *
     * @param {Array.<Property.<boolean>>} properties
     * @param {Object} [options] - Forwarded to the DerivedProperty
     * @returns {DerivedProperty.<boolean>}
     */
    or: function( properties, options ) {
      return new DerivedProperty( properties, _.reduce.bind( null, properties, disjunctionWithProperty, false ), options );
    }
  } );
} );<commit_msg>move private functions after constructor<commit_after>// Copyright 2013-2016, University of Colorado Boulder

/**
 * A DerivedProperty is computed based on other Properties.  This implementation inherits from Property to (a) simplify
 * implementation and (b) ensure it remains consistent. Note that the setters should not be called directly, so the
 * setters (set, reset and es5 setter) throw an error if used directly.
 *
 * @author Sam Reid (PhET Interactive Simulations)
 */

define( function( require ) {
  'use strict';

  // modules
  var axon = require( 'AXON/axon' );
  var inherit = require( 'PHET_CORE/inherit' );
  var Property = require( 'AXON/Property' );
  var Tandem = require( 'TANDEM/Tandem' );
  var TDerivedProperty = require( 'AXON/TDerivedProperty' );

  /**
   * @param {Property[]} dependencies - Properties that this Property's value is derived from
   * @param {function} derivation - function that derives this Property's value, expects args in the same order as dependencies
   * @param {Object} [options] - see Property
   * @constructor
   */
  function DerivedProperty( dependencies, derivation, options ) {

    options = _.extend( {
      tandem: Tandem.tandemOptional()
    }, options );

    this.dependencies = dependencies; // @private

    var initialValue = derivation.apply( null, dependencies.map( function( property ) {return property.get();} ) );

    // We must pass supertype tandem to parent class so addInstance is called only once in the subclassiest constructor.
    Property.call( this, initialValue, _.extend( {}, options, {
      tandem: options.tandem && options.tandem.createSupertypeTandem()
    } ) );

    // @private - for disposal
    this.derivedPropertyTandem = options.tandem;

    var self = this;

    // @private Keep track of listeners so they can be detached
    this.dependencyListeners = [];

    for ( var i = 0; i < dependencies.length; i++ ) {
      var dependency = dependencies[ i ];
      (function( dependency ) {
        var listener = function() {
          Property.prototype.set.call( self, derivation.apply( null, dependencies.map( function( property ) {return property.get();} ) ) );
        };
        self.dependencyListeners.push( listener );
        dependency.lazyLink( listener );
      })( dependency, i );
    }

    // If running as phet-io and a tandem is supplied, register with tandem.
    options.tandem.supplied && options.tandem.addInstance( this, TDerivedProperty( options.phetioValueType ), options );
  }

  axon.register( 'DerivedProperty', DerivedProperty );

  function equalsFunction( a, b ) {
    return a === b;
  }

  function conjunctionWithProperty( value, property ) {
    return value && property.value;
  }

  function disjunctionWithProperty( value, property ) {
    return value || property.value;
  }

  return inherit( Property, DerivedProperty, {

    // @public
    dispose: function() {

      // Unlink from dependent Properties
      for ( var i = 0; i < this.dependencies.length; i++ ) {
        var dependency = this.dependencies[ i ];
        dependency.unlink( this.dependencyListeners[ i ] );
      }
      this.dependencies = null;
      this.dependencyListeners = null;

      this.derivedPropertyTandem.removeInstance( this );

      Property.prototype.dispose.call( this );
    },

    /**
     * Override the mutators to provide an error message.  These should not be called directly,
     * the value should only be modified when the dependencies change.
     * @param value
     * @override
     * @public
     */
    set: function( value ) { throw new Error( 'Cannot set values directly to a DerivedProperty, tried to set: ' + value ); },

    /**
     * Override the mutators to provide an error message.  These should not be called directly, the value should only be modified
     * when the dependencies change. Keep the newValue output in the string so the argument won't be stripped by minifier
     * (which would cause crashes like https://github.com/phetsims/axon/issues/15)
     * @param newValue
     * @override
     * @public
     */
    set value( newValue ) { throw new Error( 'Cannot es5-set values directly to a DerivedProperty, tried to set: ' + newValue ); },

    /**
     * Override get value as well to satisfy the linter which wants get/set pairs (even though it just uses the same code as the superclass).
     * @returns {*}
     * @override
     * @public
     */
    get value() {return Property.prototype.get.call( this );},

    /**
     * Override the mutators to provide an error message.  These should not be called directly,
     * the value should only be modified when the dependencies change.
     * @override
     * @public
     */
    reset: function() { throw new Error( 'Cannot reset a DerivedProperty directly' ); }
  }, {

    /**
     * Creates a derived boolean Property whose value is true iff firstProperty's value is equal to secondProperty's
     * value.
     * @public
     *
     * @param {Property.<*>} firstProperty
     * @param {Property.<*>} secondProperty
     * @param {Object} [options] - Forwarded to the DerivedProperty
     * @returns {DerivedProperty.<boolean>}
     */
    valueEquals: function( firstProperty, secondProperty, options ) {
      return new DerivedProperty( [ firstProperty, secondProperty ], equalsFunction, options );
    },

    /**
     * Creates a derived boolean Property whose value is true iff every input Property value is true.
     * @public
     *
     * @param {Array.<Property.<boolean>>} properties
     * @param {Object} [options] - Forwarded to the DerivedProperty
     * @returns {DerivedProperty.<boolean>}
     */
    and: function( properties, options ) {
      return new DerivedProperty( properties, _.reduce.bind( null, properties, conjunctionWithProperty, true ), options ); // TODO: fix
    },

    /**
     * Creates a derived boolean Property whose value is true iff any input Property value is true.
     * @public
     *
     * @param {Array.<Property.<boolean>>} properties
     * @param {Object} [options] - Forwarded to the DerivedProperty
     * @returns {DerivedProperty.<boolean>}
     */
    or: function( properties, options ) {
      return new DerivedProperty( properties, _.reduce.bind( null, properties, disjunctionWithProperty, false ), options );
    }
  } );
} );<|endoftext|>


<commit_before>// ==== DECLARATIONS ==== //
const express = require('express');
const request = require('request');
const helmet = require('helmet');
const RateLimit = require('express-rate-limit');
const limiter = new RateLimit({
	windowMs: 15 * 60 * 1000,
	max: 20,
	delayMs: 0
});
const app = express();

// ==== FUNCTIONS ==== //
/**
 * Set the options for querying CR
 * @param  {Response} query Query from the url
 * @return {Object}     Options for the query to CR
 */
function setOptions(query) {
	let options = {
		url: 'https://api.crunchyroll.com/start_session.0.json',
		qs: {
			version: '1.0', // eslint-disable-line
			access_token: 'Scwg9PRRZ19iVwD', // eslint-disable-line
			device_type: 'com.crunchyroll.crunchyroid', // eslint-disable-line
			device_id: generateId() // eslint-disable-line
		}
	};
	if (query.auth) {
		options.qs.auth = query.auth;
	}
	return options;
}

/**
 * Generate a random 32 character long device ID
 * @return {String} Generated device ID
 */
function generateId() {
	let id = '';
	const possible = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
	for (var i = 0; i < 32; i++) {
		id += possible.charAt(Math.floor(Math.random() * possible.length));
	}
	return id;
}

/**
 * Emit a negative reply containing an error message
 * @param  {Object} res  Reply object
 * @param  {String} err Error message
 */
function replyError(res, err) {
	res.status(500).send({
		message: err,
		code: 'error',
		error: true
	});
}

/**
 * Emit a positive reply containing data
 * @param  {Object} res  Reply object
 * @param  {Object} data Object containing the requested payload
 */
function replySuccess(res, data) {
	res.status(200).send(data);
}

// ==== ROUTING ==== //
// support for reverse proxy
app.enable('trust proxy');
// use the middleware
app.use(helmet());
app.use(limiter);
app.get('/start_session', (req, res) => {
	if (req.query.version === undefined || req.query.version === '1.0') {
		let options = setOptions(req.query);
		request(options, (error, response, body) => {
			replySuccess(res, JSON.parse(body));
		}).on('error', error => {
			console.log(`Error fetching ${options.url}: ${error}`);
			replyError(res, error);
		});
	} else {
		replyError(res, 'Invalid API version specified.');
	}
});
app.get('*', (req, res) => {
	replyError(res, 'Invalid API endpoint.');
});

// process.env.PORT lets the port be set by Heroku
var port = process.env.PORT || 3001; // eslint-disable-line
app.listen(port, () => {
	console.log(`Listening on port ${port}`);
});
<commit_msg>Disable cache for server and disallow cache for client<commit_after>// ==== DECLARATIONS ==== //
const express = require('express');
const request = require('request');
const helmet = require('helmet');
const RateLimit = require('express-rate-limit');
const limiter = new RateLimit({
	windowMs: 15 * 60 * 1000,
	max: 20,
	delayMs: 0
});
const app = express();

// ==== FUNCTIONS ==== //
/**
 * Set the options for querying CR
 * @param  {Response} query Query from the url
 * @return {Object}     Options for the query to CR
 */
function setOptions(query) {
	let options = {
		url: 'https://api.crunchyroll.com/start_session.0.json',
		qs: {
			version: '1.0', // eslint-disable-line
			access_token: 'Scwg9PRRZ19iVwD', // eslint-disable-line
			device_type: 'com.crunchyroll.crunchyroid', // eslint-disable-line
			device_id: generateId() // eslint-disable-line
		}
	};
	if (query.auth) {
		options.qs.auth = query.auth;
	}
	return options;
}

/**
 * Generate a random 32 character long device ID
 * @return {String} Generated device ID
 */
function generateId() {
	let id = '';
	const possible = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
	for (var i = 0; i < 32; i++) {
		id += possible.charAt(Math.floor(Math.random() * possible.length));
	}
	return id;
}

/**
 * Emit a negative reply containing an error message
 * @param  {Object} res  Reply object
 * @param  {String} err Error message
 */
function replyError(res, err) {
	res.status(500).send({
		message: err,
		code: 'error',
		error: true
	});
}

/**
 * Emit a positive reply containing data
 * @param  {Object} res  Reply object
 * @param  {Object} data Object containing the requested payload
 */
function replySuccess(res, data) {
	res.status(200).send(data);
}

// ==== ROUTING ==== //
// support for reverse proxy
app.enable('trust proxy');
app.disable('view cache');
// use the middleware
app.use(helmet());
app.use(helmet.noCache());
app.use(limiter);
app.get('/start_session', (req, res) => {
	if (req.query.version === undefined || req.query.version === '1.0') {
		let options = setOptions(req.query);
		request(options, (error, response, body) => {
			replySuccess(res, JSON.parse(body));
		}).on('error', error => {
			console.log(`Error fetching ${options.url}: ${error}`);
			replyError(res, error);
		});
	} else {
		replyError(res, 'Invalid API version specified.');
	}
});
app.get('*', (req, res) => {
	replyError(res, 'Invalid API endpoint.');
});

// process.env.PORT lets the port be set by Heroku
var port = process.env.PORT || 3001; // eslint-disable-line
app.listen(port, () => {
	console.log(`Listening on port ${port}`);
});
<|endoftext|>


<commit_before>iD.ui.TagEditor = function(context) {
    var event = d3.dispatch('changeTags', 'choose', 'close'),
        presets = context.presets(),
        entity,
        tags,
        name,
        preset,
        selection_,
        presetUI,
        tagList;

    function tageditor(selection, newpreset) {

        entity = selection.datum();
        selection_ = selection;
        geometry = entity.geometry(context.graph());

        // preset was explicitly chosen
        if (newpreset) {
            if (preset) {
                tags = preset.removeTags(tags, geometry);
            }

            newpreset.applyTags(tags, geometry);
            preset = newpreset;

        // find a preset that best fits
        } else if (!preset) {
            preset = presets.matchType(entity, context.graph()).matchTags(entity);
        }

        selection.html('');

        var messagewrap = selection.append('div')
            .attr('class', 'message inspector-inner fillL');

        var message = messagewrap.append('h3')
            .text(t('inspector.choose'));

        var editorwrap = selection.append('div')
            .attr('class', 'tag-wrap inspector-body ' + entity.geometry(context.graph()));

        var headerwrap = editorwrap.append('div').attr('class','col12 inspector-inner head');

        var typewrap = headerwrap.append('div')
            .attr('class','col3 type');

        var typebutton = typewrap.append('button')
            .attr('class','col12')
            .on('click', function() {
                event.choose();
            });

        typebutton.append('div')
            .attr('class', 'icon icon-pre-text' + (preset ?  ' preset-' + preset.icon : ''));

        typebutton.node().focus();

         var namewrap = headerwrap.append('div')
             .attr('class', 'name col9');

        typebutton.append('span')
            .attr('class','label')
            .text(preset.name);

        namewrap.append('h4').text(t('inspector.name'));

        name = namewrap.append('input')
            .attr('placeholder', 'unknown')
            .attr('class', 'major')
            .attr('type', 'text')
            .property('value', entity.tags.name || '')
            .on('blur', function() {
                event.changeTags();
            });

        presetUI = iD.ui.preset(context)
            .entity(entity)
            .on('change', function() {
                event.changeTags();
            });

        tagList = iD.ui.Taglist(context)
            .on('change', function() {
                event.changeTags();
            });

        var tageditorpreset = editorwrap.append('div')
            .attr('class', 'inspector-preset');

        if (preset) {
            tageditorpreset.call(presetUI
                .preset(preset));
        }

        message.text(t('inspector.editing', { type: preset.name }));

        editorwrap.append('div')
            .attr('class','inspector-inner col12 fillL2').call(tagList, preset.name === 'other');

        selection.append('div')
            .attr('class', 'inspector-actions pad1 fillD col12')
            .call(drawButtons);

        tageditor.tags(tags);

        event.changeTags();
    }

    function apply() {
        event.changeTags();
        event.close();
    }

    function drawButtons(selection) {

        var inspectorButton = selection.append('button')
            .attr('class', 'apply action')
            .on('click', apply);

        inspectorButton.append('span')
            .attr('class','label')
            .text(t('inspector.okay'));

        var minorButtons = selection.append('div')
            .attr('class','minor-buttons fl');

        // Don't add for created entities
        if (entity.osmId() > 0) {
            minorButtons.append('a')
                .attr('href', 'http://www.openstreetmap.org/browse/' + entity.type + '/' + entity.osmId())
                .attr('target', '_blank')
                .text(t('inspector.view_on_osm'));
        }
    }

    tageditor.tags = function(newtags) {
        if (!arguments.length) {
            tags = _.extend(presetUI.tags(), tagList.tags());
            if (name.property('value')) tags.name = name.property('value');
            return tags;
        } else {
            tags = _.clone(newtags);
            if (presetUI && tagList) {

                // change preset if necessary (undos/redos)
                var newmatch = presets.matchType(entity, context.graph()).matchTags(entity.update({ tags: tags }));
                if (newmatch !== preset) {
                    return tageditor(selection_, newmatch);
                }

                name.property('value', tags.name || '');
                presetUI.change(tags);
                tagList.tags(_.omit(tags, _.keys(presetUI.tags() || {}).concat(['name'])));
            }
            return tageditor;
        }
    };

    return d3.rebind(tageditor, event, 'on');
};
<commit_msg>fix leaking global<commit_after>iD.ui.TagEditor = function(context) {
    var event = d3.dispatch('changeTags', 'choose', 'close'),
        presets = context.presets(),
        entity,
        tags,
        name,
        preset,
        selection_,
        presetUI,
        tagList;

    function tageditor(selection, newpreset) {

        entity = selection.datum();
        selection_ = selection;
        var geometry = entity.geometry(context.graph());

        // preset was explicitly chosen
        if (newpreset) {
            if (preset) {
                tags = preset.removeTags(tags, geometry);
            }

            newpreset.applyTags(tags, geometry);
            preset = newpreset;

        // find a preset that best fits
        } else if (!preset) {
            preset = presets.matchType(entity, context.graph()).matchTags(entity);
        }

        selection.html('');

        var messagewrap = selection.append('div')
            .attr('class', 'message inspector-inner fillL');

        var message = messagewrap.append('h3')
            .text(t('inspector.choose'));

        var editorwrap = selection.append('div')
            .attr('class', 'tag-wrap inspector-body ' + entity.geometry(context.graph()));

        var headerwrap = editorwrap.append('div').attr('class','col12 inspector-inner head');

        var typewrap = headerwrap.append('div')
            .attr('class','col3 type');

        var typebutton = typewrap.append('button')
            .attr('class','col12')
            .on('click', function() {
                event.choose();
            });

        typebutton.append('div')
            .attr('class', 'icon icon-pre-text' + (preset ?  ' preset-' + preset.icon : ''));

        typebutton.node().focus();

         var namewrap = headerwrap.append('div')
             .attr('class', 'name col9');

        typebutton.append('span')
            .attr('class','label')
            .text(preset.name);

        namewrap.append('h4').text(t('inspector.name'));

        name = namewrap.append('input')
            .attr('placeholder', 'unknown')
            .attr('class', 'major')
            .attr('type', 'text')
            .property('value', entity.tags.name || '')
            .on('blur', function() {
                event.changeTags();
            });

        presetUI = iD.ui.preset(context)
            .entity(entity)
            .on('change', function() {
                event.changeTags();
            });

        tagList = iD.ui.Taglist(context)
            .on('change', function() {
                event.changeTags();
            });

        var tageditorpreset = editorwrap.append('div')
            .attr('class', 'inspector-preset');

        if (preset) {
            tageditorpreset.call(presetUI
                .preset(preset));
        }

        message.text(t('inspector.editing', { type: preset.name }));

        editorwrap.append('div')
            .attr('class','inspector-inner col12 fillL2').call(tagList, preset.name === 'other');

        selection.append('div')
            .attr('class', 'inspector-actions pad1 fillD col12')
            .call(drawButtons);

        tageditor.tags(tags);

        event.changeTags();
    }

    function apply() {
        event.changeTags();
        event.close();
    }

    function drawButtons(selection) {

        var inspectorButton = selection.append('button')
            .attr('class', 'apply action')
            .on('click', apply);

        inspectorButton.append('span')
            .attr('class','label')
            .text(t('inspector.okay'));

        var minorButtons = selection.append('div')
            .attr('class','minor-buttons fl');

        // Don't add for created entities
        if (entity.osmId() > 0) {
            minorButtons.append('a')
                .attr('href', 'http://www.openstreetmap.org/browse/' + entity.type + '/' + entity.osmId())
                .attr('target', '_blank')
                .text(t('inspector.view_on_osm'));
        }
    }

    tageditor.tags = function(newtags) {
        if (!arguments.length) {
            tags = _.extend(presetUI.tags(), tagList.tags());
            if (name.property('value')) tags.name = name.property('value');
            return tags;
        } else {
            tags = _.clone(newtags);
            if (presetUI && tagList) {

                // change preset if necessary (undos/redos)
                var newmatch = presets.matchType(entity, context.graph()).matchTags(entity.update({ tags: tags }));
                if (newmatch !== preset) {
                    return tageditor(selection_, newmatch);
                }

                name.property('value', tags.name || '');
                presetUI.change(tags);
                tagList.tags(_.omit(tags, _.keys(presetUI.tags() || {}).concat(['name'])));
            }
            return tageditor;
        }
    };

    return d3.rebind(tageditor, event, 'on');
};
<|endoftext|>


<commit_before>const commando = require('../../../src');
const oneLine = require('common-tags').oneLine;

module.exports = class AddNumbersCommand extends commando.Command {
	constructor(client) {
		super(client, {
			name: 'add-numbers',
			aliases: ['add', 'add-nums'],
			group: 'math',
			memberName: 'add',
			description: 'Adds numbers together.',
			usage: 'add-numbers <number> [number2] [number3...]',
			details: oneLine`
				This is an incredibly useful command that finds the sum of numbers.
				This command is the envy of all other commands.
			`,
			examples: ['add-numbers 42 1337'],
			argsType: 'multiple'
		});
	}

	async run(msg, args) {
		if(!args[0]) throw new commando.CommandFormatError(msg);
		const total = args.reduce((prev, arg) => prev + parseFloat(arg), 0);
		return msg.reply(`**Sum:** ${total}`);
	}
};
<commit_msg>Fixed addnums usage<commit_after>const commando = require('../../../src');
const oneLine = require('common-tags').oneLine;

module.exports = class AddNumbersCommand extends commando.Command {
	constructor(client) {
		super(client, {
			name: 'add-numbers',
			aliases: ['add', 'add-nums'],
			group: 'math',
			memberName: 'add',
			description: 'Adds numbers together.',
			usage: '<number> [number2] [number3...]',
			details: oneLine`
				This is an incredibly useful command that finds the sum of numbers.
				This command is the envy of all other commands.
			`,
			examples: ['add-numbers 42 1337'],
			argsType: 'multiple'
		});
	}

	async run(msg, args) {
		if(!args[0]) throw new commando.CommandFormatError(msg);
		const total = args.reduce((prev, arg) => prev + parseFloat(arg), 0);
		return msg.reply(`**Sum:** ${total}`);
	}
};
<|endoftext|>


<commit_before>/*
*   Required Props:
*   key: string,
*   item: object
*
*   Required simpleState:
*   cards
*/

import React, {Component} from 'react'
import Inputcounter from '../../Inputcounter/Inputcounter'
import Divider from 'material-ui/Divider'
import Styles from './Cardwithcounter.css.js'
import SimpleState from 'react-simple-state'
import {
  Card,
  CardActions,
  CardText,
  CardMedia,
  CardTitle
} from 'material-ui/Card';

const simpleState = new SimpleState()

class card extends Component {
  constructor(props) {
    super(props);
    this.state = {
      count: 0
    }
  }

  up(e) {
    this.setState({
      count: this.state.count + 1
    });
  }
  down(e) {
    if (this.state.count > 0) {
      this.setState({
        count: this.state.count - 1
      });
    }
  }
  componentDidMount() {
    simpleState.evoke("loader", false)
  }
  componentDidUpdate() {
    let cardState = simpleState.getState("cards")
    const index = cardState.list.map(function(e) { return e.key; }).indexOf(this.props.item.key);
    if(index !== -1){
      cardState.list[index]= {key: this.props.item.key,count: this.state.count}
    }else{
      cardState.list.push({key: this.props.item.key,count: this.state.count})
    }
    simpleState.evoke("cards", {
      list: cardState.list
    });
  }

  render() {
    let item = this.props.item

    return (

        <Divider/>
        <Card>
          <CardMedia overlay={< CardTitle title={
            item.cardHeader
          } />}>

          </CardMedia>
          <CardTitle
            subtitle="Expand for Description"
            actAsExpander={true}
            showExpandableButton={true}/>
          <CardText expandable={true}>
            {item.description}
          </CardText>
          <CardActions>
            <Inputcounter count={this.state.count} up={this.up.bind(this)} down={this.down.bind(this)}/>
          </CardActions>
        </Card>

    )
  }
}

export default card<commit_msg>cahnged fasle var name<commit_after>/*
*   Required Props:
*   key: string,
*   item: object
*
*   Required simpleState:
*   cards
*/

import React, {Component} from 'react'
import Inputcounter from '../../Inputcounter/Inputcounter'
import Divider from 'material-ui/Divider'
import Styles from './Cardwithcounter.css.js'
import SimpleState from 'react-simple-state'
import {
  Card,
  CardActions,
  CardText,
  CardMedia,
  CardTitle
} from 'material-ui/Card';

const simpleState = new SimpleState()

class card extends Component {
  constructor(props) {
    super(props);
    this.state = {
      count: 0
    }
  }

  up(e) {
    this.setState({
      count: this.state.count + 1
    });
  }
  down(e) {
    if (this.state.count > 0) {
      this.setState({
        count: this.state.count - 1
      });
    }
  }
  componentDidMount() {
    simpleState.evoke("loader", false)
  }
  componentDidUpdate() {
    let cardState = simpleState.getState("cards")
    const index = cardState.list.map(function(e) { return e.key; }).indexOf(this.props.item.key);
    if(index !== -1){
      cardState.list[index]= {key: this.props.item.key,count: this.state.count}
    }else{
      cardState.list.push({key: this.props.item.key,count: this.state.count})
    }
    simpleState.evoke("cards", {
      list: cardState.list
    });
  }

  render() {
    let item = this.props.item

    return (

        <Divider/>
        <Card>
          <CardMedia overlay={< CardTitle title={
            item.name
          } />}>

          </CardMedia>
          <CardTitle
            subtitle="Expand for Description"
            actAsExpander={true}
            showExpandableButton={true}/>
          <CardText expandable={true}>
            {item.description}
          </CardText>
          <CardActions>
            <Inputcounter count={this.state.count} up={this.up.bind(this)} down={this.down.bind(this)}/>
          </CardActions>
        </Card>

    )
  }
}

export default card<|endoftext|>


<commit_before>var questions = [
  "Worin besteht das Problem?",
  "Wann tritt das Problem auf?",
  "Welche Ressourcen habe ich momentan zur Verfügung um das Problem zu lösen?",
  "Welche Menschen können mir dabei helfen, das Problem zu lösen?",
  "Wann habe ich das letzte Mal intensiv über dieses Problem nachgedacht?",
  "Auf welche Ressourcen würden mich andere hinweisen?",
  "Was würde ich mir raten, wenn ich Berater wär?",
  "Was müsste ich tun, um eine Lösung des Problems zu verhindern?",
  "Wer konnte mir bei meinem letzten Problem helfen?",
  "Welchen Nutzen habe ich von dem Problem?",
  "Was wäre der nächste Schritt, den ich gehen könnte, um das Problem zu lösen?",
  "Wie würde es sein, wenn das Problem gelöst wäre?",
  "Für wen würde sich etwas ändern, wenn das Problem gelöst wäre?",
  "Wer ist alles von dem Problem betroffen?",
  "Was würde passieren, wenn ich das Problem nicht angehen würde?",
  "Wann habe ich mich das letzte Mal bei einem Menschen für etwas bedankt?",
  "Wann war ich das letzte Mal an der frischen Luft unterwegs?",
  "Welche Frage stelle ich mir eigentlich gerade?",
  "Wie schlimm ist mein altuelles Problem?",
  "Was treibt mich an?",
  "Warum bin ich auf dieser Seite?",
  "Unter welchen Bedingungen kann ich am besten über etwas nachdenken?",
  "Was würde mir ein Kollege jetzt raten?",
  "Welcher Lösungsansatz hat sich bei dem letzten Problem bewährt?",
  "In welchem Augenblick ist mein Problem entstanden?",
  "Wen könnte ich um Rat bitten?",
  "Warum ist das Problem da?",
  "Bin ich am richtigen Problem dran oder nur an einem Symptom?",
  "Kenne ich das Spielfeld gut, in dem ich mich befinde?",
  "Für welches Problem suche ich gerade nach einer Lösung?",
  "Bin ich auf dem richtigen Weg?",
  "Was muss ich mir noch aneigenen, um mein Problem zu lösen?",
  "Sage ich zu oft \"Ich versuche ...\" anstatt zu sagen: \"Ich werde ...\"?",
  "Übernehme ich die Verantwortung für mein Handeln und Nichthandeln?",
  "Bin ich ausgeschlafen genug für das, was ich mir vornehme?",
  "Bin ich bei der Sache?",
  "Bin ich konzentriert?",
  "Welches Risiko bin ich bereit einzugehen?",
  "Welche längerfristigen Folgen hat mein Tun?",
  "Was tue ich am liebsten?",
  "Passt meine aktuelle Aufgabe zu meiner eigenen Lebensvision?",
  "Was muss zunächst abgeschlossen oder erledigt werden?",
  "Habe ich noch offene Kommunikation?",
  "Was hilft mir neue Sichtweisen zu entwickeln?",
  "Welchen Beitrag könnte ich jetzt dringend gebrauchen? Wie komme ich daran?",
  "Was brauche ich?",
  "Was hindert mich gerade?",
  "Auf was könnte ich am leichtesten verzichten?",
  "Woran erkenne ich, dass ich mein Problem gelöst habe?",
  "Was passiert, wenn ich einfach abwarte und nichts tue?",
  "Wie kann ich meine Ergebnisse messen?",
  "Wer kontrolliert, ob ich meine Arbeit gut mache?",
  "Was gibt mir Rückmeldung?",
  "Wie engagiert bin ich?",
  "Wie kann ich nach der Lösung verhindern, dass das Problem erneut auftritt?",
  "Wer weiß von dem Problem?",
  "Weiß ich alles über mein Problem?",
  "Weiß ich genug über mein Problem, um es lösen zu können?",
  "Wie kann ich mein Verhalten ändern, dass sich das Problem von selbst löst?",
  "Ist das Problem an dem ich arbeite auch mein Problem?",
  "Wessen Problem löse ich gerade?",
  "Welche Fragen habe ich mir noch nicht gestellt?",
  "Bin ich ehrlich zu mir?",
  "Löse ich gerade das wichtigste Problem?",
  "Was tue ich, wenn das Problem gelöst ist?",
  "Kann ich meine Fortschritte messen?",
  "Wann werde ich auf diese Seite das nächste mal zurückkehren?",
  "Wie wichtig ist eine gute Frage für mich?",
  "Wie lange dauert es, bis mein Handeln Wirkung zeigt?",
  "Was ist mein Ziel?",
  "Worauf will ich hinaus?",
  "Was verändert sich in meiner Umgebung, wenn ich fertig bin?",
  "Habe ich bereits begonnen?",
  "Wann werde ich beginnen?",
  "An welchem Ort erziele ich die besten Ergebnisse?",
  "Werde ich serenize.me weiterempfehlen?",
  "Wie überzeuge ich andere Mitsteiter für mein Problem?",
  "Gibt es Konkurenz?",
  "Welche Warum-Frage kommt mir als erste in den Sinn?",
  "Weiß ich, wie ich vorgehen muss?",
  "Wissen meine Mitsteiter oder Kollegen genau, was zu tun ist?",
  "Bin ich unsicher?",
  "Wie unsicher bin ich?",
  "Bin ich sicher, dass ich das Richtige tue?",
  "Was verschafft mir Sicherheit, das Richtige zu tun?",
  "Habe ich bereits ein änhliches Problem gelöst?",
  "Wie bin ich in bisherigen Situationen vorgegangen?",
  "Habe ich Spaß an der Lösung?",
  "Habe ich Spaß an dem Problem?",
  "Bekomme ich an Anerkennung für meine Arbeit?",
  "Erkenne ich die Arbeit der anderen an?",
  "Wie perfekt soll die Lösung sein?",
  "Kann ich in meiner Umgebung klar denken?",
  "Was fehlt mir, um klar zu denken?",
  "Welche Fähigkeiten fehlen mir zu Lösung des Problems?",
  "Welches Wissen fehlt mir zur Lösung des Problems?",
  "Handelt es sich um ein Problem?",
  "Gibt es etwas, das wichtiger ist und ich zunächst erledigen sollte?",
  "Bin ich ein Feuerlöscher?",
  "Habe ich einen coolen Kopf?",
  "Weiß ich bei jedem Schritt bereits schon den nächsten Schritt?",
  "Kenne ich meinen Weg?",
  "Habe ich ein Ziel?",
  "Habe ich mein Problem schon einmal aufgeschrieben?",
  "Werde ich bei der Lösung des Problems etwas neues lernen?",
  "Muss ich noch etwas lernen, bevor ich das Problem lösen kann?",
  "Kenne ich die Definition der Begriffe genau, die ich verwende?",
  "Schafft meine Lösung mehr Freiheit für Menschen?",
  "Ist das, was ich tue aus meiner Sicht eher gut oder schlecht?",
  "Tue ich mir etwas Gutes, nachdem ich das Problem gelöst habe?",
  "Tut mir die Lösung des Problems gut?",
  "Wie schaffe ich es, dass ich das Problem gerne löse?",
  "Welche Eigenschaften fehlen mir zur Lösung des Problems?",
  "Welche Eigenschaften haben andere, die mir helfen könnten?",
  "Wie groß ist mein Einfluss auf das Problem?",
  "Bin ich ausreichend vernetzt um das Problem mit anderen zu lösen?",
  "Bekomme ich genügend Rückhalt aus meiner Umgebung?",
  "Gibt es Werkzeuge, die mir bei der Lösung des Problems helfen?",
  "Welche Werkzeuge helfen bei der Lösung meines Problems?",
  "Was möchte ich alles erreichen? Bin ich auf dem richtigen Weg?",
  "Stelle ich mir töglich eine neue Frage?",
  "Habe ich ein Motto des Tages?",
  "Mit welchem Gedanken wache ich morgens auf?",
  "Was inspiriert mich?",
  "Führe ich durch Fragen oder durch Aufforderungen?",
  "Wer könnte es besser manchen als ich?",
  "Bin ich alleine in der Lage mein Problem zu lösen oder brauche ich Hilfe?",
  "Mache ich ausreichend Pausen?"
]
<commit_msg>Revise and add questions.<commit_after>var questions = [
  "Worin besteht das Problem?",
  "Wann tritt das Problem auf?",
  "Welche Ressourcen habe ich momentan zur Verfügung um das Problem zu lösen?",
  "Welche Menschen können mir dabei helfen, das Problem zu lösen?",
  "Wann habe ich das letzte Mal intensiv über dieses Problem nachgedacht?",
  "Auf welche Ressourcen, zur Lösung des Problems, würden mich andere hinweisen?",
  "Was würde ich mir raten, wenn ich Berater wär?",
  "Was müsste ich tun, um eine Lösung des Problems zu verhindern?",
  "Wer konnte mir bei meinem letzten Problem helfen?",
  "Welchen Nutzen habe ich von dem Problem?",
  "Was wäre der nächste Schritt, den ich gehen könnte, um das Problem zu lösen?",
  "Wie würde es sein, wenn das Problem gelöst wäre?",
  "Für wen würde sich etwas ändern, wenn das Problem gelöst wäre?",
  "Wer ist alles von dem Problem betroffen?",
  "Was würde passieren, wenn ich das Problem nicht angehen würde?",
  "Wann habe ich mich das letzte Mal bei einem Menschen für etwas bedankt?",
  "Wann war ich das letzte Mal an der frischen Luft unterwegs?",
  "Welche Frage stelle ich mir eigentlich gerade?",
  "Wie schlimm ist mein altuelles Problem?",
  "Was treibt mich an?",
  "Warum bin ich auf dieser Seite?",
  "Unter welchen Bedingungen kann ich am besten über etwas nachdenken?",
  "Was würde mir ein Kollege jetzt raten?",
  "Welcher Lösungsansatz hat sich bei dem letzten Problem bewährt?",
  "In welchem Augenblick ist mein Problem entstanden?",
  "Wen könnte ich um Rat bitten?",
  "Warum ist das Problem da?",
  "Bin ich am richtigen Problem dran oder nur an einem Symptom?",
  "Kenne ich das Spielfeld gut, in dem ich mich befinde?",
  "Für welches Problem suche ich gerade nach einer Lösung?",
  "Bin ich auf dem richtigen Weg?",
  "Was muss ich mir noch aneigenen, um mein Problem zu lösen?",
  "Sage ich zu oft \"Ich versuche ...\" anstatt zu sagen: \"Ich werde ...\"?",
  "Übernehme ich die Verantwortung für mein Handeln und Nichthandeln?",
  "Bin ich ausgeschlafen genug für das, was ich mir vornehme?",
  "Bin ich bei der Sache?",
  "Bin ich konzentriert?",
  "Welches Risiko bin ich bereit einzugehen?",
  "Welche längerfristigen Folgen hat mein Tun?",
  "Was tue ich am liebsten? Kann ich das zur Lösung des Problems einsetzen?",
  "Passt meine aktuelle Aufgabe zu meiner eigenen Lebensvision?",
  "Was muss zunächst abgeschlossen oder erledigt werden?",
  "Habe ich noch offene Kommunikation?",
  "Was schwirrt mir im Kopf herum?",
  "Was hilft mir neue Sichtweisen zu entwickeln?",
  "Habe ich schon eine andere Sichtweise auf das Problem angewendet?",
  "Wen kann ich um die Dringlichkeit des Problems befragen?",
  "Welchen Beitrag könnte ich jetzt dringend gebrauchen? Wie komme ich daran?",
  "Was brauche ich?",
  "Was hindert mich gerade?",
  "Auf was könnte ich am leichtesten verzichten?",
  "Woran erkenne ich, dass ich mein Problem gelöst habe?",
  "Was passiert, wenn ich einfach abwarte und nichts tue?",
  "Wie kann ich meine Ergebnisse messen?",
  "Wer kontrolliert, ob ich meine Arbeit gut mache?",
  "Was gibt mir Rückmeldung?",
  "Wie engagiert bin ich?",
  "Wie kann ich nach der Lösung verhindern, dass das Problem erneut auftritt?",
  "Wer weiß von dem Problem?",
  "Weiß ich alles über mein Problem?",
  "Weiß ich genug über mein Problem, um es lösen zu können?",
  "Wie kann ich mein Verhalten ändern, dass sich das Problem von selbst löst?",
  "Ist das Problem an dem ich arbeite auch für mich persönlich ein Problem?",
  "Wessen Problem löse ich gerade?",
  "Welche Fragen habe ich mir noch nicht gestellt?",
  "Bin ich ehrlich zu mir?",
  "Löse ich gerade das wichtigste Problem?",
  "Was tue ich, wenn das Problem gelöst ist?",
  "Kann ich meine Fortschritte messen?",
  "Wann werde ich auf diese Seite das nächste mal zurückkehren?",
  "Wie wichtig ist eine gute Frage für mich?",
  "Wie lange dauert es, bis mein Handeln Wirkung zeigt?",
  "Was ist mein Ziel?",
  "Worauf will ich hinaus?",
  "Was verändert sich in meiner Umgebung, wenn ich fertig bin?",
  "Habe ich bereits begonnen?",
  "Wann werde ich beginnen?",
  "An welchem Ort erziele ich die besten Ergebnisse?",
  "Werde ich serenize.me weiterempfehlen?",
  "Wie überzeuge ich andere Mitsteiter für mein Problem?",
  "Gibt es Konkurenz?",
  "Welche Warum-Frage kommt mir als erste in den Sinn?",
  "Weiß ich, wie ich vorgehen muss?",
  "Wissen meine Mitsteiter oder Kollegen genau, was zu tun ist?",
  "Bin ich unsicher?",
  "Wie unsicher bin ich?",
  "Bin ich sicher, dass ich das Richtige tue?",
  "Was verschafft mir Sicherheit, das Richtige zu tun?",
  "Habe ich bereits ein änhliches Problem gelöst?",
  "Wie bin ich in bisherigen Situationen vorgegangen?",
  "Habe ich Spaß an der Lösung?",
  "Habe ich Spaß an dem Problem?",
  "Bekomme ich an Anerkennung für meine Arbeit?",
  "Erkenne ich die Arbeit der anderen an?",
  "Wie perfekt soll die Lösung sein?",
  "Kann ich in meiner Umgebung klar denken?",
  "Was fehlt mir, um klar zu denken?",
  "Welche Fähigkeiten fehlen mir zu Lösung des Problems?",
  "Welches Wissen fehlt mir zur Lösung des Problems?",
  "Handelt es sich um ein Problem?",
  "Gibt es etwas, das wichtiger ist und ich zunächst erledigen sollte?",
  "Bin ich ein Feuerlöscher?",
  "Habe ich einen coolen Kopf?",
  "Weiß ich bei jedem Schritt bereits schon den nächsten Schritt?",
  "Kenne ich meinen Weg?",
  "Habe ich ein Ziel?",
  "Habe ich mein Problem schon einmal aufgeschrieben?",
  "Werde ich bei der Lösung des Problems etwas neues lernen?",
  "Muss ich noch etwas lernen, bevor ich das Problem lösen kann?",
  "Kenne ich die Definition der Begriffe genau, die ich verwende?",
  "Schafft meine Lösung mehr Freiheit für Menschen?",
  "Ist das, was ich tue aus meiner Sicht eher gut oder schlecht?",
  "Tue ich mir etwas Gutes, nachdem ich das Problem gelöst habe?",
  "Tut mir die Lösung des Problems gut?",
  "Wie schaffe ich es, dass ich das Problem gerne löse?",
  "Welche Eigenschaften fehlen mir zur Lösung des Problems?",
  "Welche Eigenschaften haben andere, die mir helfen könnten?",
  "Wie groß ist mein Einfluss auf das Problem?",
  "Bin ich ausreichend vernetzt um das Problem mit anderen zu lösen?",
  "Bekomme ich genügend Rückhalt aus meiner Umgebung?",
  "Gibt es Werkzeuge, die mir bei der Lösung des Problems helfen?",
  "Welche Werkzeuge helfen bei der Lösung meines Problems?",
  "Was möchte ich alles erreichen? Bin ich auf dem richtigen Weg?",
  "Stelle ich mir töglich eine neue Frage?",
  "Habe ich ein Motto des Tages?",
  "Mit welchem Gedanken wache ich morgens auf?",
  "Was inspiriert mich?",
  "Führe ich durch Fragen oder durch Aufforderungen?",
  "Wer könnte es besser manchen als ich?",
  "Bin ich alleine in der Lage mein Problem zu lösen oder brauche ich Hilfe?",
  "Mache ich ausreichend Pausen?",
  "Ist die Lösung dringend notwendig?",
  "Wie hoch ist der Schaden, wenn ich das Problem nicht löse?",
  "Tut es mir persönlich weh, wenn das Problem bestehen bleibt?"
]
<|endoftext|>


<commit_before>'use strict'

// Mongodb dependency
const ObjectId = require('mongodb').ObjectId;
require('mongodb-toolkit');
// Internal dependency
const BateeqModels = require('bateeq-models');
const map = BateeqModels.map;
// External dependency
const BaseManager = require('module-toolkit').BaseManager;
const moment = require('moment');

module.exports = class MonthlyStockManager extends BaseManager {
    constructor(db, user) {
        super(db, user);
        this.collection = this.db.use(map.inventory.InventoryMovement);
    }

    // GET START AND END YEAR BASED ON INVENTORY MOVEMENT
    _getFirstInventoryMovement() {
        return this.collection.find().sort({ date: 1 }).limit(1).toArray();
    }

    _getYearMonthsList(firstYear, lastYear, firstMonth, lastMonth) {
        let yearMonths = [];
        for (let i = firstYear; i <= lastYear; i++) {
            let each = this.__pushMonthBasedOnYear(i, firstYear, lastYear, firstMonth, lastMonth);
            yearMonths.push(each);
        }
        yearMonths.sort(function (a, b) { return b.year - a.year });
        return yearMonths;
    }

    __pushMonthBasedOnYear(currentYear, firstYear, lastYear, firstMonth, lastMonth) {
        let currentYearList = { year: currentYear, months: [] };
        if (currentYear === firstYear) {
            if (currentYear === lastYear) {
                for (let j = firstMonth; j <= lastMonth; j++) {
                    let currentMonth = this.__getMonthName(j);
                    currentYearList.months.push(currentMonth);
                }
            }
            else {
                for (let j = firstMonth; j <= 11; j++) {
                    let currentMonth = this.__getMonthName(j);
                    currentYearList.months.push(currentMonth);
                }
            }
        }
        else {
            if (currentYear === lastYear) {
                for (let j = 0; j <= lastMonth; j++) {
                    let currentMonth = this.__getMonthName(j);
                    currentYearList.months.push(currentMonth);
                }
            }
            else {
                for (let j = 0; j <= 11; j++) {
                    let currentMonth = this.__getMonthName(j);
                    currentYearList.months.push(currentMonth);
                }
            }

        }
        return currentYearList;
    }

    __getMonthName(monthNumber) {
        switch (monthNumber) {
            case 0:
                return { id: 0, name: "Januari" };
            case 1:
                return { id: 1, name: "Februari" };
            case 2:
                return { id: 2, name: "Maret" };
            case 3:
                return { id: 3, name: "April" };
            case 4:
                return { id: 4, name: "Mei" };
            case 5:
                return { id: 5, name: "Juni" };
            case 6:
                return { id: 6, name: "Juli" };
            case 7:
                return { id: 7, name: "Agustus" };
            case 8:
                return { id: 8, name: "September" };
            case 9:
                return { id: 9, name: "Oktober" };
            case 10:
                return { id: 10, name: "November" };
            case 11:
                return { id: 11, name: "Desember" };
        }
    }

    getYearMonthList() {
        let firstIM = this._getFirstInventoryMovement();
        let now = moment();
        return new Promise((resolve, reject) => {
            firstIM
                .then(results => {
                    let firstYear = results[0].date.getFullYear();
                    let firstMonth = results[0].date.getMonth();
                    let lastYear = parseInt(now.format('YYYY'));
                    let lastMonth = parseInt(now.format('MM')) - 1;
                    let yearMonthList = this._getYearMonthsList(firstYear, lastYear, firstMonth, lastMonth);
                    resolve(yearMonthList);
                })
        })
    }
    //

    // GET LOCALE TIME IN JAKARTA
    __getLocaleDateOfMonth(year, month, isStartOf) {
        let locale = isStartOf ? moment().month(month).year(year).startOf('month') : moment().month(month).year(year).endOf('month');
        return locale;
    }

    _setDateOfMonth(month, year) {
        let firstDay = this.__getLocaleDateOfMonth(year, month, true).format();
        let lastDay = this.__getLocaleDateOfMonth(year, month, false).format();
        return {
            firstDay: new Date(firstDay),
            lastDay: new Date(lastDay)
        }
    }
    //

    // GET INVENTORY ON PARTICULAR MONTH -> INVENTORY WITH MOVEMENT (END OF THE MONTH AND BEFORE EARLY OF THE MONTH)
    _getCurrentStocks(day) {
        let currentStocks = [
            { $match: { date: { $lte: day } } },
            { $sort: { date: -1 } },
            {
                $group: {
                    _id: { storageCode: "$storage.code", itemCode: "$item.code" },
                    storageName: { $first: "$storage.name" },
                    quantity: { $first: "$after" },
                    hpp: { $first: { $cond: { if: { $ne: ["$item.domesticCOGS", 0] }, then: "$item.domesticCOGS", else: "$item.internationalCOGS" } } },
                    sale: { $first: { $cond: { if: { $ne: ["$item.domesticSale", 0] }, then: "$item.domesticSale", else: "$item.internationalSale" } } }
                }
            },
            {
                $project: {
                    _id: 1,
                    storageName: "$storageName",
                    quantity: "$quantity",
                    hpp: { $multiply: ["$quantity", "$hpp"] },
                    sale: { $multiply: ["$quantity", "$sale"] }
                }
            },
            {
                $group: {
                    _id: { storageCode: "$_id.storageCode" },
                    storageName: { $first: "$storageName" },
                    quantity: { $sum: "$quantity" },
                    hpp: { $sum: "$hpp" },
                    sale: { $sum: "$sale" }
                }
            }
        ]
        let query = this.collection.aggregate(currentStocks).toArray();
        return query;
    }

    _combineStocks(earliest, latest) {
        let allStocks = [];
        console.log(earliest);
        console.log(latest);
        latest.forEach(ls => {
            let stock = {
                code: ls._id.storageCode,
                name: ls.storageName,
                latestQuantity: ls.quantity,
                latestHPP: ls.hpp,
                latestSale: ls.sale
            };
            let found = earliest.find(es => { return es._id.storageCode === ls._id.storageCode });
            if (found) {
                stock.earliestQuantity = found.quantity;
                stock.earliestHPP = found.hpp;
                stock.earliestSale = found.sale;
            }
            else {
                stock.earliestQuantity = 0;
                stock.earliestHPP = 0;
                stock.earliestSale = 0;
            }
            allStocks.push(stock);
        })
        return allStocks;
    }

    getOverallStock(month, year) {
        let date = this._setDateOfMonth(month, year);
        let earliestStocksQuery = this._getCurrentStocks(date.firstDay);
        let latestStocksQuery = this._getCurrentStocks(date.lastDay);
        return new Promise((resolve, reject) => {
            return Promise.all([earliestStocksQuery, latestStocksQuery])
                .then(results => {
                    let earliestStocks = results[0];
                    let latestStocks = results[1];
                    let finalStocks = this._combineStocks(earliestStocks, latestStocks);
                    resolve(finalStocks);
                })
        })
    }
    //

    // GET LATEST ITEM WITH PARTICULAR MONTH AND STORAGE CODE
    _getCurrentItems(code, day) {
        let currentItems = [
            {
                $match: {
                    date: { $lte: day },
                    "storage.code": code
                }
            },
            { $sort: { date: -1 } },
            {
                $group: {
                    _id: { itemCode: "$item.code" },
                    itemName: { $first: "$item.name" },
                    quantity: { $first: "$after" },
                    hpp: { $first: { $cond: { if: { $ne: ["$item.domesticCOGS", 0] }, then: "$item.domesticCOGS", else: "$item.internationalCOGS" } } },
                    sale: { $first: { $cond: { if: { $ne: ["$item.domesticSale", 0] }, then: "$item.domesticSale", else: "$item.internationalSale" } } }
                }
            },
            {
                $project: {
                    itemCode: "$_id.itemCode",
                    itemName: "$itemName",
                    quantity: "$quantity",
                    totalHPP: { $multiply: ["$quantity", "$hpp"] },
                    totalSale: { $multiply: ["$quantity", "$sale"] }
                }
            },
            { $match: { quantity: { $ne: 0 } } }
        ]
        let query = this.collection.aggregate(currentItems).toArray();
        return query;
    }

    getStockInStorage(storageCode, month, year) {
        let date = this._setDateOfMonth(month, year);
        let latestItemsQuery = this._getCurrentItems(storageCode, date.lastDay);
        return new Promise((resolve, reject) => {
            return latestItemsQuery
                .then(latestItems => {
                    resolve(latestItems);
                })
        })
    }
    //
}<commit_msg>Remove console log unit test<commit_after>'use strict'

// Mongodb dependency
const ObjectId = require('mongodb').ObjectId;
require('mongodb-toolkit');
// Internal dependency
const BateeqModels = require('bateeq-models');
const map = BateeqModels.map;
// External dependency
const BaseManager = require('module-toolkit').BaseManager;
const moment = require('moment');

module.exports = class MonthlyStockManager extends BaseManager {
    constructor(db, user) {
        super(db, user);
        this.collection = this.db.use(map.inventory.InventoryMovement);
    }

    // GET START AND END YEAR BASED ON INVENTORY MOVEMENT
    _getFirstInventoryMovement() {
        return this.collection.find().sort({ date: 1 }).limit(1).toArray();
    }

    _getYearMonthsList(firstYear, lastYear, firstMonth, lastMonth) {
        let yearMonths = [];
        for (let i = firstYear; i <= lastYear; i++) {
            let each = this.__pushMonthBasedOnYear(i, firstYear, lastYear, firstMonth, lastMonth);
            yearMonths.push(each);
        }
        yearMonths.sort(function (a, b) { return b.year - a.year });
        return yearMonths;
    }

    __pushMonthBasedOnYear(currentYear, firstYear, lastYear, firstMonth, lastMonth) {
        let currentYearList = { year: currentYear, months: [] };
        if (currentYear === firstYear) {
            if (currentYear === lastYear) {
                for (let j = firstMonth; j <= lastMonth; j++) {
                    let currentMonth = this.__getMonthName(j);
                    currentYearList.months.push(currentMonth);
                }
            }
            else {
                for (let j = firstMonth; j <= 11; j++) {
                    let currentMonth = this.__getMonthName(j);
                    currentYearList.months.push(currentMonth);
                }
            }
        }
        else {
            if (currentYear === lastYear) {
                for (let j = 0; j <= lastMonth; j++) {
                    let currentMonth = this.__getMonthName(j);
                    currentYearList.months.push(currentMonth);
                }
            }
            else {
                for (let j = 0; j <= 11; j++) {
                    let currentMonth = this.__getMonthName(j);
                    currentYearList.months.push(currentMonth);
                }
            }

        }
        return currentYearList;
    }

    __getMonthName(monthNumber) {
        switch (monthNumber) {
            case 0:
                return { id: 0, name: "Januari" };
            case 1:
                return { id: 1, name: "Februari" };
            case 2:
                return { id: 2, name: "Maret" };
            case 3:
                return { id: 3, name: "April" };
            case 4:
                return { id: 4, name: "Mei" };
            case 5:
                return { id: 5, name: "Juni" };
            case 6:
                return { id: 6, name: "Juli" };
            case 7:
                return { id: 7, name: "Agustus" };
            case 8:
                return { id: 8, name: "September" };
            case 9:
                return { id: 9, name: "Oktober" };
            case 10:
                return { id: 10, name: "November" };
            case 11:
                return { id: 11, name: "Desember" };
        }
    }

    getYearMonthList() {
        let firstIM = this._getFirstInventoryMovement();
        let now = moment();
        return new Promise((resolve, reject) => {
            firstIM
                .then(results => {
                    let firstYear = results[0].date.getFullYear();
                    let firstMonth = results[0].date.getMonth();
                    let lastYear = parseInt(now.format('YYYY'));
                    let lastMonth = parseInt(now.format('MM')) - 1;
                    let yearMonthList = this._getYearMonthsList(firstYear, lastYear, firstMonth, lastMonth);
                    resolve(yearMonthList);
                })
        })
    }
    //

    // GET LOCALE TIME IN JAKARTA
    __getLocaleDateOfMonth(year, month, isStartOf) {
        let locale = isStartOf ? moment().month(month).year(year).startOf('month') : moment().month(month).year(year).endOf('month');
        return locale;
    }

    _setDateOfMonth(month, year) {
        let firstDay = this.__getLocaleDateOfMonth(year, month, true).format();
        let lastDay = this.__getLocaleDateOfMonth(year, month, false).format();
        return {
            firstDay: new Date(firstDay),
            lastDay: new Date(lastDay)
        }
    }
    //

    // GET INVENTORY ON PARTICULAR MONTH -> INVENTORY WITH MOVEMENT (END OF THE MONTH AND BEFORE EARLY OF THE MONTH)
    _getCurrentStocks(day) {
        let currentStocks = [
            { $match: { date: { $lte: day } } },
            { $sort: { date: -1 } },
            {
                $group: {
                    _id: { storageCode: "$storage.code", itemCode: "$item.code" },
                    storageName: { $first: "$storage.name" },
                    quantity: { $first: "$after" },
                    hpp: { $first: { $cond: { if: { $ne: ["$item.domesticCOGS", 0] }, then: "$item.domesticCOGS", else: "$item.internationalCOGS" } } },
                    sale: { $first: { $cond: { if: { $ne: ["$item.domesticSale", 0] }, then: "$item.domesticSale", else: "$item.internationalSale" } } }
                }
            },
            {
                $project: {
                    _id: 1,
                    storageName: "$storageName",
                    quantity: "$quantity",
                    hpp: { $multiply: ["$quantity", "$hpp"] },
                    sale: { $multiply: ["$quantity", "$sale"] }
                }
            },
            {
                $group: {
                    _id: { storageCode: "$_id.storageCode" },
                    storageName: { $first: "$storageName" },
                    quantity: { $sum: "$quantity" },
                    hpp: { $sum: "$hpp" },
                    sale: { $sum: "$sale" }
                }
            }
        ]
        let query = this.collection.aggregate(currentStocks).toArray();
        return query;
    }

    _combineStocks(earliest, latest) {
        let allStocks = [];
        latest.forEach(ls => {
            let stock = {
                code: ls._id.storageCode,
                name: ls.storageName,
                latestQuantity: ls.quantity,
                latestHPP: ls.hpp,
                latestSale: ls.sale
            };
            let found = earliest.find(es => { return es._id.storageCode === ls._id.storageCode });
            if (found) {
                stock.earliestQuantity = found.quantity;
                stock.earliestHPP = found.hpp;
                stock.earliestSale = found.sale;
            }
            else {
                stock.earliestQuantity = 0;
                stock.earliestHPP = 0;
                stock.earliestSale = 0;
            }
            allStocks.push(stock);
        })
        return allStocks;
    }

    getOverallStock(month, year) {
        let date = this._setDateOfMonth(month, year);
        let earliestStocksQuery = this._getCurrentStocks(date.firstDay);
        let latestStocksQuery = this._getCurrentStocks(date.lastDay);
        return new Promise((resolve, reject) => {
            return Promise.all([earliestStocksQuery, latestStocksQuery])
                .then(results => {
                    let earliestStocks = results[0];
                    let latestStocks = results[1];
                    let finalStocks = this._combineStocks(earliestStocks, latestStocks);
                    resolve(finalStocks);
                })
        })
    }
    //

    // GET LATEST ITEM WITH PARTICULAR MONTH AND STORAGE CODE
    _getCurrentItems(code, day) {
        let currentItems = [
            {
                $match: {
                    date: { $lte: day },
                    "storage.code": code
                }
            },
            { $sort: { date: -1 } },
            {
                $group: {
                    _id: { itemCode: "$item.code" },
                    itemName: { $first: "$item.name" },
                    quantity: { $first: "$after" },
                    hpp: { $first: { $cond: { if: { $ne: ["$item.domesticCOGS", 0] }, then: "$item.domesticCOGS", else: "$item.internationalCOGS" } } },
                    sale: { $first: { $cond: { if: { $ne: ["$item.domesticSale", 0] }, then: "$item.domesticSale", else: "$item.internationalSale" } } }
                }
            },
            {
                $project: {
                    itemCode: "$_id.itemCode",
                    itemName: "$itemName",
                    quantity: "$quantity",
                    totalHPP: { $multiply: ["$quantity", "$hpp"] },
                    totalSale: { $multiply: ["$quantity", "$sale"] }
                }
            },
            { $match: { quantity: { $ne: 0 } } }
        ]
        let query = this.collection.aggregate(currentItems).toArray();
        return query;
    }

    getStockInStorage(storageCode, month, year) {
        let date = this._setDateOfMonth(month, year);
        let latestItemsQuery = this._getCurrentItems(storageCode, date.lastDay);
        return new Promise((resolve, reject) => {
            return latestItemsQuery
                .then(latestItems => {
                    resolve(latestItems);
                })
        })
    }
    //
}<|endoftext|>