<commit_before>const app = require('express')();
const bodyParser = require('body-parser');
const http = require('http').Server(app);
const io = require('socket.io')(http);
const request = require('request');
const useEnvFile = require("node-env-file");

if (process.env.USE_ENV_FILE) {
    useEnvFile(".env");
}

const topicOwner = {};
const ownerTopic = {};

app.use(bodyParser.json()); // for parsing application/json

app.get('/', function(req, res){
    res.sendFile(__dirname + '/index.html');
});

function sendMessage(chatId, text) {
    console.log(chatId + " : " + text);
    request
        .post('https://api.telegram.org/bot' + process.env.TELEGRAM_TOKEN + '/sendMessage')
        .form({
            "chat_id": chatId,
            "text": text
        });
}

app.post('/hook', function(req, res){
    let chatId = req.body.message.chat.id;
    let text = req.body.message.text;

    if (text && text.startsWith("/register")) {
        let topic = text.split(' ')[1];

        if (!topic) {
            sendMessage(chatId, "Could not register");
        } else if (!topicOwner[topic]) {
            topicOwner[topic] = chatId;
            ownerTopic[chatId] = topic;
            sendMessage(chatId, "You have registered " + topic);
        } else {
            sendMessage(chatId, "The topic " + topic + " is already taken");
        }
    } else {
        io.emit(ownerTopic[chatId], text);
    }

    res.statusCode = 200;
    res.end();
});

io.on('connection', function(client){

    client.on('register', function(topic){
        console.log("web client " + client.id + " registered to " + topic);
        if (topicOwner[topic]) {
            sendMessage(topicOwner[topic], "new visitor " + client.id);
        }

        client.on(topic, function(msg) {
            if (topicOwner[topic]) {
                sendMessage(topicOwner[topic], "message from " + client.id + " : " + msg);
            }

            io.emit(topic, msg);
        });

        client.on('disconnect', function(){
            if (topicOwner[topic]) {
                sendMessage(topicOwner[topic], "message from " + client.id + " : " + msg);
            } else {
                console.log("client " + client.id + " left");
            }
        });
    });

    client.on('disconnect', function(){
        console.log("client " + client.id + " left");
    });
});

http.listen(process.env.PORT || 3000, function(){
    console.log('listening on *:' + process.env.PORT || 3000);
});
<commit_msg>port issue<commit_after>const app = require('express')();
const bodyParser = require('body-parser');
const http = require('http').Server(app);
const io = require('socket.io')(http);
const request = require('request');
const useEnvFile = require("node-env-file");

if (process.env.USE_ENV_FILE) {
    useEnvFile(".env");
}

const topicOwner = {};
const ownerTopic = {};

app.use(bodyParser.json()); // for parsing application/json

app.get('/', function(req, res){
    res.sendFile(__dirname + '/index.html');
});

function sendMessage(chatId, text) {
    console.log(chatId + " : " + text);
    request
        .post('https://api.telegram.org/bot' + process.env.TELEGRAM_TOKEN + '/sendMessage')
        .form({
            "chat_id": chatId,
            "text": text
        });
}

app.post('/hook', function(req, res){
    let chatId = req.body.message.chat.id;
    let text = req.body.message.text;

    if(!text) {
        sendMessage(chatId, "Something went wrong, message is empty");
    } else if (text.startsWith("/start")) {
        sendMessage(chatId, "*Welcome to intergram* \n" +
            "Please type `/register #uniqe_topic_name` to register your chat identifier");
    } else if (text.startsWith("/register")) {
        let topic = text.split(' ')[1];

        if (!topic) {
            sendMessage(chatId, "Could not register");
        } else if (!topicOwner[topic]) {
            topicOwner[topic] = chatId;
            ownerTopic[chatId] = topic;
            sendMessage(chatId, "You have registered " + topic);
        } else {
            sendMessage(chatId, "The topic " + topic + " is already taken");
        }
    } else if (ownerTopic[chatId]) {
        io.emit(ownerTopic[chatId], text);
    } else {
        sendMessage(chatId, "Something went wrong, please register ");
    }

    res.statusCode = 200;
    res.end();
});

io.on('connection', function(client){

    client.on('register', function(topic){
        console.log("web client " + client.id + " registered to " + topic);
        if (topicOwner[topic]) {
            sendMessage(topicOwner[topic], "new visitor " + client.id);
        }

        client.on(topic, function(msg) {
            if (topicOwner[topic]) {
                sendMessage(topicOwner[topic], "message from " + client.id + " : " + msg);
            }

            io.emit(topic, msg);
        });

        client.on('disconnect', function(){
            if (topicOwner[topic]) {
                sendMessage(topicOwner[topic], "message from " + client.id + " : " + msg);
            } else {
                console.log("client " + client.id + " left");
            }
        });
    });

    client.on('disconnect', function(){
        console.log("client " + client.id + " left");
    });
});

http.listen(process.env.PORT || 3000, function(){
    console.log('listening on *:' + process.env.PORT || 3000);
});
<|endoftext|>


<commit_before>// Copyright 2018, University of Colorado Boulder

/**
 * Accordion box for showing and hiding terms of the interactive quadratic equation.
 *
 * @author Andrea Lin
 * @author Chris Malley (PixelZoom, Inc.)
 */
define( require => {
  'use strict';

  // modules
  const AccordionBox = require( 'SUN/AccordionBox' );
  const ConstantTermCheckbox = require( 'GRAPHING_QUADRATICS/explore/view/ConstantTermCheckbox' );
  const EquationsCheckbox = require( 'GRAPHING_QUADRATICS/common/view/EquationsCheckbox' );
  const GQColors = require( 'GRAPHING_QUADRATICS/common/GQColors' );
  const GQConstants = require( 'GRAPHING_QUADRATICS/common/GQConstants' );
  const graphingQuadratics = require( 'GRAPHING_QUADRATICS/graphingQuadratics' );
  const HSeparator = require( 'SUN/HSeparator' );
  const LinearTermCheckbox = require( 'GRAPHING_QUADRATICS/explore/view/LinearTermCheckbox' );
  const PhetFont = require( 'SCENERY_PHET/PhetFont' );
  const QuadraticTermCheckbox = require( 'GRAPHING_QUADRATICS/explore/view/QuadraticTermCheckbox' );
  const Tandem = require( 'TANDEM/Tandem' );
  const Text = require( 'SCENERY/nodes/Text' );
  const VBox = require( 'SCENERY/nodes/VBox' );

  // strings
  const quadraticTermsString = require( 'string!GRAPHING_QUADRATICS/quadraticTerms' );

  class QuadraticTermsAccordionBox extends AccordionBox {

    /**
     * @param {ExploreViewProperties} viewProperties
     * @param {Object} [options]
     */
    constructor( viewProperties, options ) {

      options = _.extend( {
        expandedProperty: viewProperties.quadraticTermsAccordionBoxExpandedProperty,
        titleAlignX: 'left',
        titleXSpacing: 8,
        tandem: Tandem.required
      }, GQConstants.ACCORDION_BOX_OPTIONS, options );

      assert && assert( !options.titleNode, 'QuadraticTermsAccordionBox sets titleNode' );
      options.titleNode = new Text( quadraticTermsString, {
        font: new PhetFont( GQConstants.TITLE_FONT_SIZE ),
        maxWidth: 180, // determined empirically
        tandem: options.tandem.createTandem( 'titleNode' )
      } );

      // y = ax^2
      const quadraticTermCheckbox = new QuadraticTermCheckbox( viewProperties.quadraticTermVisibleProperty, {
        tandem: options.tandem.createTandem( 'quadraticTermCheckbox' ),
        phetioDocumentation: 'checkbox that makes the quadratic term (y = ax^2) visible'
      } );

      // y = bx
      const linearTermCheckbox = new LinearTermCheckbox( viewProperties.linearTermVisibleProperty, {
        tandem: options.tandem.createTandem( 'linearTermCheckbox' ),
        phetioDocumentation: 'checkbox that makes the linear term (y = bx) visible'
      } );

      // y = c
      const constantTermCheckbox = new ConstantTermCheckbox( viewProperties.constantTermVisibleProperty, {
        tandem: options.tandem.createTandem( 'constantTermCheckbox' ),
        phetioDocumentation: 'checkbox that makes the constant term (y = c) visible'
      } );

      // Equations
      const equationsCheckbox = new EquationsCheckbox( viewProperties.equationsVisibleProperty, {
        tandem: options.tandem.createTandem( 'equationsCheckbox' )
      } );

      const maxCheckboxWidth = _.maxBy(
        [ quadraticTermCheckbox, linearTermCheckbox, constantTermCheckbox, equationsCheckbox ],
        node => node.width ).width;

      // vertical layout
      const contentNode = new VBox( {
        align: 'left',
        spacing: GQConstants.CHECKBOXES_Y_SPACING,
        children: [
          quadraticTermCheckbox,
          linearTermCheckbox,
          constantTermCheckbox,
          new HSeparator( Math.max( maxCheckboxWidth, 200 ), { stroke: GQColors.SEPARATOR } ),
          equationsCheckbox
        ]
      } );

      super( contentNode, options );
    }
  }

  return graphingQuadratics.register( 'QuadraticTermsAccordionBox', QuadraticTermsAccordionBox );
} );<commit_msg>doc<commit_after>// Copyright 2018, University of Colorado Boulder

/**
 * Accordion box for showing and hiding terms of the interactive quadratic equation.
 *
 * @author Andrea Lin
 * @author Chris Malley (PixelZoom, Inc.)
 */
define( require => {
  'use strict';

  // modules
  const AccordionBox = require( 'SUN/AccordionBox' );
  const ConstantTermCheckbox = require( 'GRAPHING_QUADRATICS/explore/view/ConstantTermCheckbox' );
  const EquationsCheckbox = require( 'GRAPHING_QUADRATICS/common/view/EquationsCheckbox' );
  const GQColors = require( 'GRAPHING_QUADRATICS/common/GQColors' );
  const GQConstants = require( 'GRAPHING_QUADRATICS/common/GQConstants' );
  const graphingQuadratics = require( 'GRAPHING_QUADRATICS/graphingQuadratics' );
  const HSeparator = require( 'SUN/HSeparator' );
  const LinearTermCheckbox = require( 'GRAPHING_QUADRATICS/explore/view/LinearTermCheckbox' );
  const PhetFont = require( 'SCENERY_PHET/PhetFont' );
  const QuadraticTermCheckbox = require( 'GRAPHING_QUADRATICS/explore/view/QuadraticTermCheckbox' );
  const Tandem = require( 'TANDEM/Tandem' );
  const Text = require( 'SCENERY/nodes/Text' );
  const VBox = require( 'SCENERY/nodes/VBox' );

  // strings
  const quadraticTermsString = require( 'string!GRAPHING_QUADRATICS/quadraticTerms' );

  class QuadraticTermsAccordionBox extends AccordionBox {

    /**
     * @param {ExploreViewProperties} viewProperties
     * @param {Object} [options]
     */
    constructor( viewProperties, options ) {

      options = _.extend( {
        expandedProperty: viewProperties.quadraticTermsAccordionBoxExpandedProperty,
        titleAlignX: 'left',
        titleXSpacing: 8,
        tandem: Tandem.required
      }, GQConstants.ACCORDION_BOX_OPTIONS, options );

      // AccordionBox title
      assert && assert( !options.titleNode, 'QuadraticTermsAccordionBox sets titleNode' );
      options.titleNode = new Text( quadraticTermsString, {
        font: new PhetFont( GQConstants.TITLE_FONT_SIZE ),
        maxWidth: 180, // determined empirically
        tandem: options.tandem.createTandem( 'titleNode' )
      } );

      // y = ax^2
      const quadraticTermCheckbox = new QuadraticTermCheckbox( viewProperties.quadraticTermVisibleProperty, {
        tandem: options.tandem.createTandem( 'quadraticTermCheckbox' ),
        phetioDocumentation: 'checkbox that makes the quadratic term (y = ax^2) visible'
      } );

      // y = bx
      const linearTermCheckbox = new LinearTermCheckbox( viewProperties.linearTermVisibleProperty, {
        tandem: options.tandem.createTandem( 'linearTermCheckbox' ),
        phetioDocumentation: 'checkbox that makes the linear term (y = bx) visible'
      } );

      // y = c
      const constantTermCheckbox = new ConstantTermCheckbox( viewProperties.constantTermVisibleProperty, {
        tandem: options.tandem.createTandem( 'constantTermCheckbox' ),
        phetioDocumentation: 'checkbox that makes the constant term (y = c) visible'
      } );

      // Equations
      const equationsCheckbox = new EquationsCheckbox( viewProperties.equationsVisibleProperty, {
        tandem: options.tandem.createTandem( 'equationsCheckbox' )
      } );

      const maxCheckboxWidth = _.maxBy(
        [ quadraticTermCheckbox, linearTermCheckbox, constantTermCheckbox, equationsCheckbox ],
        node => node.width ).width;

      // vertical layout
      const contentNode = new VBox( {
        align: 'left',
        spacing: GQConstants.CHECKBOXES_Y_SPACING,
        children: [
          quadraticTermCheckbox,
          linearTermCheckbox,
          constantTermCheckbox,
          new HSeparator( Math.max( maxCheckboxWidth, 200 ), { stroke: GQColors.SEPARATOR } ),
          equationsCheckbox
        ]
      } );

      super( contentNode, options );
    }
  }

  return graphingQuadratics.register( 'QuadraticTermsAccordionBox', QuadraticTermsAccordionBox );
} );<|endoftext|>


<commit_before>/*!
 * ${copyright}
 */

sap.ui.define(['jquery.sap.global', './ListItemBaseRenderer', 'sap/ui/core/Renderer'],
	function(jQuery, ListItemBaseRenderer, Renderer) {
		"use strict";

		/**
		 * ObjectListItem renderer.
		 * @namespace
		 */
		var ObjectListItemRenderer = Renderer.extend(ListItemBaseRenderer);

		/**
		 * Renders the HTML for single line of Attribute and Status.
		 *
		 * @param {sap.ui.core.RenderManager}
		 *            rm The RenderManager that can be used for writing to the render output buffer
		 * @param {sap.m.ObjectListItem}
		 *            oLI An object to be rendered
		 * @param {sap.m.ObjectAttribute}
		 *            oAttribute An attribute to be rendered
		 * @param {sap.m.ObjectStatus}
		 *            oStatus A status to be rendered
		 */
		ObjectListItemRenderer.renderAttributeStatus = function(rm, oLI, oAttribute, oStatus) {

			if (!oAttribute && !oStatus || (oAttribute && oAttribute._isEmpty() && oStatus && oStatus._isEmpty())) {
				return; // nothing to render
			}

			rm.write("
");

			if (oAttribute && !oAttribute._isEmpty()) {
				rm.write("
");
				rm.renderControl(oAttribute);
				rm.write("
");
			}

			if (oStatus && (!oStatus._isEmpty())) {
				rm.write("
");
				if (oStatus instanceof Array) {
					while (oStatus.length > 0) {
						rm.renderControl(oStatus.shift());
					}
				} else {
					rm.renderControl(oStatus);
				}
				rm.write("
");
			}

			rm.write("
"); // Start attribute row container
		};

		/**
		 * Renders the HTML for the given control, using the provided
		 * {@link sap.ui.core.RenderManager}.
		 *
		 * @param {sap.ui.core.RenderManager}
		 *          oRenderManager The RenderManager that can be used for writing to the
		 *          Render-Output-Buffer
		 * @param {sap.ui.core.Control}
		 *          oControl An object representation of the control that should be
		 *          rendered
		 */
		ObjectListItemRenderer.renderLIAttributes = function(rm, oLI) {
			rm.addClass("sapMObjLItem");
			rm.addClass("sapMObjLListModeDiv");
		};

		ObjectListItemRenderer.renderLIContent = function(rm, oLI) {
			var sTitleDir = oLI.getTitleTextDirection(),
				sIntroDir = oLI.getIntroTextDirection(),
				sNumberDir = oLI.getNumberTextDirection();

			// Introductory text at the top of the item, like "On behalf of Julie..."
			if (oLI.getIntro()) {
				rm.write("
");
				rm.write("");
				rm.writeEscaped(oLI.getIntro());
				rm.write("");
				rm.write("
");
			}

			// Container for fields placed on the top half of the item, below the intro. This
			// includes title, number, and number units.
			rm.write("
");

			if (!!oLI.getIcon()) {
				rm.write("
");
				rm.renderControl(oLI._getImageControl());
				rm.write("
");
			}

			// Container for a number and a units qualifier.
			rm.write("
");

			if (oLI.getNumber()) {
				rm.write("
");
				rm.writeEscaped(oLI.getNumber());
				rm.write("
");

				if (oLI.getNumberUnit()) {
					rm.write("
");
					rm.writeEscaped(oLI.getNumberUnit());
					rm.write("
");
				}
			}

			rm.write("
"); // End Number/units container

			// Title container displayed to the left of the number and number units container.
			rm.write("
");
			var oTitleText = oLI._getTitleText();
			if (oTitleText) {
				//sets the text direction of the title,
				//by delegating the RTL support to sap.m.Text
				oTitleText.setTextDirection(sTitleDir);
				oTitleText.setText(oLI.getTitle());
				oTitleText.addStyleClass("sapMObjLTitle");
				rm.renderControl(oTitleText);
			}

			rm.write("
"); // End Title container

			rm.write("
"); // End Top row container

			if (!(sap.ui.Device.browser.internet_explorer && sap.ui.Device.browser.version < 10)) {
				rm.write("

");
			}

			// Bottom row container.
			if (oLI._hasBottomContent()) {
				rm.write("
");

				var aAttribs = oLI._getVisibleAttributes();
				var statuses = [];
				var markers = null;

				if (oLI.getShowMarkers() || oLI.getMarkLocked()) {
					var placeholderIcon = oLI._getPlaceholderIcon();
					markers = [placeholderIcon];

					markers._isEmpty = function() {
						return false;
					};

					if (oLI.getMarkLocked()) {
						var lockIcon = oLI._getLockIcon();
						lockIcon.setVisible(oLI.getMarkLocked());
						markers.push(lockIcon);
					}

					if (oLI.getShowMarkers()) {
						var favIcon = oLI._getFavoriteIcon();
						var flagIcon = oLI._getFlagIcon();

						favIcon.setVisible(oLI.getMarkFavorite());
						flagIcon.setVisible(oLI.getMarkFlagged());

						markers.push(favIcon);
						markers.push(flagIcon);
					}

					statuses.push(markers);
				}

				statuses.push(oLI.getFirstStatus());
				statuses.push(oLI.getSecondStatus());

				while (aAttribs.length > 0) {
					this.renderAttributeStatus(rm, oLI, aAttribs.shift(), statuses.shift());
				}

				while (statuses.length > 0) {
					this.renderAttributeStatus(rm, oLI, null, statuses.shift());
				}

				rm.write("
"); // End Bottom row container
			}

			// ARIA description node
			this.renderAriaNode(rm, oLI, this.getAriaNodeText(oLI));

		};

		/**
		 * Renders hidden ARIA node, additionally, describing the ObjectListItem if description text is provided.
		 * {@link sap.ui.core.RenderManager}.
		 *
		 * @param {sap.ui.core.RenderManager}
		 *			rm The RenderManager that can be used for writing to the
		 *			Render-Output-Buffer
		 * @param {sap.m.ObjectListItem}
		 *			oLI An object to be rendered
		 * @param {String}
		 *			sAriaNodeText The ARIA node description text
		 */
		ObjectListItemRenderer.renderAriaNode = function(rm, oLI, sAriaNodeText) {
			if (sAriaNodeText) {
				rm.write("
");
				rm.writeEscaped(sAriaNodeText);

				rm.write("
");
			}
		};

		/**
		 * Returns ARIA node description text for flag, favorite, and lock marks.
		 *
		 * @param {sap.m.ObjectListItem}
		 *			oLI an object to be rendered
		 * @returns {String}
		 */
		ObjectListItemRenderer.getAriaNodeText = function(oLI) {
			var aAriaNodeText = [];

			var oLibraryResourceBundle = sap.ui.getCore().getLibraryResourceBundle("sap.m");

			if (oLI.getMarkFlagged()) {
				aAriaNodeText.push(oLibraryResourceBundle.getText("ARIA_FLAG_MARK_VALUE"));
			}

			if (oLI.getMarkFavorite()) {
				aAriaNodeText.push(oLibraryResourceBundle.getText("ARIA_FAVORITE_MARK_VALUE"));
			}

			if (oLI.getMarkLocked()) {
				aAriaNodeText.push(oLibraryResourceBundle.getText("OBJECTLISTITEM_ARIA_LOCKED_MARK_VALUE"));
			}

			return aAriaNodeText.join(" ");
		};

		/**
		 * Gets ObjectListItem`s inner nodes IDs, later used in aria labelledby attribute.
		 *
		 * @param {sap.m.ObjectListItem}
		 *			oLI An object representation of the control
		 * @returns {String} ObjectListItem`s inner nodes IDs
		 */
		ObjectListItemRenderer.getAriaLabelledBy = function(oLI) {
			var aLabelledByIds = [];

			if (oLI.getIntro()) {
				aLabelledByIds.push(oLI.getId() + "-intro");
			}

			if (oLI.getTitle()) {
				aLabelledByIds.push(oLI.getId() + "-titleText");
			}

			if (oLI.getNumber()) {
				aLabelledByIds.push(oLI.getId() + "-number");
			}

			if (oLI.getNumberUnit()) {
				aLabelledByIds.push(oLI.getId() + "-numberUnit");
			}

			if (oLI.getFirstStatus()) {
				aLabelledByIds.push(oLI.getFirstStatus().getId());
			}

			if (oLI.getSecondStatus()) {
				aLabelledByIds.push(oLI.getSecondStatus().getId());
			}

			if (oLI.getAttributes()) {
				oLI.getAttributes().forEach(function(attribute) {
					aLabelledByIds.push(attribute.getId());
				});
			}

			if (this.getAriaNodeText(oLI)) {
				aLabelledByIds.push(oLI.getId() + "-aria");
			}

			return aLabelledByIds.join(" ");
		};

		return ObjectListItemRenderer;

	}, /* bExport= */ true);
<commit_msg>[INTERNAL][FIX] sap.m.ObjectListItem: Screen reader order fixed<commit_after>/*!
 * ${copyright}
 */

sap.ui.define(['jquery.sap.global', './ListItemBaseRenderer', 'sap/ui/core/Renderer'],
	function(jQuery, ListItemBaseRenderer, Renderer) {
		"use strict";

		/**
		 * ObjectListItem renderer.
		 * @namespace
		 */
		var ObjectListItemRenderer = Renderer.extend(ListItemBaseRenderer);

		/**
		 * Renders the HTML for single line of Attribute and Status.
		 *
		 * @param {sap.ui.core.RenderManager}
		 *            rm The RenderManager that can be used for writing to the render output buffer
		 * @param {sap.m.ObjectListItem}
		 *            oLI An object to be rendered
		 * @param {sap.m.ObjectAttribute}
		 *            oAttribute An attribute to be rendered
		 * @param {sap.m.ObjectStatus}
		 *            oStatus A status to be rendered
		 */
		ObjectListItemRenderer.renderAttributeStatus = function(rm, oLI, oAttribute, oStatus) {

			if (!oAttribute && !oStatus || (oAttribute && oAttribute._isEmpty() && oStatus && oStatus._isEmpty())) {
				return; // nothing to render
			}

			rm.write("
");

			if (oAttribute && !oAttribute._isEmpty()) {
				rm.write("
");
				rm.renderControl(oAttribute);
				rm.write("
");
			}

			if (oStatus && (!oStatus._isEmpty())) {
				rm.write("
");
				if (oStatus instanceof Array) {
					while (oStatus.length > 0) {
						rm.renderControl(oStatus.shift());
					}
				} else {
					rm.renderControl(oStatus);
				}
				rm.write("
");
			}

			rm.write("
"); // Start attribute row container
		};

		/**
		 * Renders the HTML for the given control, using the provided
		 * {@link sap.ui.core.RenderManager}.
		 *
		 * @param {sap.ui.core.RenderManager}
		 *          oRenderManager The RenderManager that can be used for writing to the
		 *          Render-Output-Buffer
		 * @param {sap.ui.core.Control}
		 *          oControl An object representation of the control that should be
		 *          rendered
		 */
		ObjectListItemRenderer.renderLIAttributes = function(rm, oLI) {
			rm.addClass("sapMObjLItem");
			rm.addClass("sapMObjLListModeDiv");
		};

		ObjectListItemRenderer.renderLIContent = function(rm, oLI) {
			var sTitleDir = oLI.getTitleTextDirection(),
				sIntroDir = oLI.getIntroTextDirection(),
				sNumberDir = oLI.getNumberTextDirection();

			// Introductory text at the top of the item, like "On behalf of Julie..."
			if (oLI.getIntro()) {
				rm.write("
");
				rm.write("");
				rm.writeEscaped(oLI.getIntro());
				rm.write("");
				rm.write("
");
			}

			// Container for fields placed on the top half of the item, below the intro. This
			// includes title, number, and number units.
			rm.write("
");

			if (!!oLI.getIcon()) {
				rm.write("
");
				rm.renderControl(oLI._getImageControl());
				rm.write("
");
			}

			// Container for a number and a units qualifier.
			rm.write("
");

			if (oLI.getNumber()) {
				rm.write("
");
				rm.writeEscaped(oLI.getNumber());
				rm.write("
");

				if (oLI.getNumberUnit()) {
					rm.write("
");
					rm.writeEscaped(oLI.getNumberUnit());
					rm.write("
");
				}
			}

			rm.write("
"); // End Number/units container

			// Title container displayed to the left of the number and number units container.
			rm.write("
");
			var oTitleText = oLI._getTitleText();
			if (oTitleText) {
				//sets the text direction of the title,
				//by delegating the RTL support to sap.m.Text
				oTitleText.setTextDirection(sTitleDir);
				oTitleText.setText(oLI.getTitle());
				oTitleText.addStyleClass("sapMObjLTitle");
				rm.renderControl(oTitleText);
			}

			rm.write("
"); // End Title container

			rm.write("
"); // End Top row container

			if (!(sap.ui.Device.browser.internet_explorer && sap.ui.Device.browser.version < 10)) {
				rm.write("

");
			}

			// Bottom row container.
			if (oLI._hasBottomContent()) {
				rm.write("
");

				var aAttribs = oLI._getVisibleAttributes();
				var statuses = [];
				var markers = null;

				if (oLI.getShowMarkers() || oLI.getMarkLocked()) {
					var placeholderIcon = oLI._getPlaceholderIcon();
					markers = [placeholderIcon];

					markers._isEmpty = function() {
						return false;
					};

					if (oLI.getMarkLocked()) {
						var lockIcon = oLI._getLockIcon();
						lockIcon.setVisible(oLI.getMarkLocked());
						markers.push(lockIcon);
					}

					if (oLI.getShowMarkers()) {
						var favIcon = oLI._getFavoriteIcon();
						var flagIcon = oLI._getFlagIcon();

						favIcon.setVisible(oLI.getMarkFavorite());
						flagIcon.setVisible(oLI.getMarkFlagged());

						markers.push(favIcon);
						markers.push(flagIcon);
					}

					statuses.push(markers);
				}

				statuses.push(oLI.getFirstStatus());
				statuses.push(oLI.getSecondStatus());

				while (aAttribs.length > 0) {
					this.renderAttributeStatus(rm, oLI, aAttribs.shift(), statuses.shift());
				}

				while (statuses.length > 0) {
					this.renderAttributeStatus(rm, oLI, null, statuses.shift());
				}

				rm.write("
"); // End Bottom row container
			}

			// ARIA description node
			this.renderAriaNode(rm, oLI, this.getAriaNodeText(oLI));

		};

		/**
		 * Renders hidden ARIA node, additionally, describing the ObjectListItem if description text is provided.
		 * {@link sap.ui.core.RenderManager}.
		 *
		 * @param {sap.ui.core.RenderManager}
		 *			rm The RenderManager that can be used for writing to the
		 *			Render-Output-Buffer
		 * @param {sap.m.ObjectListItem}
		 *			oLI An object to be rendered
		 * @param {String}
		 *			sAriaNodeText The ARIA node description text
		 */
		ObjectListItemRenderer.renderAriaNode = function(rm, oLI, sAriaNodeText) {
			if (sAriaNodeText) {
				rm.write("
");
				rm.writeEscaped(sAriaNodeText);

				rm.write("
");
			}
		};

		/**
		 * Returns ARIA node description text for flag, favorite, and lock marks.
		 *
		 * @param {sap.m.ObjectListItem}
		 *			oLI an object to be rendered
		 * @returns {String}
		 */
		ObjectListItemRenderer.getAriaNodeText = function(oLI) {
			var aAriaNodeText = [];

			var oLibraryResourceBundle = sap.ui.getCore().getLibraryResourceBundle("sap.m");

			if (oLI.getMarkFlagged()) {
				aAriaNodeText.push(oLibraryResourceBundle.getText("ARIA_FLAG_MARK_VALUE"));
			}

			if (oLI.getMarkFavorite()) {
				aAriaNodeText.push(oLibraryResourceBundle.getText("ARIA_FAVORITE_MARK_VALUE"));
			}

			if (oLI.getMarkLocked()) {
				aAriaNodeText.push(oLibraryResourceBundle.getText("OBJECTLISTITEM_ARIA_LOCKED_MARK_VALUE"));
			}

			return aAriaNodeText.join(" ");
		};

		/**
		 * Gets ObjectListItem`s inner nodes IDs, later used in aria labelledby attribute.
		 *
		 * @param {sap.m.ObjectListItem}
		 *			oLI An object representation of the control
		 * @returns {String} ObjectListItem`s inner nodes IDs
		 */
		ObjectListItemRenderer.getAriaLabelledBy = function(oLI) {
			var aLabelledByIds = [];

			if (oLI.getIntro()) {
				aLabelledByIds.push(oLI.getId() + "-intro");
			}

			if (oLI.getTitle()) {
				aLabelledByIds.push(oLI.getId() + "-titleText");
			}

			if (oLI.getNumber()) {
				aLabelledByIds.push(oLI.getId() + "-number");
			}

			if (oLI.getNumberUnit()) {
				aLabelledByIds.push(oLI.getId() + "-numberUnit");
			}

			if (oLI.getAttributes()) {
				oLI.getAttributes().forEach(function(attribute) {
					aLabelledByIds.push(attribute.getId());
				});
			}

			if (oLI.getFirstStatus()) {
				aLabelledByIds.push(oLI.getFirstStatus().getId());
			}

			if (oLI.getSecondStatus()) {
				aLabelledByIds.push(oLI.getSecondStatus().getId());
			}

			if (this.getAriaNodeText(oLI)) {
				aLabelledByIds.push(oLI.getId() + "-aria");
			}

			return aLabelledByIds.join(" ");
		};

		return ObjectListItemRenderer;

	}, /* bExport= */ true);
<|endoftext|>


<commit_before>import { combineReducers } from 'redux';
import { denormalize } from 'normalizr';
import byId, * as fromById from './notificationById';
import {
  notificationList as notificationListSchema,
  notification as notificationSchema,
} from './../store/schema';

import {
  LOAD_NOTIFICATIONS_START,
  LOAD_NOTIFICATIONS_SUCCESS,
  LOAD_NOTIFICATIONS_ERROR,
} from '../constants';

const handlePageInfo = (state = {}, action) => {
  if (state.endCursor && !action.savePageInfo) {
    return state;
  }
  return { ...state, ...action.pagination };
};

const initialState = { ids: [] };

const status = (
  state = { pending: false, success: false, error: null },
  action,
) => {
  switch (action.type) {
    case LOAD_NOTIFICATIONS_START: {
      return {
        pending: true,
        error: null,
        success: false,
      };
    }
    case LOAD_NOTIFICATIONS_SUCCESS: {
      return {
        pending: false,
        error: null,
        success: true,
      };
    }
    case LOAD_NOTIFICATIONS_ERROR:
      return {
        pending: false,
        error: action.message,
        success: false,
      };

    default:
      return state;
  }
};

const all = (state = initialState, action) => {
  switch (action.type) {
    case LOAD_NOTIFICATIONS_SUCCESS: {
      if (action.payload.entities.notifications) {
        if (action.newQuery) {
          return { ...state, ids: action.payload.result };
        }
        return {
          ...state,
          ids: [...new Set([...action.payload.result, ...state.ids])],
        };
      }
      return action.newQuey ? { ...state, ids: [] } : state;
    }

    default:
      return state;
  }
};

const pageInfo = (state = { endCursor: '', hasNextPage: false }, action) => {
  /* if (action.filter !== filter) {
     return state;
   } */
  switch (action.type) {
    case LOAD_NOTIFICATIONS_SUCCESS:
      return handlePageInfo(state, action);

    default:
      return state;
  }
};

export default combineReducers({
  byId,
  all,
  pageInfo,
  status,
});

const hydrateList = (state, data, entities) =>
  denormalize(
    { notifications: data },
    { notifications: notificationListSchema },
    {
      ...entities,
      notifications: state.byId,
      activities: entities.activities.byId,
      users: entities.users.byId,
      statements: entities.statements.byId,
      proposals: entities.proposals.byId,
      comments: entities.comments.byId,
      discussions: entities.discussions.byId,
      messages: entities.messages.byId,
    },
  );

export const getStatus = state => ({
  error: state.status.error,
  pending: state.status.pending,
  pageInfo: state.pageInfo,
});
const hydrateEntity = (data, entities) =>
  denormalize(data, notificationSchema, entities);

export const getEntity = (state, id, entities) => {
  const notification = fromById.getEntity(state.byId, id);
  return hydrateEntity(notification, entities);
};

export const getAll = (state, entities) => {
  const { ids } = state.all;
  return hydrateList(state, ids, entities).notifications;
};
<commit_msg>fixed type in notifications reducer<commit_after>import { combineReducers } from 'redux';
import { denormalize } from 'normalizr';
import byId, * as fromById from './notificationById';
import {
  notificationList as notificationListSchema,
  notification as notificationSchema,
} from './../store/schema';

import {
  LOAD_NOTIFICATIONS_START,
  LOAD_NOTIFICATIONS_SUCCESS,
  LOAD_NOTIFICATIONS_ERROR,
} from '../constants';

const handlePageInfo = (state = {}, action) => {
  if (state.endCursor && !action.savePageInfo) {
    return state;
  }
  return { ...state, ...action.pagination };
};

const initialState = { ids: [] };

const status = (
  state = { pending: false, success: false, error: null },
  action,
) => {
  switch (action.type) {
    case LOAD_NOTIFICATIONS_START: {
      return {
        pending: true,
        error: null,
        success: false,
      };
    }
    case LOAD_NOTIFICATIONS_SUCCESS: {
      return {
        pending: false,
        error: null,
        success: true,
      };
    }
    case LOAD_NOTIFICATIONS_ERROR:
      return {
        pending: false,
        error: action.message,
        success: false,
      };

    default:
      return state;
  }
};

const all = (state = initialState, action) => {
  switch (action.type) {
    case LOAD_NOTIFICATIONS_SUCCESS: {
      if (action.payload.entities.notifications) {
        if (action.newQuery) {
          return { ...state, ids: action.payload.result };
        }
        return {
          ...state,
          ids: [...new Set([...action.payload.result, ...state.ids])],
        };
      }
      return action.newQuery ? { ...state, ids: [] } : state;
    }

    default:
      return state;
  }
};

const pageInfo = (state = { endCursor: '', hasNextPage: false }, action) => {
  /* if (action.filter !== filter) {
     return state;
   } */
  switch (action.type) {
    case LOAD_NOTIFICATIONS_SUCCESS:
      return handlePageInfo(state, action);

    default:
      return state;
  }
};

export default combineReducers({
  byId,
  all,
  pageInfo,
  status,
});

const hydrateList = (state, data, entities) =>
  denormalize(
    { notifications: data },
    { notifications: notificationListSchema },
    {
      ...entities,
      notifications: state.byId,
      activities: entities.activities.byId,
      users: entities.users.byId,
      statements: entities.statements.byId,
      proposals: entities.proposals.byId,
      comments: entities.comments.byId,
      discussions: entities.discussions.byId,
      messages: entities.messages.byId,
    },
  );

export const getStatus = state => ({
  error: state.status.error,
  pending: state.status.pending,
  pageInfo: state.pageInfo,
});
const hydrateEntity = (data, entities) =>
  denormalize(data, notificationSchema, entities);

export const getEntity = (state, id, entities) => {
  const notification = fromById.getEntity(state.byId, id);
  return hydrateEntity(notification, entities);
};

export const getAll = (state, entities) => {
  const { ids } = state.all;
  return hydrateList(state, ids, entities).notifications;
};
<|endoftext|>


<commit_before>exports.config = {
  seleniumAddress: 'http://localhost:4444/wd/hub',
  capabilities: {
    /*
     * Can be used to specify the phantomjs binary path.
     * This can generally be ommitted if you installed phantomjs globally.
     */
    // 'phantomjs.binary.path':'./node_modules/phantomjs/bin/phantomjs',

    /*
     * Command line arugments to pass to phantomjs.
     * Can be ommitted if no arguments need to be passed.
     * Acceptable cli arugments: https://github.com/ariya/phantomjs/wiki/API-Reference#wiki-command-line-options
     */
    'phantomjs.cli.args':['--logfile=PATH', '--loglevel=DEBUG']
  }
}
<commit_msg>Configure Protractor properly.<commit_after>exports.config = {
  chromeDriver: 'node_modules/protractor/selenium/chromedriver',
  // chromeOnly: true,
  seleniumAddress: 'http://localhost:4444/wd/hub',
  baseUrl: 'http://localhost:' + (process.env.HTTP_PORT || '9000'),
  rootElement: 'section',
  capabilities: {
    /*
     * Can be used to specify the phantomjs binary path.
     * This can generally be ommitted if you installed phantomjs globally.
     */
    // 'phantomjs.binary.path':'./node_modules/phantomjs/bin/phantomjs',

    /*
     * Command line arugments to pass to phantomjs.
     * Can be ommitted if no arguments need to be passed.
     * Acceptable cli arugments: https://github.com/ariya/phantomjs/wiki/API-Reference#wiki-command-line-options
     */
    // 'phantomjs.cli.args':['--logfile=PATH', '--loglevel=DEBUG']
  }
}
<|endoftext|>


<commit_before>'use strict';

/* Query For Feeds Controller */

mftApp.controller('FeedIndexCtrl', ['$scope', '$resource', 'Feed', '$routeParams', '$route', '$location', '$filter',
  function($scope, $resource, Feed, $routeParams, $route, $location, $filter) {
	$scope.$route = $route;
	$scope.$location = $location;
	$scope.$routeParams = $routeParams;
	$scope.params = $routeParams;
	$scope.feedList = Feed.query();
	var length = $scope.feedList.results.length;

	//Infinite Scrolling
	$scope.loadMore = function() {
	    var last = $scope.feedList.results[length - 1];
	    for(var i = 1; i <= 20; i++) {
	      $scope.feedList.results.push(last + i);
	    }
	};

	//Ajax Call
	/*$.ajax({
	    url: "http://dev.bigcompass.com:2222/rest/AaronL/Feeds/",
	    success: function(reports){

	        var global = reports;
			// Create x2js instance with default config
			var x2js = new X2JS();
			var xmlText = global;
			var jsonObj = x2js.xml_str2json( xmlText );
	        return global;
			return jsonObj;
			console.log(jsonObj);
			console.log(global);
			$scope.jsonString = findJSON;
			console.log($scope.jsonString);
	        }
	    });*/

	//Default Order the feeds by lastActive
	var sortOrder = '-ID';
	$scope.sortOrder = sortOrder;
	$scope.reverse = true;

	//Order the Feeds by each column
	$scope.sort = function(newSortOrder) {
	  if ($scope.sortOrder == newSortOrder)
	    $scope.reverse = !$scope.reverse;
	    $scope.sortOrder = newSortOrder;

	//Change arrow direction
        //$('th i').each(function(){
            // icon reset
			if ($scope.reverse)
            	$("th i").removeClass('icon-chevron-down').addClass('icon-chevron-up');

	           // $('th.'+newSortOrder+'i').removeClass().addClass('icon-chevron-up icon-white');
	        else
	            $("th i").removeClass('icon-chevron-up').addClass('icon-chevron-down');

       //});
    };
  }
]);

<commit_msg>Infinite Scrolling<commit_after>'use strict';

/* Query For Feeds Controller */

mftApp.controller('FeedIndexCtrl', ['$scope', '$resource', 'Feed', '$routeParams', '$route', '$location', '$filter',
  function($scope, $resource, Feed, $routeParams, $route, $location, $filter) {
	$scope.$route = $route;
	$scope.$location = $location;
	$scope.$routeParams = $routeParams;
	$scope.params = $routeParams;
	$scope.feedList = Feed.query();

	//Infinite Scrolling
	$scope.loadMore = function() {
	    var last = $scope.feedList.results[1367 - 1];
	    for(var i = 1; i <= 20; i++) {
	      $scope.feedList.results.push(last + i);
	    }
	};

	//Ajax Call
	/*$.ajax({
	    url: "http://dev.bigcompass.com:2222/rest/AaronL/Feeds/",
	    success: function(reports){

	        var global = reports;
			// Create x2js instance with default config
			var x2js = new X2JS();
			var xmlText = global;
			var jsonObj = x2js.xml_str2json( xmlText );
	        return global;
			return jsonObj;
			console.log(jsonObj);
			console.log(global);
			$scope.jsonString = findJSON;
			console.log($scope.jsonString);
	        }
	    });*/

	//Default Order the feeds by lastActive
	var sortOrder = '-ID';
	$scope.sortOrder = sortOrder;
	$scope.reverse = true;

	//Order the Feeds by each column
	$scope.sort = function(newSortOrder) {
	  if ($scope.sortOrder == newSortOrder)
	    $scope.reverse = !$scope.reverse;
	    $scope.sortOrder = newSortOrder;

	//Change arrow direction
        //$('th i').each(function(){
            // icon reset
			if ($scope.reverse)
            	$("th i").removeClass('icon-chevron-down').addClass('icon-chevron-up');

	           // $('th.'+newSortOrder+'i').removeClass().addClass('icon-chevron-up icon-white');
	        else
	            $("th i").removeClass('icon-chevron-up').addClass('icon-chevron-down');

       //});
    };
  }
]);

<|endoftext|>


<commit_before>Template.participantsDefinition.events({
	"click .submitGameConfiguration": function() {
		var filterInt = function(value) {
			if (/^(\-|\+)?([0-9]+|Infinity)$/.test(value))
				return Number(value);
			return NaN;
		};
		var currentGame = this._id;
		var isFilled = function(element) {
			if ($(element).val() === "") {
				return null;
			} else {
				return $(element).val();
			}
		};
		var homeTeamPlayers = [];
		var awayTeamPlayers = [];
		var homeTeamCoachs = [];
		var awayTeamCoachs = [];
		var homeTeam = {};
		var awayTeam = {};
		$('.player').each(function(index, element) {
			var player = {
				firstName: isFilled($(element).find('.firstName')),
				lastName: isFilled($(element).find('.lastName')),
				jersey: filterInt($(element).find('.jersey').val()),
				playerIndex: filterInt($(element).find('.playerIndex').val()),
				stats: {
					points: {
						onePointIn: 0,
						totalPoints: 0,
						twoPointsIn: 0,
						threePointsIn: 0,
						onePointOut: 0,
						twoPointsOut: 0,
						threePointsOut: 0
					},
					evaluation: 0,
					assists: 0,
					rebounds: {
						offReb: 0,
						defReb: 0
					},
					turnovers: 0,
					fouls: {
						offFouls: 0,
						totalFouls: 0,
						provFouls: {
							offFouls: 0,
							defFouls: 0
						},
						foul: 0,
						foul1FT: 0,
						foul2FT: 0,
						foul3FT: 0,
						techFoul: 0,
						antiSportFoul: 0,
						disqualifyingFoul: 0
					},
					steals: 0,
					blocks: 0
				}
			};
			if (index < 12) {
				player.team = "homeTeam";
				homeTeamPlayers.push(player);
			} else {
				player.team = "awayTeam";
				awayTeamPlayers.push(player);
			}
		});
		$('.coach').each(function(index, element) {
			var coach = {
				firstName: isFilled($(element).find('.firstName')),
				lastName: isFilled($(element).find('.lastName')),
				coachIndex: filterInt($(element).find('.coachIndex').val()),
				team: $(element).find('.team').val()
			};
			if (index < 2) {
				homeTeamCoachs.push(coach);
			} else {
				awayTeamCoachs.push(coach);
			}
		});
		homeTeam.players = homeTeamPlayers;
		homeTeam.coachs = homeTeamCoachs;
		awayTeam.players = awayTeamPlayers;
		awayTeam.coachs = awayTeamCoachs;

		Meteor.call('participantsUpdate', currentGame, homeTeam, awayTeam, function(error, result) {
			if (error) {
				return throwError(error.message);
			}
			Router.go('gameStats', {
				_id: currentGame
			});
		});
	}
});
<commit_msg>Add inPlay properties in player object<commit_after>Template.participantsDefinition.events({
	"click .submitGameConfiguration": function() {
		var filterInt = function(value) {
			if (/^(\-|\+)?([0-9]+|Infinity)$/.test(value))
				return Number(value);
			return NaN;
		};
		var currentGame = this._id;
		var isFilled = function(element) {
			if ($(element).val() === "") {
				return null;
			} else {
				return $(element).val();
			}
		};
		var homeTeamPlayers = [];
		var awayTeamPlayers = [];
		var homeTeamCoachs = [];
		var awayTeamCoachs = [];
		var homeTeam = {};
		var awayTeam = {};
		$('.player').each(function(index, element) {
			var player = {
				firstName: isFilled($(element).find('.firstName')),
				lastName: isFilled($(element).find('.lastName')),
				jersey: filterInt($(element).find('.jersey').val()),
				playerIndex: filterInt($(element).find('.playerIndex').val()),
				inPlay: false,
				stats: {
					points: {
						onePointIn: 0,
						totalPoints: 0,
						twoPointsIn: 0,
						threePointsIn: 0,
						onePointOut: 0,
						twoPointsOut: 0,
						threePointsOut: 0
					},
					evaluation: 0,
					assists: 0,
					rebounds: {
						offReb: 0,
						defReb: 0
					},
					turnovers: 0,
					fouls: {
						offFouls: 0,
						totalFouls: 0,
						provFouls: {
							offFouls: 0,
							defFouls: 0
						},
						foul: 0,
						foul1FT: 0,
						foul2FT: 0,
						foul3FT: 0,
						techFoul: 0,
						antiSportFoul: 0,
						disqualifyingFoul: 0
					},
					steals: 0,
					blocks: 0
				}
			};
			if (index < 12) {
				player.team = "homeTeam";
				homeTeamPlayers.push(player);
			} else {
				player.team = "awayTeam";
				awayTeamPlayers.push(player);
			}
		});
		$('.coach').each(function(index, element) {
			var coach = {
				firstName: isFilled($(element).find('.firstName')),
				lastName: isFilled($(element).find('.lastName')),
				coachIndex: filterInt($(element).find('.coachIndex').val()),
				team: $(element).find('.team').val()
			};
			if (index < 2) {
				homeTeamCoachs.push(coach);
			} else {
				awayTeamCoachs.push(coach);
			}
		});
		homeTeam.players = homeTeamPlayers;
		homeTeam.coachs = homeTeamCoachs;
		awayTeam.players = awayTeamPlayers;
		awayTeam.coachs = awayTeamCoachs;

		Meteor.call('participantsUpdate', currentGame, homeTeam, awayTeam, function(error, result) {
			if (error) {
				return throwError(error.message);
			}
			Router.go('gameStats', {
				_id: currentGame
			});
		});
	}
});
<|endoftext|>


<commit_before>// Copyright 2019 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

/* global capitalizeFirstLetters */

/**
 * Loads the page if the user is logged in. Otherwise, redirects to the
 * login page.
 */
function load() {
  /* global loadPage */
  loadPage(loadReceiptAnalysis);  // From js/common.js.
}

/** Fetches receipt properties from the server and adds them to the page. */
function loadReceiptAnalysis() {
  const receipt = getReceiptFromQueryString();

  document.getElementById('date-input').value = receipt.date;
  document.getElementById('store-input').value = receipt.storeName;
  document.getElementById('price-input').value = `$${receipt.price}`;
  document.getElementById('categories-input').value = receipt.categories;

  document.getElementById('receipt-image').src = receipt.imageUrl;
}

/**
 * Extracts the receipt properties from the query string.
 * @return {object} The extracted receipt.
 */
function getReceiptFromQueryString() {
  const parameters = new URLSearchParams(location.search);

  const date = getDateFromTimestamp(parameters.get('timestamp'));
  const storeName = capitalizeFirstLetters(parameters.get('store'));
  const price = parameters.get('price');
  const categories =
      capitalizeFirstLetters(parameters.get('categories').replace(/,/gi, ', '));
  const imageUrl = parameters.get('image-url');

  return {date, storeName, price, categories, imageUrl};
}

/** Converts a timestamp string into the equivalent date string. */
function getDateFromTimestamp(timestamp) {
  const time = parseInt(timestamp);

  // Only return the year, month, and day
  return new Date(time).toISOString().substring(0, 10);
}

/** Builds the div element for a category along with its children. */
function buildCategoryElement(category) {
  const categoryElement =
      document.querySelector('#category-template').content.cloneNode(true);
  categoryElement.querySelector('#category-name').innerText = category;

  return categoryElement;
}

/**
 * Sends a request to update the receipt.
 */
async function updateReceipt(event) {
  // Prevent the default action of reloading the page on form submission.
  event.preventDefault();

  const receipt = getReceiptFromForm();
  const formData = new FormData();

  formData.append('date', receipt.date);
  formData.append('store', receipt.store);
  formData.append('price', receipt.price);

  createCategoryList(receipt.categories).forEach((category) => {
    formData.append('categories', category);
  });

  // TODO: Send request to servlet.
}

/**
 * Gets the receipt properties from the form data.
 * @return {object} The extracted receipt.
 */
function getReceiptFromForm() {
  // TODO: Get receipt ID from URL.
  const date = document.getElementById('date-input').valueAsNumber;
  const store = document.getElementById('store-input').value;
  const price =
      convertStringToNumber(document.getElementById('price-input').value);
  const categories = document.getElementById('categories-input').value;

  return {date, store, price, categories};
}

/** Converts the comma-separated categories string into a list of categories. */
function createCategoryList(categories) {
  return categories.split(',').map((category) => category.trim());
}

/**
 * Converts the formatted price back to a number when the user
 * selects the price input.
 */
function convertPricetoValue(event) {
  const value = event.target.value;
  event.target.value = value ? convertStringToNumber(value) : '';
}

/**
 * Converts a string value into a number, removing all non-numeric characters.
 */
function convertStringToNumber(string) {
  return Number(String(string).replace(/[^0-9.]+/g, ''));
}

/**
 * Converts the number inputted by the user to a formatted string when
 * the user unfocuses from the price input.
 */
function formatCurrency(event) {
  const value = event.target.value;

  if (value) {
    event.target.value =
        convertStringToNumber(value).toLocaleString(undefined, {
          maximumFractionDigits: 2,
          currency: 'USD',
          style: 'currency',
          currencyDisplay: 'symbol',
        });
  } else {
    event.target.value = '';
  }
}

/**
 * Redirects the user to the home page when the "Return to Home" button is
 * clicked.
 */
function redirectHome() {
  if (isFormSaved()) {
    // Remove warning for unsaved changes.
    window.onbeforeunload = null;
  } else {
    // Warn user of losing unsaved changes.
    window.onbeforeunload = () => true;
  }

  window.location.href = '/';
}

/**
 * Checks there are any unsaved changes.
 * @return {boolean} Whether the form data matches the stored receipt.
 */
function isFormSaved() {
  const savedReceipt = getReceiptFromQueryString();
  const formReceipt = getReceiptFromForm();

  return savedReceipt.date === getDateFromTimestamp(formReceipt.date) &&
      savedReceipt.storeName === formReceipt.store &&
      convertStringToNumber(savedReceipt.price) === formReceipt.price &&
      savedReceipt.categories === formReceipt.categories;
}
<commit_msg>Add null checks for receipt fields and ensure all fields are set.<commit_after>// Copyright 2019 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

/* global capitalizeFirstLetters */

/**
 * Loads the page if the user is logged in. Otherwise, redirects to the
 * login page.
 */
function load() {
  /* global loadPage */
  loadPage(loadReceiptAnalysis);  // From js/common.js.
}

/** Fetches receipt properties from the server and adds them to the page. */
function loadReceiptAnalysis() {
  const receipt = getReceiptFromQueryString();

  // Set the value and max value of the date input field.
  const dateInput = document.getElementById('date-input');
  const today = formatDate(new Date());
  dateInput.value = receipt.date || today;
  dateInput.max = today;

  if (receipt.storeName) {
    document.getElementById('store-input').value = receipt.storeName;
  }
  if (receipt.price) {
    document.getElementById('price-input').value = `$${receipt.price}`;
  }
  if (receipt.categories) {
    document.getElementById('categories-input').value = receipt.categories;
  }

  document.getElementById('receipt-image').src = receipt.imageUrl;
}

/**
 * Extracts the receipt properties from the query string.
 * @return {object} The extracted receipt.
 */
function getReceiptFromQueryString() {
  const parameters = new URLSearchParams(location.search);

  const date = formatReceiptProperty('timestamp', getDateFromTimestamp);
  const storeName = formatReceiptProperty('store', capitalizeFirstLetters);
  const price = parameters.get('price');
  const categories = formatReceiptProperty('categories', formatCategories);
  const imageUrl = parameters.get('image-url');

  return {date, storeName, price, categories, imageUrl};
}

/**
 * Extracts the given property from the query string and formats it.
 * @param {string} propertyName The name of the query string property.
 * @param {function(string): *} format A function to format the specified
 *     property.
 * @return {*} The formatted property, or null if the property is not in the
 *     query string.
 */
function formatReceiptProperty(propertyName, format) {
  const parameters = new URLSearchParams(location.search);
  return parameters.has(propertyName) ? format(parameters.get(propertyName)) :
                                        null;
}

/** Converts a timestamp string into the equivalent date string. */
function getDateFromTimestamp(timestamp) {
  const time = parseInt(timestamp);

  // Only return the year, month, and day
  return new Date(time).toISOString().substring(0, 10);
}

/**
 * Capitalizes and adds spaces between the categories.
 * @param {string} categories A comma-separated list of categories
 * @return {string} The formatted list of categories.
 */
function formatCategories(categories) {
  return capitalizeFirstLetters(categories.replace(/,/gi, ', '));
}

/**
 * Converts a date to 'YYYY-MM-DD' format, corresponding to the value attribute
 * of the date input.
 * @param {Date} date The date to convert.
 * @return {string} The formatted date.
 */
function formatDate(date) {
  const day = String(date.getDate()).padStart(2, '0');
  const month = String(date.getMonth() + 1).padStart(2, '0');
  const year = date.getFullYear();
  return `${year}-${month}-${day}`;
}

/** Builds the div element for a category along with its children. */
function buildCategoryElement(category) {
  const categoryElement =
      document.querySelector('#category-template').content.cloneNode(true);
  categoryElement.querySelector('#category-name').innerText = category;

  return categoryElement;
}

/**
 * Sends a request to update the receipt.
 */
async function updateReceipt(event) {
  // Prevent the default action of reloading the page on form submission.
  event.preventDefault();

  const receipt = getReceiptFromForm();
  const formData = new FormData();

  formData.append('date', receipt.date);
  formData.append('store', receipt.store);
  formData.append('price', receipt.price);

  createCategoryList(receipt.categories).forEach((category) => {
    formData.append('categories', category);
  });

  // TODO: Send request to servlet.
}

/**
 * Gets the receipt properties from the form data.
 * @return {object} The extracted receipt.
 */
function getReceiptFromForm() {
  // TODO: Get receipt ID from URL.
  const date = document.getElementById('date-input').valueAsNumber;
  const store = document.getElementById('store-input').value;
  const price =
      convertStringToNumber(document.getElementById('price-input').value);
  const categories = document.getElementById('categories-input').value;

  return {date, store, price, categories};
}

/** Converts the comma-separated categories string into a list of categories. */
function createCategoryList(categories) {
  return categories.split(',').map((category) => category.trim());
}

/**
 * Converts the formatted price back to a number when the user
 * selects the price input.
 */
function convertPricetoValue(event) {
  const value = event.target.value;
  event.target.value = value ? convertStringToNumber(value) : '';
}

/**
 * Converts a string value into a number, removing all non-numeric characters.
 */
function convertStringToNumber(string) {
  return Number(String(string).replace(/[^0-9.]+/g, ''));
}

/**
 * Converts the number inputted by the user to a formatted string when
 * the user unfocuses from the price input.
 */
function formatCurrency(event) {
  const value = event.target.value;

  if (value) {
    event.target.value =
        convertStringToNumber(value).toLocaleString(undefined, {
          maximumFractionDigits: 2,
          currency: 'USD',
          style: 'currency',
          currencyDisplay: 'symbol',
        });
  } else {
    event.target.value = '';
  }
}

/**
 * Redirects the user to the home page when the "Return to Home" button is
 * clicked.
 */
function redirectHome() {
  if (isFormSaved()) {
    // Remove warning for unsaved changes.
    window.onbeforeunload = null;
  } else {
    // Warn user of losing unsaved changes.
    window.onbeforeunload = () => true;
  }

  if (!isReceiptComplete()) {
    alert('Please ensure that all fields are set and have been saved.');
    return;
  }

  window.location.href = '/';
}

/**
 * Checks if there are any unsaved changes.
 * @return {boolean} Whether the form data matches the stored receipt.
 */
function isFormSaved() {
  const savedReceipt = getReceiptFromQueryString();
  const formReceipt = getReceiptFromForm();

  return savedReceipt.date === getDateFromTimestamp(formReceipt.date) &&
      savedReceipt.storeName === formReceipt.store &&
      convertStringToNumber(savedReceipt.price) === formReceipt.price &&
      savedReceipt.categories === formReceipt.categories;
}

/**
 * Checks all receipt fields are saved.
 * @return {boolean} Whether all fields have been set.
 */
function isReceiptComplete() {
  const savedReceipt = getReceiptFromQueryString();

  return savedReceipt.date && savedReceipt.storeName && savedReceipt.price &&
      savedReceipt.categories;
}
<|endoftext|>


<commit_before>const http = require("http");
const bodyParser = require('body-parser');
const app = require("express")();
const EventEmitter = require("events");
const util = require('util');
const process = require('child_process');

const server = http.createServer(app);
server.listen(3000, () => console.log(`Paths livestream server is now running on port ${server.address().port}!`));

const io = require("socket.io")(server);

const emitter = new EventEmitter();
emitter.on("attempt_connection", (stream) => console.log("A user attempted to connect to Paths livestream server!"));

app.use(bodyParser.urlencoded({ extended: false }));

app.get("/", (request, response) => {
  const error = {
    "status": "error",
    "reason": "Please connect to a socket.io room in order to use Paths livestream service."
  }
  response.header("Content-Type", "application/json")
  response.send(JSON.stringify(error));
  emitter.emit("attempt_connection");
});

io.on("connection", (socket) => {
  console.log("A user successfully connected to Paths livestream server!")

  socket.on("create", (room) => {
    socket.join(room.key);
  });

  socket.on("stream_started", (stream) => {
    const secretKey = stream.key;
    const executeCommand = util.promisify(process.exec);

    console.log(`Stream started - secret key is ${secretKey}`);

    async function startSnapshot() {
      const { output, error } = await executeCommand(`ffmpeg -i rtmp://35.202.142.142:1935/stream/${secretKey} -f image2 -vf fps=fps=1/5 snapshot-${secretKey}-%d.png`);
      console.log(`Output parsed: ${output}`);
      console.log(`Error occured: ${error}`);
    }
    startSnapshot();
  });

  socket.on("disconnect", () => {
    console.log("A user disconnected from Paths livestream server!");
  });
});
<commit_msg>More work on snapshots.<commit_after>const http = require("http");
const bodyParser = require('body-parser');
const app = require("express")();
const EventEmitter = require("events");
const util = require('util');
const process = require('child_process');

const server = http.createServer(app);
server.listen(3000, () => console.log(`Paths livestream server is now running on port ${server.address().port}!`));

const io = require("socket.io")(server);

const emitter = new EventEmitter();
emitter.on("attempt_connection", (stream) => console.log("A user attempted to connect to Paths livestream server!"));

app.use(bodyParser.urlencoded({ extended: false }));

app.get("/", (request, response) => {
  const error = {
    "status": "error",
    "reason": "Please connect to a socket.io room in order to use Paths livestream service."
  }
  response.header("Content-Type", "application/json")
  response.send(JSON.stringify(error));
  emitter.emit("attempt_connection");
});

io.on("connection", (socket) => {
  console.log("A user successfully connected to Paths livestream server!")

  socket.on("create", (room) => {
    socket.join(room.key);
  });

  socket.on("stream_started", (stream) => {
    const secretKey = stream.key;
    const executeCommand = util.promisify(process.exec);

    console.log(`Stream started - secret key is ${secretKey}`);

    async function startSnapshot() {
      const { output, error } = await executeCommand(`ffmpeg -i rtmp://35.202.142.142:1935/stream/${secretKey} -f image2 -vf fps=fps=1/5 snapshot-${secretKey}-%d.png`);
      console.log(`Output parsed: ${output}`);
      console.log(`Error occured: ${error}`);
    }
    startSnapshot();
  });

  socket.on("disconnect", () => {
    console.log("A user disconnected from Paths livestream server!");

    async function endSnapshot() {
      const { output, error } = await executeCommand("sudo killall ffmpeg");
      console.log(`Output parsed: ${output}`);
      console.log(`Error occured: ${error}`);
    }
    endSnapshot();
  });
});
<|endoftext|>


<commit_before>'use strict';

try {
    /////////////////////////////////////
    // config
    /////////////////////////////////////
    var config = require('./config.js');

    /////////////////////////////////////
    // load required libraries
    /////////////////////////////////////
    var http = require('http');
    var path = require('path');
    var express = require('express');
    var bodyParser = require('body-parser');
    var lessMiddleware = require('less-middleware');

    /////////////////////////////////////
    // setup express
    /////////////////////////////////////
    var app = express();
    app.set('port', (process.env.PORT || config.port));

    // body JSON parsing
    app.use(bodyParser.json());
    app.use(bodyParser.urlencoded({ extended: true }));

    // set public path
    var public_path = path.join(__dirname, 'public');

    // compile less
    app.use(lessMiddleware(public_path, {
        dest: public_path,
        force: true,
        preprocess: {
            path: function(pathname, req) {
                var csspath = path.sep + 'css' + path.sep;
                return pathname.replace(csspath, csspath + 'less' + path.sep);
            }
        }
    }));

    app.use(express.static(public_path));

    /////////////////////////////////////
    // setup view engine
    /////////////////////////////////////
    app.set('view engine', 'pug');

    /////////////////////////////////////
    // load and setup API
    /////////////////////////////////////
    app.use('/rest/api', require('./rest/api.js')());

    /////////////////////////////////////
    // setup page + action routes
    /////////////////////////////////////
    //app.use('/', require('./routes/pages.js')());

    /////////////////////////////////////
    // hook node onto ip:port
    /////////////////////////////////////
    http.createServer(app).listen(app.get('port'), function() {
        console.log('Running on http://localhost:' + app.get('port'));
    });
}
catch (err) {
    console.log(err);
    throw err;
}<commit_msg>tweak<commit_after>try {
    /////////////////////////////////////
    // config
    /////////////////////////////////////
    var config = require('./config.js');

    /////////////////////////////////////
    // load required libraries
    /////////////////////////////////////
    var http = require('http');
    var path = require('path');
    var express = require('express');
    var bodyParser = require('body-parser');
    var lessMiddleware = require('less-middleware');

    /////////////////////////////////////
    // setup express
    /////////////////////////////////////
    var app = express();
    app.set('port', (process.env.PORT || config.port));

    // body JSON parsing
    app.use(bodyParser.json());
    app.use(bodyParser.urlencoded({ extended: true }));

    // set public path
    var public_path = path.join(__dirname, 'public');

    // compile less
    app.use(lessMiddleware(public_path, {
        dest: public_path,
        force: true,
        preprocess: {
            path: function(pathname, req) {
                var csspath = path.sep + 'css' + path.sep;
                return pathname.replace(csspath, csspath + 'less' + path.sep);
            }
        }
    }));

    app.use(express.static(public_path));

    /////////////////////////////////////
    // setup view engine
    /////////////////////////////////////
    app.set('view engine', 'pug');

    /////////////////////////////////////
    // load and setup API
    /////////////////////////////////////
    app.use('/rest/api', require('./rest/api.js')());

    /////////////////////////////////////
    // setup page + action routes
    /////////////////////////////////////
    //app.use('/', require('./routes/pages.js')());

    /////////////////////////////////////
    // hook node onto ip:port
    /////////////////////////////////////
    http.createServer(app).listen(app.get('port'), function() {
        console.log('Running on http://localhost:' + app.get('port'));
    });
}
catch (err) {
    console.log(err);
    throw err;
}<|endoftext|>


<commit_before>/*jslint es5: true, indent: 2, nomen: true, maxlen: 120 */
/*global module, require */

////////////////////////////////////////////////////////////////////////////////
/// @brief Foxx queues
///
/// @file
///
/// DISCLAIMER
///
/// Copyright 2004-2014 triAGENS GmbH, Cologne, Germany
///
/// Licensed under the Apache License, Version 2.0 (the "License");
/// you may not use this file except in compliance with the License.
/// You may obtain a copy of the License at
///
///     http://www.apache.org/licenses/LICENSE-2.0
///
/// Unless required by applicable law or agreed to in writing, software
/// distributed under the License is distributed on an "AS IS" BASIS,
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
/// See the License for the specific language governing permissions and
/// limitations under the License.
///
/// Copyright holder is triAGENS GmbH, Cologne, Germany
///
/// @author Alan Plum
/// @author Copyright 2014, triAGENS GmbH, Cologne, Germany
////////////////////////////////////////////////////////////////////////////////

var _ = require('underscore'),
  db = require('org/arangodb').db,
  workers = require('org/arangodb/tasks'),
  taskDefaults,
  queues,
  run,
  Queue,
  worker;

queues = {
  _tasks: Object.create(null),
  get: function (key) {
    'use strict';
    if (!db._queues.exists(key)) {
      throw new Error('Queue does not exist: ' + key);
    }
    return new Queue(key);
  },
  create: function (key, maxWorkers) {
    'use strict';
    db._executeTransaction({
      collections: {
        read: ['_queues'],
        write: ['_queues']
      },
      action: function () {
        if (db._queues.exists(key)) {
          db._queues.update(key, {maxWorkers: maxWorkers});
        } else {
          db._queues.save({_key: key, maxWorkers: maxWorkers});
        }
      }
    });
    return new Queue(key);
  },
  destroy: function (key) {
    'use strict';
    var result = false;
    db._executeTransaction({
      collections: {
        read: ['_queues'],
        write: ['_queues']
      },
      action: function () {
        if (db._queues.exists(key)) {
          db._queues.delete(key);
          result = true;
        }
      }
    });
    return result;
  },
  registerTask: function (name, opts) {
    'use strict';
    if (typeof opts === 'function') {
      opts = {execute: opts};
    }
    if (typeof opts.execute !== 'function') {
      throw new Error('Must provide a function to execute!');
    }
    var task = _.extend({}, taskDefaults, opts);
    if (task.maxFailures < 0) {
      task.maxFailures = Infinity;
    }
    queues._tasks[name] = task;
  }
};

Queue = function Queue(name) {
  'use strict';
  Object.defineProperty(this, 'name', {
    get: function () {
      return name;
    },
    set: function (value) {
      throw new Error('name is not mutable');
    },
    configurable: false,
    enumerable: true
  });
};

Queue.prototype.push = function (name, data) {
  'use strict';
  db._queue.save({
    status: 'pending',
    queue: this.name,
    task: name,
    failures: 0,
    data: data
  });
};

run = function () {
  'use strict';
  var db = require('org/arangodb').db,
    console = require('console');

  db._executeTransaction({
    collections: {
      read: ['_queues', '_jobs'],
      write: ['_jobs']
    },
    action: function () {
      var queues = db._queues.all().toArray();
      queues.forEach(function (queue) {
        var numBusy = db._jobs.byExample({
          queue: queue._key,
          status: 'progress'
        }).count();
        if (numBusy >= queue.maxWorkers) {
          return;
        }
        db._jobs.byExample({
          queue: queue._key,
          status: 'pending'
        }).limit(queue.maxWorkers - numBusy).toArray().forEach(function (job) {
          db._jobs.update(job, {status: 'progress'});
          workers.register({
            command: worker,
            params: _.extend(job._shallowCopy, {status: 'progress'}),
            offset: 0
          });
        });
      });
    }
  });
};

worker = function (job) {
  'use strict';
  var db = require('org/arangodb').db,
    queues = require('org/arangodb/foxx').queues,
    console = require('console'),
    task = queues._tasks[job.task],
    failed = false;

  if (!task) {
    console.warn('Unknown task for job ' + job._key + ':', job.task);
    db._jobs.update(job, {status: 'pending'});
    return;
  }

  try {
    queues._tasks[job.task].execute(job.data);
  } catch (err) {
    console.error('Job ' + job._key + ' failed:', err);
    failed = true;
  }
  db._jobs.update(job, failed ? {
    failures: job.failures + 1,
    status: (job.failures + 1 > task.maxFailures) ? 'failed' : 'pending'
  } : {status: 'complete'});
};

queues._create('default', 1);

module.exports = queues;

// -----------------------------------------------------------------------------
// --SECTION--                                                       END-OF-FILE
// -----------------------------------------------------------------------------

// Local Variables:
// mode: outline-minor
// outline-regexp: "/// @brief\\|/// @addtogroup\\|// --SECTION--\\|/// @}\\|/\\*jslint"
// End:
<commit_msg>Exposed Foxx.queues._manager.run.<commit_after>/*jslint es5: true, indent: 2, nomen: true, maxlen: 120 */
/*global module, require */

////////////////////////////////////////////////////////////////////////////////
/// @brief Foxx queues
///
/// @file
///
/// DISCLAIMER
///
/// Copyright 2004-2014 triAGENS GmbH, Cologne, Germany
///
/// Licensed under the Apache License, Version 2.0 (the "License");
/// you may not use this file except in compliance with the License.
/// You may obtain a copy of the License at
///
///     http://www.apache.org/licenses/LICENSE-2.0
///
/// Unless required by applicable law or agreed to in writing, software
/// distributed under the License is distributed on an "AS IS" BASIS,
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
/// See the License for the specific language governing permissions and
/// limitations under the License.
///
/// Copyright holder is triAGENS GmbH, Cologne, Germany
///
/// @author Alan Plum
/// @author Copyright 2014, triAGENS GmbH, Cologne, Germany
////////////////////////////////////////////////////////////////////////////////

var _ = require('underscore'),
  db = require('org/arangodb').db,
  workers = require('org/arangodb/tasks'),
  taskDefaults,
  queues,
  Queue,
  worker;

queues = {
  _tasks: Object.create(null),
  get: function (key) {
    'use strict';
    if (!db._queues.exists(key)) {
      throw new Error('Queue does not exist: ' + key);
    }
    return new Queue(key);
  },
  create: function (key, maxWorkers) {
    'use strict';
    db._executeTransaction({
      collections: {
        read: ['_queues'],
        write: ['_queues']
      },
      action: function () {
        if (db._queues.exists(key)) {
          db._queues.update(key, {maxWorkers: maxWorkers});
        } else {
          db._queues.save({_key: key, maxWorkers: maxWorkers});
        }
      }
    });
    return new Queue(key);
  },
  destroy: function (key) {
    'use strict';
    var result = false;
    db._executeTransaction({
      collections: {
        read: ['_queues'],
        write: ['_queues']
      },
      action: function () {
        if (db._queues.exists(key)) {
          db._queues.delete(key);
          result = true;
        }
      }
    });
    return result;
  },
  registerTask: function (name, opts) {
    'use strict';
    if (typeof opts === 'function') {
      opts = {execute: opts};
    }
    if (typeof opts.execute !== 'function') {
      throw new Error('Must provide a function to execute!');
    }
    var task = _.extend({}, taskDefaults, opts);
    if (task.maxFailures < 0) {
      task.maxFailures = Infinity;
    }
    queues._tasks[name] = task;
  }
};

Queue = function Queue(name) {
  'use strict';
  Object.defineProperty(this, 'name', {
    get: function () {
      return name;
    },
    set: function (value) {
      throw new Error('name is not mutable');
    },
    configurable: false,
    enumerable: true
  });
};

Queue.prototype.push = function (name, data) {
  'use strict';
  db._queue.save({
    status: 'pending',
    queue: this.name,
    task: name,
    failures: 0,
    data: data
  });
};

queues._manager = {
  run: function () {
    'use strict';
    var db = require('org/arangodb').db,
      console = require('console');

    db._executeTransaction({
      collections: {
        read: ['_queues', '_jobs'],
        write: ['_jobs']
      },
      action: function () {
        var queues = db._queues.all().toArray();
        queues.forEach(function (queue) {
          var numBusy = db._jobs.byExample({
            queue: queue._key,
            status: 'progress'
          }).count();
          if (numBusy >= queue.maxWorkers) {
            return;
          }
          db._jobs.byExample({
            queue: queue._key,
            status: 'pending'
          }).limit(queue.maxWorkers - numBusy).toArray().forEach(function (job) {
            db._jobs.update(job, {status: 'progress'});
            workers.register({
              command: worker,
              params: _.extend(job._shallowCopy, {status: 'progress'}),
              offset: 0
            });
          });
        });
      }
    });
  }
};

worker = function (job) {
  'use strict';
  var db = require('org/arangodb').db,
    queues = require('org/arangodb/foxx').queues,
    console = require('console'),
    task = queues._tasks[job.task],
    failed = false;

  if (!task) {
    console.warn('Unknown task for job ' + job._key + ':', job.task);
    db._jobs.update(job, {status: 'pending'});
    return;
  }

  try {
    queues._tasks[job.task].execute(job.data);
  } catch (err) {
    console.error('Job ' + job._key + ' failed:', err);
    failed = true;
  }
  db._jobs.update(job, failed ? {
    failures: job.failures + 1,
    status: (job.failures + 1 > task.maxFailures) ? 'failed' : 'pending'
  } : {status: 'complete'});
};

queues._create('default', 1);

module.exports = queues;

// -----------------------------------------------------------------------------
// --SECTION--                                                       END-OF-FILE
// -----------------------------------------------------------------------------

// Local Variables:
// mode: outline-minor
// outline-regexp: "/// @brief\\|/// @addtogroup\\|// --SECTION--\\|/// @}\\|/\\*jslint"
// End:
<|endoftext|>


<commit_before>import { applyMiddleware, createStore, compose } from 'redux'
import promiseMiddleware from 'redux-promise'
import thunkMiddleware from 'redux-thunk'
import saveStudentsMiddleware from './middleware/save-students'
import routerMiddleware from './middleware/router'
import rootReducer from './reducer'

const finalCreateStore = compose(
	applyMiddleware(
		promiseMiddleware,
		thunkMiddleware,
		routerMiddleware,
		saveStudentsMiddleware
	)
)(createStore)

export default function configureStore(initialState) {
	return finalCreateStore(rootReducer, initialState)
}
<commit_msg>enable checkStudentsMiddleware in production, too<commit_after>import { applyMiddleware, createStore, compose } from 'redux'
import promiseMiddleware from 'redux-promise'
import thunkMiddleware from 'redux-thunk'
import checkStudentsMiddleware from './middleware/check-students'
import saveStudentsMiddleware from './middleware/save-students'
import routerMiddleware from './middleware/router'
import rootReducer from './reducer'

const finalCreateStore = compose(
	applyMiddleware(
		promiseMiddleware,
		thunkMiddleware,
		routerMiddleware,
		checkStudentsMiddleware,
		saveStudentsMiddleware
	)
)(createStore)

export default function configureStore(initialState) {
	return finalCreateStore(rootReducer, initialState)
}
<|endoftext|>


<commit_before>exports.config = {
    // The address of a running selenium server.
    seleniumAddress: 'http://localhost:4444/wd/hub',

    // Spec patterns are relative to the location of this config.
    specs: [
        'spec/*_spec.js'
    ],

    capabilities: {
        'browserName': 'chrome',
        'chromeOptions': {'args': ['--disable-extensions']}
    },

    // A base URL for your application under test. Calls to protractor.get()
    // with relative paths will be prepended with this.
    //baseUrl: process.env.PROTRACTOR_BASE_URL || 'http://192.168.41.111',
    baseUrl: process.env.PROTRACTOR_BASE_URL || 'http://127.0.0.1',

    jasmineNodeOpts: {
        onComplete: null,
        isVerbose: false,
        showColors: true,
        includeStackTrace: true,
        defaultTimeoutInterval: 20000
    }
};<commit_msg>test(e2e): protractor tests<commit_after>exports.config = {
    // The address of a running selenium server.
    seleniumAddress: 'http://localhost:4444/wd/hub',

    // Spec patterns are relative to the location of this config.
    specs: [
        'spec/*_spec.js'
    ],

    capabilities: {
        'browserName': 'chrome',
        'chromeOptions': {'args': ['--disable-extensions']}
    },

    // A base URL for your application under test. Calls to protractor.get()
    // with relative paths will be prepended with this.
    baseUrl: process.env.PROTRACTOR_BASE_URL || 'http://192.168.41.111',
    //baseUrl: process.env.PROTRACTOR_BASE_URL || 'http://127.0.0.1',

    jasmineNodeOpts: {
        onComplete: null,
        isVerbose: false,
        showColors: true,
        includeStackTrace: true,
        defaultTimeoutInterval: 20000
    }
};<|endoftext|>


<commit_before>'use strict'

var controllersModule = require('./_index');
var _ = require('lazy.js');
var moment = require('moment');
var uuid = require('uuid');

/**
* @ngInject
*/
function AdminArticleCtrl($scope, $stateParams, ArticleService, $filter, $rootScope, $state, Articles, $http, $sce, $timeout, EmiAuth) {
  $scope.alerts = [];
  $scope.previousState = $rootScope.previousState;
  $scope.previousStateParams = $rootScope.previousStateParams;

  $scope.cancel = function() {
    if ($rootScope.previousState) {
      $state.go($scope.previousState, $scope.previousStateParams);
    } else {
      $state.go("app.admin.articles");
    }
  };

  var nullify = function(field) {
    if(field.bg != null && field.bg != undefined && field.bg.trim() === "")
      field.bg = null;
    if(field.en != null && field.en != undefined && field.en.trim() === "")
      field.en = null;
  }

  $scope.save = function() {
    $scope.alerts = [];

    // Remove the empty props to be able to filter with exists in ES
    nullify($scope.article.title);
    $scope.article.date = moment().valueOf();
    if (!$scope.article.itemId) {
      $scope.article.itemId = uuid.v1();
    }

    var method = $http.post;
    var url = "/api/articles";
    if ($scope.article.id) {
      method = $http.put;
      url = "/api/articles/" + $scope.article.id;
    }
    method(url, $scope.article, EmiAuth.addAuthHeader({}))
    .then(function(response) {
      $scope.alerts.push({type: 'success', msg: $sce.trustAsHtml("Статията е записана успешно")});
    })
    .catch(function(err) {
      $scope.alerts.push({type: 'danger', msg: "Не е възможно да се запише статията в момента. Моля опитайте след малко."});
      console.log(err);
    });
  }

  $scope.closeAlert = function(index) {
    $scope.alerts.splice(index, 1);
  };

  var editorOptions = function(options, inline, onChange) {
    options.inline = inline;
    options.language = $stateParams.lang || 'bg',
    options.skin = 'lightgray';
    options.theme = 'modern';
    options.browser_spellcheck = true;
    options.init_instance_callback = function(editor) {
      var textContentTrigger = function() {
        onChange(editor);
      };

      editor.on('KeyUp', textContentTrigger);
      editor.on('ExecCommand', textContentTrigger);
      editor.on('SetContent', function(e) {
        if (!e.initial)
          textContentTrigger();
      });
    };
    return options;
  }

  var htmlOptions = function(updateProperty) {
    return editorOptions(
      {
        plugins : [
          'google_tools advlist autolink lists link image charmap print preview hr anchor pagebreak',
          'searchreplace wordcount visualblocks visualchars code fullscreen',
          'insertdatetime media nonbreaking save table contextmenu directionality',
          'template paste textcolor colorpicker textpattern'
        ],
        toolbar1: 'insertfile undo redo | styleselect | bold italic | alignleft aligncenter alignright alignjustify | bullist numlist outdent indent | link google_tools image | print preview media | forecolor',
        image_caption: true,
        image_advtab: true,
        language : "bg",
      },
      false,
      function(editor) {
        updateProperty(jQuery(editor.getElement()).html());
      });
  }

  var titleOptions = function(updateProperty) {
    return editorOptions({
        toolbar: 'undo redo',
        menubar: false
      },
      true,
      function(editor) {
        updateProperty(jQuery(editor.getElement()).text());
      });
  }

  $scope.htmlBgOptions = htmlOptions(function(html) {
      $scope.article.html.bg = html;
      $scope.bgHtml = $sce.trustAsHtml(html);
  });
  $scope.htmlEnOptions = htmlOptions(function(html) {
      $scope.article.html.en = html;
      $scope.enHtml = $sce.trustAsHtml(html);
  });
  $scope.titleBgOptions = titleOptions(title => $scope.article.title.bg = title);
  $scope.titleEnOptions = titleOptions(title => $scope.article.title.en = title);

  var init = function(article) {
    $scope.article = article;

    $scope.articleType = article.category.reduce(function(prev, curr) {
      return curr ? curr : prev;
    }, 'news');
    $scope.bgHtml = $sce.trustAsHtml(article.html.bg);
    $scope.enHtml = $sce.trustAsHtml(article.html.en);
    var html = angular.copy(article.html);
    $scope.html = html;

    $scope.$watch('articleType', function () {
      $scope.article.category = [$scope.articleType];
    });
  }

  if ($stateParams.id) {
    ArticleService.article($stateParams.id)
    .then(init)
    .catch(err => $scope.alerts.push({type: 'danger', msg: err + ""}));
  } else {
    init({
      title: {bg:'', en:''},
      html: {bg:'', en:''},
      category: ['news'],
      image: {
        config: {
          fill: true,
          horizontalalign: "center",
          verticalalign: "center"
        }
      },
      published: false,
      deleted: false
    });
  }

  $scope.onPicked = function (docs) {
    var imageInfo = docs.shift();
    $scope.article.image = {
      config: {
        fill: true,
        horizontalalign: "center",
        verticalalign: "center"
      },
      url: "http://drive.google.com/uc?export=view&id=" + imageInfo.id
    };
    $scope.$apply();
  }
}

controllersModule.controller('AdminArticleCtrl', AdminArticleCtrl);
<commit_msg>New articles save will not duplicate them<commit_after>'use strict'

var controllersModule = require('./_index');
var _ = require('lazy.js');
var moment = require('moment');
var uuid = require('uuid');

/**
* @ngInject
*/
function AdminArticleCtrl($scope, $stateParams, ArticleService, $filter, $rootScope, $state, Articles, $http, $sce, $timeout, EmiAuth) {
  $scope.alerts = [];
  $scope.previousState = $rootScope.previousState;
  $scope.previousStateParams = $rootScope.previousStateParams;

  $scope.cancel = function() {
    if ($rootScope.previousState) {
      $state.go($scope.previousState, $scope.previousStateParams);
    } else {
      $state.go("app.admin.articles");
    }
  };

  var nullify = function(field) {
    if(field.bg != null && field.bg != undefined && field.bg.trim() === "")
      field.bg = null;
    if(field.en != null && field.en != undefined && field.en.trim() === "")
      field.en = null;
  }

  $scope.save = function() {
    $scope.alerts = [];

    // Remove the empty props to be able to filter with exists in ES
    nullify($scope.article.title);
    $scope.article.date = moment().valueOf();
    if (!$scope.article.itemId) {
      $scope.article.itemId = uuid.v1();
    }

    var method = $http.post;
    var url = "/api/articles";
    if ($scope.article.id) {
      method = $http.put;
      url = "/api/articles/" + $scope.article.id;
    }
    method(url, $scope.article, EmiAuth.addAuthHeader({}))
    .then(function(response) {
      $scope.article = response.data;
      $scope.alerts.push({type: 'success', msg: $sce.trustAsHtml("Статията е записана успешно")});
    })
    .catch(function(err) {
      $scope.alerts.push({type: 'danger', msg: "Не е възможно да се запише статията в момента. Моля опитайте след малко."});
      console.log(err);
    });
  }

  $scope.closeAlert = function(index) {
    $scope.alerts.splice(index, 1);
  };

  var editorOptions = function(options, inline, onChange) {
    options.inline = inline;
    options.language = $stateParams.lang || 'bg',
    options.skin = 'lightgray';
    options.theme = 'modern';
    options.browser_spellcheck = true;
    options.init_instance_callback = function(editor) {
      var textContentTrigger = function() {
        onChange(editor);
      };

      editor.on('KeyUp', textContentTrigger);
      editor.on('ExecCommand', textContentTrigger);
      editor.on('SetContent', function(e) {
        if (!e.initial)
          textContentTrigger();
      });
    };
    return options;
  }

  var htmlOptions = function(updateProperty) {
    return editorOptions(
      {
        plugins : [
          'google_tools advlist autolink lists link image charmap print preview hr anchor pagebreak',
          'searchreplace wordcount visualblocks visualchars code fullscreen',
          'insertdatetime media nonbreaking save table contextmenu directionality',
          'template paste textcolor colorpicker textpattern'
        ],
        toolbar1: 'insertfile undo redo | styleselect | bold italic | alignleft aligncenter alignright alignjustify | bullist numlist outdent indent | link google_tools image | print preview media | forecolor',
        image_caption: true,
        image_advtab: true,
        language : "bg",
      },
      false,
      function(editor) {
        updateProperty(jQuery(editor.getElement()).html());
      });
  }

  var titleOptions = function(updateProperty) {
    return editorOptions({
        toolbar: 'undo redo',
        menubar: false
      },
      true,
      function(editor) {
        updateProperty(jQuery(editor.getElement()).text());
      });
  }

  $scope.htmlBgOptions = htmlOptions(function(html) {
      $scope.article.html.bg = html;
      $scope.bgHtml = $sce.trustAsHtml(html);
  });
  $scope.htmlEnOptions = htmlOptions(function(html) {
      $scope.article.html.en = html;
      $scope.enHtml = $sce.trustAsHtml(html);
  });
  $scope.titleBgOptions = titleOptions(title => $scope.article.title.bg = title);
  $scope.titleEnOptions = titleOptions(title => $scope.article.title.en = title);

  var init = function(article) {
    $scope.article = article;

    $scope.articleType = article.category.reduce(function(prev, curr) {
      return curr ? curr : prev;
    }, 'news');
    $scope.bgHtml = $sce.trustAsHtml(article.html.bg);
    $scope.enHtml = $sce.trustAsHtml(article.html.en);
    var html = angular.copy(article.html);
    $scope.html = html;

    $scope.$watch('articleType', function () {
      $scope.article.category = [$scope.articleType];
    });
  }

  if ($stateParams.id) {
    ArticleService.article($stateParams.id)
    .then(init)
    .catch(err => $scope.alerts.push({type: 'danger', msg: err + ""}));
  } else {
    init({
      title: {bg:'', en:''},
      html: {bg:'', en:''},
      category: ['news'],
      image: {
        config: {
          fill: true,
          horizontalalign: "center",
          verticalalign: "center"
        }
      },
      published: false,
      deleted: false
    });
  }

  $scope.onPicked = function (docs) {
    var imageInfo = docs.shift();
    $scope.article.image = {
      config: {
        fill: true,
        horizontalalign: "center",
        verticalalign: "center"
      },
      url: "http://drive.google.com/uc?export=view&id=" + imageInfo.id
    };
    $scope.$apply();
  }
}

controllersModule.controller('AdminArticleCtrl', AdminArticleCtrl);
<|endoftext|>