<commit_before>/** @file This file contains functions that draw the popup bubble during labeling or editing an object. */

// *******************************************
// Public methods:
// *******************************************

/** This function creates the popup bubble.
 * @param {float} left - xlocation of the bubble
 * @param {float} top - ylocation of the bubble
 * @param {string} innerhtml - extra html content for the bubble
 * @param {string} dom_attach - id of the html element where it should be attached
 * @returns {string} bubble_name - dom element name for the popup bubble
*/
var part_bubble;
function CreatePopupBubble(left,top,innerHTML,dom_attach) {
  var html_str;
  var bubble_name = 'myPopup';

  // Adjust location to account for the displacement of the arrow:
  left -= 22;
  if (left < 5) left = 5;

  // Select the vertical position of the bubble decoration arrow
  if (top > 214) {
    html_str  = '
';
  }
  else {
    html_str  = '
';
  }

  // Insert bubble inner contents:
  html_str += innerHTML;

  // Close div tag:
  html_str += '
';

  // Insert bubble into the DOM tree:
  $('#'+dom_attach).append(html_str);
  if (part_bubble) $('#myPopup').css('background-color', 'rgb(255,230,230)')

  // Place bubble in the right location taking into account the rendered size and the location of the arrow
  if(top > 214) {
    h = $('#'+bubble_name).height();
    document.getElementById(bubble_name).style.top = (top-h-80) + 'px';
  }
  else {
    document.getElementById(bubble_name).style.top = (top) + 'px';
  }
  setTimeout("$('#objEnter').focus();",1);
  return bubble_name;
}

/** This function creates the close button at the top-right corner of the popup bubble
 * @param {string} dom_bubble - dom_bubble name
 * @param {function} close_button - function to run when the close button is pressed
*/
function CreatePopupBubbleCloseButton(dom_bubble,close_function) {
  if(arguments.length==1) {
    close_function = function() {return;};
  }
  var html_str = '';
  $('#'+dom_bubble).append(html_str);
  $('#'+dom_bubble+'_closebutton').mousedown(function () {
      $('#'+dom_bubble).remove();
      close_function();
      return;
    });
}

// *******************************************
// All functions below here need to be moved to their appropriate module:
// *******************************************

// THINGS THAT WILL BE GOOD TO SIMPLIFY:
//  1- why are there two functions -almost-identical- to close the bubble?
//  2- why is different the way the data is submitted in edit and query? I think with LM_xml data handling this will be simplified.
//  3- I want functions
//        LM_xml.store(obj_index, fieldname, value)
//        LM_xml.getvalue(obj_index, fieldname)
//        LM_xml.sendtoserver
//

// Query popup bubble:
function mkPopup(left,top,scribble_popup) {
  wait_for_input = 1;
  var innerHTML = GetPopupFormDraw(scribble_popup);
  CreatePopupBubble(left,top,innerHTML,'main_section');

  // Focus the cursor inside the box
  setTimeout("$('#objEnter').focus();",1);
}

function mkEditPopup(left,top,anno) {
  edit_popup_open = 1;
  var innerHTML = GetPopupFormEdit(anno);
  var dom_bubble = CreatePopupBubble(left,top,innerHTML,'main_section');
  CreatePopupBubbleCloseButton(dom_bubble,StopEditEvent);

  // Focus the cursor inside the box
  $('#objEnter').select();
  $('#objEnter').focus();
}

function CloseQueryPopup() {
  wait_for_input = 0;
  $('#myPopup').remove();
}

function CloseEditPopup() {
  edit_popup_open = 0;
  $('#myPopup').remove();
}

// ****************************
// Forms:
// ****************************

function GetPopupFormDraw(scribble_form) {
  wait_for_input = 1;
  part_bubble = false;
  html_str = "Enter object name
";
  if (add_parts_to != null){
    html_str = "Enter part name
";
    part_bubble = true;
  }
  html_str += HTMLobjectBox("");

  if(use_attributes) {
    html_str += HTMLoccludedBox("");
    html_str += "Enter attributes
";
    html_str += HTMLattributesBox("");
  }
  if(use_parts) {
    html_str += HTMLpartsBox("");
  }
  html_str += "
";

  // Done button:
  html_str += '<input type="button" value="Done" title="Press this button after you have provided all the information you want about the object." onclick="main_handler.SubmitQuery();" tabindex="0" />';

  // Undo close button/Keep editting
  if (!scribble_form) html_str += '<input type="button" value="Undo close" title="Press this button if you accidentally closed the polygon. You can continue adding control points." onclick="UndoCloseButton();" tabindex="0" />';
  else html_str += '<input type="button" value="Edit Scribble" title="Press this button if to keep adding scribbles." onclick="KeepEditingScribbles();" tabindex="0" />';
  // Add parts/Stop adding parts
  if (add_parts_to == null) html_str += '<input type="button" value="Add parts" title="Press this button if you want to start adding parts" onclick="main_handler.StartAddParts();" tabindex="0" />';
  else html_str += '<input type="button" value="Stop parts" title="Press this button if you want to stop adding parts" onclick="main_handler.StopAddParts();" tabindex="0" />';

  // Delete button:
  html_str += '<input type="button" value="Delete" title="Press this button if you wish to delete the polygon." onclick="main_handler.WhatIsThisObjectDeleteButton();" tabindex="0" />';

  return html_str;
}

function GetPopupFormEdit(anno) {
  // get object name and attributes from 'anno'
  edit_popup_open =  1;
  part_bubble = false;
  var obj_name = LMgetObjectField(LM_xml,anno.anno_id,'name');
  if(obj_name=="") obj_name = "?";
  var attributes = LMgetObjectField(LM_xml,anno.anno_id,'attributes');
  var occluded = LMgetObjectField(LM_xml,anno.anno_id,'occluded');
  var parts = LMgetObjectField(LM_xml, anno.anno_id, 'parts');

  html_str = "Enter object name
";
  html_str += HTMLobjectBox(obj_name);

  if(use_attributes) {
    html_str += HTMLoccludedBox(occluded);
    html_str += "Enter attributes
";
    html_str += HTMLattributesBox(attributes);
  }

  if(use_parts) {
    html_str += HTMLpartsBox(parts);
  }

  html_str += "
";

  // Done button:
  if (video_mode) html_str += '<input type="button" value="Done" title="Press this button when you are done editing." onclick="main_media.SubmitEditObject();" tabindex="0" />';

  else html_str += '<input type="button" value="Done" title="Press this button when you are done editing." onclick="main_handler.SubmitEditLabel();" tabindex="0" />';

  /*************************************************************/
  /*************************************************************/
  // Scribble: if anno.GetType() != 0 then scribble mode:

  // Adjust polygon button:
  if (anno.GetType() == 0) {
    html_str += '<input type="button" value="Adjust polygon" title="Press this button if you wish to update the polygon\'s control points." onclick="javascript:AdjustPolygonButton();" />';
  }
  else {
    html_str += '<input type="button" value="Edit Scribbles" title="Press this button if you wish to update the segmentation." onclick="javascript:EditBubbleEditScribble();" />';
  }
  /*************************************************************/
  /*************************************************************/

  // Add parts/Stop adding parts
  if (add_parts_to == null) html_str += '<input type="button" value="Add parts" title="Press this button if you want to start adding parts" onclick="main_handler.StartAddParts();" tabindex="0" />';
  // Delete button:
  html_str += '<input type="button" value="Delete" title="Press this button if you wish to delete the polygon." onclick="main_handler.EditBubbleDeleteButton();" tabindex="0" />';

  return html_str;
}

// ****************************
// Simple building blocks:
// ****************************

// Shows the box to enter the object name
function HTMLobjectBox(obj_name) {
  var html_str="";

  html_str += '<input name="objEnter" id="objEnter" type="text" style="width:260px;" tabindex="0" value="'+obj_name+'" title="Enter the object\'s name here. Avoid application specific names, codes, long descriptions. Use a name you think other people would agree in using. "';

  html_str += ' onkeyup="var c;if(event.keyCode)c=event.keyCode;if(event.which)c=event.which;if(c==13)';

  // if obj_name is empty it means that the box is being created
  if (obj_name=='') {
    // If press enter, then submit; if press ESC, then delete:
    if (video_mode) html_str += 'main_media.SubmitObject();if(c==27) main_handler.WhatIsThisObjectDeleteButton();" ';
    else html_str += 'main_handler.SubmitQuery();if(c==27)main_handler.WhatIsThisObjectDeleteButton();" ';
  }
  else {
    // If press enter, then submit:
    if (video_mode) html_str += 'main_media.SubmitEditObject();" ';
    else html_str += 'main_handler.SubmitEditLabel();" ';
  }

  // if there is a list of objects, we need to habilitate the list
  if(object_choices=='...') {
    html_str += '/>'; // close <input
  }
  else {
    html_str += 'list="datalist1" />'; // insert list and close <input
    html_str += '<datalist id="datalist1"><select style="display:none">';
    for(var i = 0; i < object_choices.length; i++) {
      html_str += '<option value="' + object_choices[i] + '">' + object_choices[i] + '</option>';
    }
    html_str += '</select></datalist>';
  }

  html_str += '
';

  return html_str;
}

// ****************************
// ATTRIBUTES:
// ****************************
// ?attributes=object:car;brand:seat/ford;color:...;comments:...

// is the object occluded?
function HTMLoccludedBox(occluded) {
  var html_str="";

  // by default, the value of occluded is "no"
  if (!(occluded=="no" || occluded=="yes")) {
    occluded="no";
  }

  // the value of the selection is inside a hidden field:
  html_str += 'Is occluded? <input type="hidden" name="occluded" id="occluded" value="'+occluded+'"/>';

  // generate radio button
  if (occluded=='yes') {
    html_str += '<input type="radio" name="rboccluded" id="rboccluded" value="yes" checked="yes" onclick="document.getElementById(\'occluded\').value=\'yes\';" />yes';
    html_str += '<input type="radio" name="rboccluded" id="rboccluded" value="no"  onclick="document.getElementById(\'occluded\').value=\'no\';" />no';
  }
  else {
    html_str += '<input type="radio" name="rboccluded" id="rboccluded" value="yes"  onclick="document.getElementById(\'occluded\').value=\'yes\';" />yes';
    html_str += '<input type="radio" name="rboccluded" id="rboccluded" value="no" checked="yes"  onclick="document.getElementById(\'occluded\').value=\'no\';" />no';
  }
  html_str += '
';

  return html_str;
}

// Boxes to enter attributes
function HTMLattributesBox(attList) {
  return '<textarea name="attributes" id="attributes" type="text" style="width:260px; height:3em;" tabindex="0" title="Enter a comma separated list of attributes, adjectives or other object properties">'+attList+'</textarea>';
}

// ****************************
// PARTS:
// ****************************
function HTMLpartsBox(parts) {
  var html_str="";
  if (parts.length>0) {
    if (parts.length==1) {
      html_str = 'Object has 1 part.';
    }
    else {
      html_str = 'Object has '+parts.length+' parts.';
    }
  }
  else {
    html_str = 'Object has no parts.';
  }

  return html_str;
}
<commit_msg>Solved design bug in bounding box bubbles<commit_after>/** @file This file contains functions that draw the popup bubble during labeling or editing an object. */

// *******************************************
// Public methods:
// *******************************************

/** This function creates the popup bubble.
 * @param {float} left - xlocation of the bubble
 * @param {float} top - ylocation of the bubble
 * @param {string} innerhtml - extra html content for the bubble
 * @param {string} dom_attach - id of the html element where it should be attached
 * @returns {string} bubble_name - dom element name for the popup bubble
*/
var part_bubble;
function CreatePopupBubble(left,top,innerHTML,dom_attach) {
  var html_str;
  var bubble_name = 'myPopup';

  // Adjust location to account for the displacement of the arrow:
  left -= 22;
  if (left < 5) left = 5;

  // Select the vertical position of the bubble decoration arrow
  if (top > 214) {
    html_str  = '
';
  }
  else {
    html_str  = '
';
  }

  // Insert bubble inner contents:
  html_str += innerHTML;

  // Close div tag:
  html_str += '
';

  // Insert bubble into the DOM tree:
  $('#'+dom_attach).append(html_str);
  if (part_bubble) $('#myPopup').css('background-color', 'rgb(255,230,230)')

  // Place bubble in the right location taking into account the rendered size and the location of the arrow
  if(top > 214) {
    h = $('#'+bubble_name).height();
    document.getElementById(bubble_name).style.top = (top-h-80) + 'px';
  }
  else {
    document.getElementById(bubble_name).style.top = (top) + 'px';
  }
  setTimeout("$('#objEnter').focus();",1);
  return bubble_name;
}

/** This function creates the close button at the top-right corner of the popup bubble
 * @param {string} dom_bubble - dom_bubble name
 * @param {function} close_button - function to run when the close button is pressed
*/
function CreatePopupBubbleCloseButton(dom_bubble,close_function) {
  if(arguments.length==1) {
    close_function = function() {return;};
  }
  var html_str = '';
  $('#'+dom_bubble).append(html_str);
  $('#'+dom_bubble+'_closebutton').mousedown(function () {
      $('#'+dom_bubble).remove();
      close_function();
      return;
    });
}

// *******************************************
// All functions below here need to be moved to their appropriate module:
// *******************************************

// THINGS THAT WILL BE GOOD TO SIMPLIFY:
//  1- why are there two functions -almost-identical- to close the bubble?
//  2- why is different the way the data is submitted in edit and query? I think with LM_xml data handling this will be simplified.
//  3- I want functions
//        LM_xml.store(obj_index, fieldname, value)
//        LM_xml.getvalue(obj_index, fieldname)
//        LM_xml.sendtoserver
//

// Query popup bubble:
function mkPopup(left,top,scribble_popup) {
  wait_for_input = 1;
  var innerHTML = GetPopupFormDraw(scribble_popup);
  CreatePopupBubble(left,top,innerHTML,'main_section');

  // Focus the cursor inside the box
  setTimeout("$('#objEnter').focus();",1);
}

function mkEditPopup(left,top,anno) {
  edit_popup_open = 1;
  var innerHTML = GetPopupFormEdit(anno);
  var dom_bubble = CreatePopupBubble(left,top,innerHTML,'main_section');
  CreatePopupBubbleCloseButton(dom_bubble,StopEditEvent);

  // Focus the cursor inside the box
  $('#objEnter').select();
  $('#objEnter').focus();
}

function CloseQueryPopup() {
  wait_for_input = 0;
  $('#myPopup').remove();
}

function CloseEditPopup() {
  edit_popup_open = 0;
  $('#myPopup').remove();
}

// ****************************
// Forms:
// ****************************

function GetPopupFormDraw(scribble_form) {
  wait_for_input = 1;
  part_bubble = false;
  html_str = "Enter object name
";
  if (add_parts_to != null){
    html_str = "Enter part name
";
    part_bubble = true;
  }
  html_str += HTMLobjectBox("");

  if(use_attributes) {
    html_str += HTMLoccludedBox("");
    html_str += "Enter attributes
";
    html_str += HTMLattributesBox("");
  }
  if(use_parts) {
    html_str += HTMLpartsBox("");
  }
  html_str += "
";

  // Done button:
  html_str += '<input type="button" value="Done" title="Press this button after you have provided all the information you want about the object." onclick="main_handler.SubmitQuery();" tabindex="0" />';

  // Undo close button/Keep editting
  if (!scribble_form) if (!bounding_box) html_str += '<input type="button" value="Undo close" title="Press this button if you accidentally closed the polygon. You can continue adding control points." onclick="UndoCloseButton();" tabindex="0" />';
  else if (scribble_form) html_str += '<input type="button" value="Edit Scribble" title="Press this button if to keep adding scribbles." onclick="KeepEditingScribbles();" tabindex="0" />';
  // Add parts/Stop adding parts
  if (add_parts_to == null) html_str += '<input type="button" value="Add parts" title="Press this button if you want to start adding parts" onclick="main_handler.StartAddParts();" tabindex="0" />';
  else html_str += '<input type="button" value="Stop parts" title="Press this button if you want to stop adding parts" onclick="main_handler.StopAddParts();" tabindex="0" />';

  // Delete button:
  html_str += '<input type="button" value="Delete" title="Press this button if you wish to delete the polygon." onclick="main_handler.WhatIsThisObjectDeleteButton();" tabindex="0" />';

  return html_str;
}

function GetPopupFormEdit(anno) {
  // get object name and attributes from 'anno'
  edit_popup_open =  1;
  part_bubble = false;
  var obj_name = LMgetObjectField(LM_xml,anno.anno_id,'name');
  if(obj_name=="") obj_name = "?";
  var attributes = LMgetObjectField(LM_xml,anno.anno_id,'attributes');
  var occluded = LMgetObjectField(LM_xml,anno.anno_id,'occluded');
  var parts = LMgetObjectField(LM_xml, anno.anno_id, 'parts');

  html_str = "Enter object name
";
  html_str += HTMLobjectBox(obj_name);

  if(use_attributes) {
    html_str += HTMLoccludedBox(occluded);
    html_str += "Enter attributes
";
    html_str += HTMLattributesBox(attributes);
  }

  if(use_parts) {
    html_str += HTMLpartsBox(parts);
  }

  html_str += "
";

  // Done button:
  if (video_mode) html_str += '<input type="button" value="Done" title="Press this button when you are done editing." onclick="main_media.SubmitEditObject();" tabindex="0" />';

  else html_str += '<input type="button" value="Done" title="Press this button when you are done editing." onclick="main_handler.SubmitEditLabel();" tabindex="0" />';

  /*************************************************************/
  /*************************************************************/
  // Scribble: if anno.GetType() != 0 then scribble mode:

  // Adjust polygon button:
  if (anno.GetType() == 0) {
    html_str += '<input type="button" value="Adjust polygon" title="Press this button if you wish to update the polygon\'s control points." onclick="javascript:AdjustPolygonButton();" />';
  }
  else {
    html_str += '<input type="button" value="Edit Scribbles" title="Press this button if you wish to update the segmentation." onclick="javascript:EditBubbleEditScribble();" />';
  }
  /*************************************************************/
  /*************************************************************/

  // Add parts/Stop adding parts
  if (add_parts_to == null) html_str += '<input type="button" value="Add parts" title="Press this button if you want to start adding parts" onclick="main_handler.StartAddParts();" tabindex="0" />';
  // Delete button:
  html_str += '<input type="button" value="Delete" title="Press this button if you wish to delete the polygon." onclick="main_handler.EditBubbleDeleteButton();" tabindex="0" />';

  return html_str;
}

// ****************************
// Simple building blocks:
// ****************************

// Shows the box to enter the object name
function HTMLobjectBox(obj_name) {
  var html_str="";

  html_str += '<input name="objEnter" id="objEnter" type="text" style="width:260px;" tabindex="0" value="'+obj_name+'" title="Enter the object\'s name here. Avoid application specific names, codes, long descriptions. Use a name you think other people would agree in using. "';

  html_str += ' onkeyup="var c;if(event.keyCode)c=event.keyCode;if(event.which)c=event.which;if(c==13)';

  // if obj_name is empty it means that the box is being created
  if (obj_name=='') {
    // If press enter, then submit; if press ESC, then delete:
    if (video_mode) html_str += 'main_media.SubmitObject();if(c==27) main_handler.WhatIsThisObjectDeleteButton();" ';
    else html_str += 'main_handler.SubmitQuery();if(c==27)main_handler.WhatIsThisObjectDeleteButton();" ';
  }
  else {
    // If press enter, then submit:
    if (video_mode) html_str += 'main_media.SubmitEditObject();" ';
    else html_str += 'main_handler.SubmitEditLabel();" ';
  }

  // if there is a list of objects, we need to habilitate the list
  if(object_choices=='...') {
    html_str += '/>'; // close <input
  }
  else {
    html_str += 'list="datalist1" />'; // insert list and close <input
    html_str += '<datalist id="datalist1"><select style="display:none">';
    for(var i = 0; i < object_choices.length; i++) {
      html_str += '<option value="' + object_choices[i] + '">' + object_choices[i] + '</option>';
    }
    html_str += '</select></datalist>';
  }

  html_str += '
';

  return html_str;
}

// ****************************
// ATTRIBUTES:
// ****************************
// ?attributes=object:car;brand:seat/ford;color:...;comments:...

// is the object occluded?
function HTMLoccludedBox(occluded) {
  var html_str="";

  // by default, the value of occluded is "no"
  if (!(occluded=="no" || occluded=="yes")) {
    occluded="no";
  }

  // the value of the selection is inside a hidden field:
  html_str += 'Is occluded? <input type="hidden" name="occluded" id="occluded" value="'+occluded+'"/>';

  // generate radio button
  if (occluded=='yes') {
    html_str += '<input type="radio" name="rboccluded" id="rboccluded" value="yes" checked="yes" onclick="document.getElementById(\'occluded\').value=\'yes\';" />yes';
    html_str += '<input type="radio" name="rboccluded" id="rboccluded" value="no"  onclick="document.getElementById(\'occluded\').value=\'no\';" />no';
  }
  else {
    html_str += '<input type="radio" name="rboccluded" id="rboccluded" value="yes"  onclick="document.getElementById(\'occluded\').value=\'yes\';" />yes';
    html_str += '<input type="radio" name="rboccluded" id="rboccluded" value="no" checked="yes"  onclick="document.getElementById(\'occluded\').value=\'no\';" />no';
  }
  html_str += '
';

  return html_str;
}

// Boxes to enter attributes
function HTMLattributesBox(attList) {
  return '<textarea name="attributes" id="attributes" type="text" style="width:260px; height:3em;" tabindex="0" title="Enter a comma separated list of attributes, adjectives or other object properties">'+attList+'</textarea>';
}

// ****************************
// PARTS:
// ****************************
function HTMLpartsBox(parts) {
  var html_str="";
  if (parts.length>0) {
    if (parts.length==1) {
      html_str = 'Object has 1 part.';
    }
    else {
      html_str = 'Object has '+parts.length+' parts.';
    }
  }
  else {
    html_str = 'Object has no parts.';
  }

  return html_str;
}
<|endoftext|>


<commit_before>'use strict';
var winston = require('winston'),
    moment = require('moment');

const winstonLogger = new (winston.Logger)({
    transports: [new (winston.transports.Console)({
        timestamp: () => {
            return `[${moment().toISOString()}]`;
        },
        formatter: (options) => {
            return options.timestamp() +' '+ options.level.toUpperCase() +' '+ (undefined !== options.message ? options.message : '') +
                (options.meta && Object.keys(options.meta).length ? '\n\t'+ JSON.stringify(options.meta) : '' );
        }
    })]
});

module.exports = winstonLogger;
<commit_msg>Delinted logger.js as much as I could without going crazy.<commit_after>'use strict';

const winston = require('winston');
const moment = require('moment');

const winstonLogger = new (winston.Logger)({
  transports: [new (winston.transports.Console)({
    timestamp: () => `[${moment().toISOString()}]`,
    formatter: options =>
      `${options.timestamp()} ` +
      `${options.level.toUpperCase()} ` +
      (undefined !== options.message ? options.message : '') +
      (options.meta && Object.keys(options.meta).length ? `\n\t${JSON.stringify(options.meta)}` : ''),
  })],
});

module.exports = winstonLogger;
<|endoftext|>


<commit_before>/* global Path2D */

import * as util from '../../../util';

let CRp = {};

CRp.drawEdge = function( context, edge, shiftToOriginWithBb, drawLabel ){
  let r = this;
  let rs = edge._private.rscratch;
  let usePaths = r.usePaths();

  if( !edge.visible() ){ return; }

  // if bezier ctrl pts can not be calculated, then die
  if( rs.badLine || rs.allpts == null || isNaN(rs.allpts[0]) ){ // isNaN in case edge is impossible and browser bugs (e.g. safari)
    return;
  }

  let bb;
  if( shiftToOriginWithBb ){
    bb = shiftToOriginWithBb;

    context.translate( -bb.x1, -bb.y1 );
  }

  let overlayPadding = edge.pstyle('overlay-padding').pfValue;
  let overlayWidth = 2 * overlayPadding;
  let overlayOpacity = edge.pstyle('overlay-opacity').value;
  let overlayColor = edge.pstyle('overlay-color').value;
  let opacity = edge.pstyle('opacity').value;
  let lineStyle = edge.pstyle('line-style').value;
  let edgeWidth = edge.pstyle('width').pfValue;
  let lineCap = edge.pstyle('line-cap').value;

  let drawLine = ( strokeOpacity = opacity ) => {
    context.lineWidth = edgeWidth;
    context.lineCap = lineCap;

    r.eleStrokeStyle( context, edge, strokeOpacity );
    r.drawEdgePath(
      edge,
      context,
      rs.allpts,
      lineStyle
    );

    context.lineCap = 'butt'; // reset for other drawing functions
  };

  let drawOverlay = ( strokeOpacity = overlayOpacity ) => {
    context.lineWidth = overlayWidth;

    if( rs.edgeType === 'self' && !usePaths ){
      context.lineCap = 'butt';
    } else {
      context.lineCap = 'round';
    }

    r.colorStrokeStyle( context, overlayColor[0], overlayColor[1], overlayColor[2], strokeOpacity );

    r.drawEdgePath(
      edge,
      context,
      rs.allpts,
      'solid'
    );
  };

  let drawArrows = ( arrowOpacity = opacity ) => {
    r.drawArrowheads( context, edge, arrowOpacity );
  };

  let drawText = () => {
    r.drawElementText( context, edge, drawLabel );
  };

  context.lineJoin = 'round';

  let ghost = edge.pstyle('ghost').value === 'yes';

  if( ghost ){
    let gx = edge.pstyle('ghost-offset-x').pfValue;
    let gy = edge.pstyle('ghost-offset-y').pfValue;
    let ghostOpacity = edge.pstyle('ghost-opacity').value;
    let effectiveGhostOpacity = opacity * ghostOpacity;

    context.translate( gx, gy );

    drawLine( effectiveGhostOpacity );
    drawArrows( effectiveGhostOpacity );

    context.translate( -gx, -gy );
  }

  drawLine();
  drawArrows();
  drawOverlay();
  drawText();

  if( shiftToOriginWithBb ){
    context.translate( bb.x1, bb.y1 );
  }
};

CRp.drawEdgePath = function( edge, context, pts, type ){
  let rs = edge._private.rscratch;
  let canvasCxt = context;
  let path;
  let pathCacheHit = false;
  let usePaths = this.usePaths();
  let dashStyle = edge.pstyle('dash-style').pfValue;
  let lineDashOffset = edge.pstyle('line-dash-offset').value;

  if( usePaths ){
    let pathCacheKey = pts.join( '$' );
    let keyMatches = rs.pathCacheKey && rs.pathCacheKey === pathCacheKey;

    if( keyMatches ){
      path = context = rs.pathCache;
      pathCacheHit = true;
    } else {
      path = context = new Path2D();
      rs.pathCacheKey = pathCacheKey;
      rs.pathCache = path;
    }
  }

  if( canvasCxt.setLineDash ){ // for very outofdate browsers
    switch( type ){
      case 'dotted':
        canvasCxt.setLineDash( [ 1, 1 ] );
        break;

      case 'dashed':
        canvasCxt.setLineDash( dashStyle );
        canvasCxt.lineDashOffset = lineDashOffset;
        break;

      case 'solid':
        canvasCxt.setLineDash( [ ] );
        break;
    }
  }

  if( !pathCacheHit && !rs.badLine ){
    if( context.beginPath ){ context.beginPath(); }
    context.moveTo( pts[0], pts[1] );

    switch( rs.edgeType ){
      case 'bezier':
      case 'self':
      case 'compound':
      case 'multibezier':
        for( let i = 2; i + 3 < pts.length; i += 4 ){
          context.quadraticCurveTo( pts[ i ], pts[ i + 1], pts[ i + 2], pts[ i + 3] );
        }
        break;

      case 'straight':
      case 'segments':
      case 'haystack':
        for( let i = 2; i + 1 < pts.length; i += 2 ){
          context.lineTo( pts[ i ], pts[ i + 1] );
        }
        break;
    }
  }

  context = canvasCxt;
  if( usePaths ){
    context.stroke( path );
  } else {
    context.stroke();
  }

  // reset any line dashes
  if( context.setLineDash ){ // for very outofdate browsers
    context.setLineDash( [ ] );
  }

};

CRp.drawArrowheads = function( context, edge, opacity ){
  let rs = edge._private.rscratch;
  let isHaystack = rs.edgeType === 'haystack';

  if( !isHaystack ){
    this.drawArrowhead( context, edge, 'source', rs.arrowStartX, rs.arrowStartY, rs.srcArrowAngle, opacity );
  }

  this.drawArrowhead( context, edge, 'mid-target', rs.midX, rs.midY, rs.midtgtArrowAngle, opacity );

  this.drawArrowhead( context, edge, 'mid-source', rs.midX, rs.midY, rs.midsrcArrowAngle, opacity );

  if( !isHaystack ){
    this.drawArrowhead( context, edge, 'target', rs.arrowEndX, rs.arrowEndY, rs.tgtArrowAngle, opacity );
  }
};

CRp.drawArrowhead = function( context, edge, prefix, x, y, angle, opacity ){
  if( isNaN( x ) || x == null || isNaN( y ) || y == null || isNaN( angle ) || angle == null ){ return; }

  let self = this;
  let arrowShape = edge.pstyle( prefix + '-arrow-shape' ).value;
  if( arrowShape === 'none' ) { return; }

  let arrowClearFill = edge.pstyle( prefix + '-arrow-fill' ).value === 'hollow' ? 'both' : 'filled';
  let arrowFill = edge.pstyle( prefix + '-arrow-fill' ).value;
  let edgeWidth = edge.pstyle( 'width' ).pfValue;
  let edgeOpacity = edge.pstyle( 'opacity' ).value;

  if( opacity === undefined ){
    opacity = edgeOpacity;
  }

  let gco = context.globalCompositeOperation;

  if( opacity !== 1 || arrowFill === 'hollow' ){ // then extra clear is needed
    context.globalCompositeOperation = 'destination-out';

    self.colorFillStyle( context, 255, 255, 255, 1 );
    self.colorStrokeStyle( context, 255, 255, 255, 1 );

    self.drawArrowShape( edge, context,
      arrowClearFill, edgeWidth, arrowShape, x, y, angle
    );

    context.globalCompositeOperation = gco;
  } // otherwise, the opaque arrow clears it for free :)

  let color = edge.pstyle( prefix + '-arrow-color' ).value;
  self.colorFillStyle( context, color[0], color[1], color[2], opacity );
  self.colorStrokeStyle( context, color[0], color[1], color[2], opacity );

  self.drawArrowShape( edge, context,
    arrowFill, edgeWidth, arrowShape, x, y, angle
  );
};

CRp.drawArrowShape = function( edge, context, fill, edgeWidth, shape, x, y, angle ){
  let r = this;
  let usePaths = this.usePaths();
  let pathCacheHit = false;
  let path;
  let canvasContext = context;
  let translation = { x, y };
  let scale = edge.pstyle( 'arrow-scale' ).value;
  let size = this.getArrowWidth( edgeWidth, scale );
  let shapeImpl = r.arrowShapes[ shape ];

  if( usePaths ){
    let cache = r.arrowPathCache = r.arrowPathCache || [];
    let key = util.hashString(shape);
    let cachedPath = cache[ key ];

    if( cachedPath != null ){
      path = context = cachedPath;
      pathCacheHit = true;
    } else {
      path = context = new Path2D();
      cache[ key ] = path;
    }
  }

  if( context.beginPath ){ context.beginPath(); }

  if( !pathCacheHit ){
    if( usePaths ){ // store in the path cache with values easily manipulated later
      shapeImpl.draw( context, 1, 0, { x: 0, y: 0 }, 1 );
    } else {
      shapeImpl.draw( context, size, angle, translation, edgeWidth );
    }
  }

  if( context.closePath ){ context.closePath(); }

  context = canvasContext;

  if( usePaths ){ // set transform to arrow position/orientation
    context.translate( x, y );
    context.rotate( angle );
    context.scale( size, size );
  }

  if( fill === 'filled' || fill === 'both' ){
    if( usePaths ){
      context.fill( path );
    } else {
      context.fill();
    }
  }

  if( fill === 'hollow' || fill === 'both' ){
    context.lineWidth = ( shapeImpl.matchEdgeWidth ? edgeWidth : 1 ) / ( usePaths ? size : 1 );
    context.lineJoin = 'miter';

    if( usePaths ){
      context.stroke( path );
    } else {
      context.stroke();
    }
  }

  if( usePaths ){ // reset transform by applying inverse
    context.scale( 1/size, 1/size );
    context.rotate( -angle );
    context.translate( -x, -y );
  }
};

export default CRp;
<commit_msg>Streamlined the code<commit_after>/* global Path2D */

import * as util from '../../../util';

let CRp = {};

CRp.drawEdge = function( context, edge, shiftToOriginWithBb, drawLabel ){
  let r = this;
  let rs = edge._private.rscratch;
  let usePaths = r.usePaths();

  if( !edge.visible() ){ return; }

  // if bezier ctrl pts can not be calculated, then die
  if( rs.badLine || rs.allpts == null || isNaN(rs.allpts[0]) ){ // isNaN in case edge is impossible and browser bugs (e.g. safari)
    return;
  }

  let bb;
  if( shiftToOriginWithBb ){
    bb = shiftToOriginWithBb;

    context.translate( -bb.x1, -bb.y1 );
  }

  let overlayPadding = edge.pstyle('overlay-padding').pfValue;
  let overlayWidth = 2 * overlayPadding;
  let overlayOpacity = edge.pstyle('overlay-opacity').value;
  let overlayColor = edge.pstyle('overlay-color').value;
  let opacity = edge.pstyle('opacity').value;
  let lineStyle = edge.pstyle('line-style').value;
  let edgeWidth = edge.pstyle('width').pfValue;
  let lineCap = edge.pstyle('line-cap').value;

  let drawLine = ( strokeOpacity = opacity ) => {
    context.lineWidth = edgeWidth;
    context.lineCap = lineCap;

    r.eleStrokeStyle( context, edge, strokeOpacity );
    r.drawEdgePath(
      edge,
      context,
      rs.allpts,
      lineStyle
    );

    context.lineCap = 'butt'; // reset for other drawing functions
  };

  let drawOverlay = ( strokeOpacity = overlayOpacity ) => {
    context.lineWidth = overlayWidth;

    if( rs.edgeType === 'self' && !usePaths ){
      context.lineCap = 'butt';
    } else {
      context.lineCap = 'round';
    }

    r.colorStrokeStyle( context, overlayColor[0], overlayColor[1], overlayColor[2], strokeOpacity );

    r.drawEdgePath(
      edge,
      context,
      rs.allpts,
      'solid'
    );
  };

  let drawArrows = ( arrowOpacity = opacity ) => {
    r.drawArrowheads( context, edge, arrowOpacity );
  };

  let drawText = () => {
    r.drawElementText( context, edge, drawLabel );
  };

  context.lineJoin = 'round';

  let ghost = edge.pstyle('ghost').value === 'yes';

  if( ghost ){
    let gx = edge.pstyle('ghost-offset-x').pfValue;
    let gy = edge.pstyle('ghost-offset-y').pfValue;
    let ghostOpacity = edge.pstyle('ghost-opacity').value;
    let effectiveGhostOpacity = opacity * ghostOpacity;

    context.translate( gx, gy );

    drawLine( effectiveGhostOpacity );
    drawArrows( effectiveGhostOpacity );

    context.translate( -gx, -gy );
  }

  drawLine();
  drawArrows();
  drawOverlay();
  drawText();

  if( shiftToOriginWithBb ){
    context.translate( bb.x1, bb.y1 );
  }
};

CRp.drawEdgePath = function( edge, context, pts, type ){
  let rs = edge._private.rscratch;
  let canvasCxt = context;
  let path;
  let pathCacheHit = false;
  let usePaths = this.usePaths();
  let dashStyle = edge.pstyle('dash-style').pfValue;
  let lineDashOffset = edge.pstyle('line-dash-offset').pfValue;

  if( usePaths ){
    let pathCacheKey = pts.join( '$' );
    let keyMatches = rs.pathCacheKey && rs.pathCacheKey === pathCacheKey;

    if( keyMatches ){
      path = context = rs.pathCache;
      pathCacheHit = true;
    } else {
      path = context = new Path2D();
      rs.pathCacheKey = pathCacheKey;
      rs.pathCache = path;
    }
  }

  if( canvasCxt.setLineDash ){ // for very outofdate browsers
    switch( type ){
      case 'dotted':
        canvasCxt.setLineDash( [ 1, 1 ] );
        break;

      case 'dashed':
        canvasCxt.setLineDash( dashStyle );
        canvasCxt.lineDashOffset = lineDashOffset;
        break;

      case 'solid':
        canvasCxt.setLineDash( [ ] );
        break;
    }
  }

  if( !pathCacheHit && !rs.badLine ){
    if( context.beginPath ){ context.beginPath(); }
    context.moveTo( pts[0], pts[1] );

    switch( rs.edgeType ){
      case 'bezier':
      case 'self':
      case 'compound':
      case 'multibezier':
        for( let i = 2; i + 3 < pts.length; i += 4 ){
          context.quadraticCurveTo( pts[ i ], pts[ i + 1], pts[ i + 2], pts[ i + 3] );
        }
        break;

      case 'straight':
      case 'segments':
      case 'haystack':
        for( let i = 2; i + 1 < pts.length; i += 2 ){
          context.lineTo( pts[ i ], pts[ i + 1] );
        }
        break;
    }
  }

  context = canvasCxt;
  if( usePaths ){
    context.stroke( path );
  } else {
    context.stroke();
  }

  // reset any line dashes
  if( context.setLineDash ){ // for very outofdate browsers
    context.setLineDash( [ ] );
  }

};

CRp.drawArrowheads = function( context, edge, opacity ){
  let rs = edge._private.rscratch;
  let isHaystack = rs.edgeType === 'haystack';

  if( !isHaystack ){
    this.drawArrowhead( context, edge, 'source', rs.arrowStartX, rs.arrowStartY, rs.srcArrowAngle, opacity );
  }

  this.drawArrowhead( context, edge, 'mid-target', rs.midX, rs.midY, rs.midtgtArrowAngle, opacity );

  this.drawArrowhead( context, edge, 'mid-source', rs.midX, rs.midY, rs.midsrcArrowAngle, opacity );

  if( !isHaystack ){
    this.drawArrowhead( context, edge, 'target', rs.arrowEndX, rs.arrowEndY, rs.tgtArrowAngle, opacity );
  }
};

CRp.drawArrowhead = function( context, edge, prefix, x, y, angle, opacity ){
  if( isNaN( x ) || x == null || isNaN( y ) || y == null || isNaN( angle ) || angle == null ){ return; }

  let self = this;
  let arrowShape = edge.pstyle( prefix + '-arrow-shape' ).value;
  if( arrowShape === 'none' ) { return; }

  let arrowClearFill = edge.pstyle( prefix + '-arrow-fill' ).value === 'hollow' ? 'both' : 'filled';
  let arrowFill = edge.pstyle( prefix + '-arrow-fill' ).value;
  let edgeWidth = edge.pstyle( 'width' ).pfValue;
  let edgeOpacity = edge.pstyle( 'opacity' ).value;

  if( opacity === undefined ){
    opacity = edgeOpacity;
  }

  let gco = context.globalCompositeOperation;

  if( opacity !== 1 || arrowFill === 'hollow' ){ // then extra clear is needed
    context.globalCompositeOperation = 'destination-out';

    self.colorFillStyle( context, 255, 255, 255, 1 );
    self.colorStrokeStyle( context, 255, 255, 255, 1 );

    self.drawArrowShape( edge, context,
      arrowClearFill, edgeWidth, arrowShape, x, y, angle
    );

    context.globalCompositeOperation = gco;
  } // otherwise, the opaque arrow clears it for free :)

  let color = edge.pstyle( prefix + '-arrow-color' ).value;
  self.colorFillStyle( context, color[0], color[1], color[2], opacity );
  self.colorStrokeStyle( context, color[0], color[1], color[2], opacity );

  self.drawArrowShape( edge, context,
    arrowFill, edgeWidth, arrowShape, x, y, angle
  );
};

CRp.drawArrowShape = function( edge, context, fill, edgeWidth, shape, x, y, angle ){
  let r = this;
  let usePaths = this.usePaths();
  let pathCacheHit = false;
  let path;
  let canvasContext = context;
  let translation = { x, y };
  let scale = edge.pstyle( 'arrow-scale' ).value;
  let size = this.getArrowWidth( edgeWidth, scale );
  let shapeImpl = r.arrowShapes[ shape ];

  if( usePaths ){
    let cache = r.arrowPathCache = r.arrowPathCache || [];
    let key = util.hashString(shape);
    let cachedPath = cache[ key ];

    if( cachedPath != null ){
      path = context = cachedPath;
      pathCacheHit = true;
    } else {
      path = context = new Path2D();
      cache[ key ] = path;
    }
  }

  if( context.beginPath ){ context.beginPath(); }

  if( !pathCacheHit ){
    if( usePaths ){ // store in the path cache with values easily manipulated later
      shapeImpl.draw( context, 1, 0, { x: 0, y: 0 }, 1 );
    } else {
      shapeImpl.draw( context, size, angle, translation, edgeWidth );
    }
  }

  if( context.closePath ){ context.closePath(); }

  context = canvasContext;

  if( usePaths ){ // set transform to arrow position/orientation
    context.translate( x, y );
    context.rotate( angle );
    context.scale( size, size );
  }

  if( fill === 'filled' || fill === 'both' ){
    if( usePaths ){
      context.fill( path );
    } else {
      context.fill();
    }
  }

  if( fill === 'hollow' || fill === 'both' ){
    context.lineWidth = ( shapeImpl.matchEdgeWidth ? edgeWidth : 1 ) / ( usePaths ? size : 1 );
    context.lineJoin = 'miter';

    if( usePaths ){
      context.stroke( path );
    } else {
      context.stroke();
    }
  }

  if( usePaths ){ // reset transform by applying inverse
    context.scale( 1/size, 1/size );
    context.rotate( -angle );
    context.translate( -x, -y );
  }
};

export default CRp;
<|endoftext|>


<commit_before>var hue = require("node-hue-api");
var HueApi = require("node-hue-api").HueApi;
var machina = require('machina');

module.exports = {

  name: 'Hue Adapter',
  logName: 'HueAdapter: ',
  linkButtonIntervalMs: 5000,
  searchNewNodesIntervalMs: 60000,
  hueBridge: null,

  signals: new machina.Fsm({
    namespace: 'hue-signal',
    initialState: 'uninitialized',
    states: {
      uninitialized: {
        "*": function () {
          this.deferUntilTransition();
          this.transition('searchBridges');
        }
      },
      searchBridges: {
        _onEnter: function () {
          this.emit("searchBridges");
        },
        'bridgeNotFound': function () {
          this.transition('bridgeNotFound');
        },
        'initializeBridge': function () {
          this.transition('initializeBridge');
        }
      },
      initializeBridge: {
        _onEnter: function () {
          this.emit("initializeBridge");
        },
        'waitingForLinkButton': function () {
          this.transition('waitingForLinkButton');
        }
      },
      waitingForLinkButton: {
        _onEnter: function() {
          this.timer = setTimeout( function() {
            this.handle( 'timeout' );
          }.bind( this ), 5000 );
        },
        timeout: 'initializeBridge',
        _onExit: function() {
          clearTimeout( this.timer );
        }
      },
      bridgeNotFound: {
        _onEnter: function () {
        }
      }
    }
  }),

  initializeBridge: function initializeBridge() {
    sails.log.debug(this.logName + "Registering with hue bridge");
    var that = this;

    BridgeSetting.findOne({bridgeId: that.logName, key: 'userId'}).exec(
      function (err, record) {
        if (record) {
          console.log('key:' + record.value);
        }
    });

    var hueApi = new HueApi();

    hueApi.createUser(that.hueBridge.ipaddress, function(err, user) {
      if (err) {
        sails.log.error(that.logName + "Error registering with bridge:" + err);
        that.signals.handle('waitingForLinkButton');
      } else {
        BridgeSetting.create ({
          bridgeId: that.logName,
          key: 'userId',
          value: user
        }).exec(function (error, created) {
          sails.log.info(that.logName + "Saved key")
        });
      }
    });
  },

  searchBridges: function searchBridges() {
    sails.log.debug(this.logName + "Searching for hue bridges");
    var that = this;
    hue.nupnpSearch(function (err, result) {
      if (err) {
        sails.log.error(that.logName + "Error searching for bridges:" + err);
        that.signals.handle('bridgeNotFound');
      } else {
        if (result.length === 0) {
          sails.log.debug(that.logName + "No Hue bridges Found.");
          that.signals.handle('bridgeNotFound');
        } else {
          var bridge = result[0];
          sails.log.debug(that.logName + "Bridge found: " + JSON.stringify(bridge));
          that.hueBridge = bridge;
          that.signals.handle('initializeBridge');
        }
      }
    });
  },

  init: function () {
    sails.log.info(this.logName + ": Starting");
    var that = this;
    this.signals.on('searchBridges', function() { that.searchBridges(); });
    this.signals.on('initializeBridge', function() { that.initializeBridge(); });
    this.signals.handle('init');
  },

  getStatus: function getStatus() {
    return this.signals.compositeState()
  }
};

<commit_msg>Lights now fetched from hue<commit_after>var hue = require("node-hue-api");
var HueApi = require("node-hue-api").HueApi;
var machina = require('machina');

module.exports = {

  name: 'Hue Adapter',
  logName: 'HueAdapter: ',
  linkButtonIntervalMs: 5000,
  searchNewNodesIntervalMs: 60000,
  hueBridge: null,
  hueApi: null,

  signals: new machina.Fsm({
    namespace: 'hue-signal',
    initialState: 'uninitialized',
    states: {
      uninitialized: {
        "*": function () {
          this.deferUntilTransition();
          this.transition('searchBridges');
        }
      },
      searchBridges: {
        _onEnter: function () {
          this.emit("searchBridges");
        },
        'bridgeNotFound': function () {
          this.transition('bridgeNotFound');
        },
        'initializeBridge': function () {
          this.transition('initializeBridge');
        }
      },
      initializeBridge: {
        _onEnter: function () {
          this.emit("initializeBridge");
        },
        'waitingForLinkButton': function () {
          this.transition('waitingForLinkButton');
        },
        'fetchingLights': function () {
          this.transition('fetchingLights');
        }
      },
      waitingForLinkButton: {
        _onEnter: function() {
          this.timer = setTimeout( function() {
            this.handle( 'timeout' );
          }.bind( this ), 5000 );
        },
        timeout: 'initializeBridge',
        _onExit: function() {
          clearTimeout( this.timer );
        }
      },
      fetchingLights: {
        _onEnter: function() {
          this.emit("fetchingLights");
        }
      },
      initialized: {
        _onEnter: function() {
          this.timer = setTimeout( function() {
            this.handle( 'timeout' );
          }.bind( this ), 60000 );
        },
        timeout: 'fetchingLights',
        _onExit: function() {
          clearTimeout( this.timer );
        }
      },
      bridgeNotFound: {
        _onEnter: function () {
        }
      }
    }
  }),

  connectWithKey: function connectWithKey(key) {
    sails.log.debug(this.logName + "Connecting with credentials");

    this.hueApi = new HueApi(this.hueBridge.ipaddress, key);

    var that = this;

    that.hueApi.description(function(err, result) {
      if (err) {
        sails.log.error(that.logName + "Error getting bridge description: " + err);
      } else {
        sails.log.debug(that.logName + "Connected to " + result.model.name);
        that.signals.handle('fetchingLights');
      }
    });
  },

  registerWithBridge: function registerWithBridge() {
    sails.log.debug(this.logName + "Registering with hue bridge");

    var hueApi = new HueApi();
    var that = this;

    hueApi.createUser(that.hueBridge.ipaddress, function(err, key) {
      if (err) {
        sails.log.error(that.logName + "Error registering with bridge:" + err);
        that.signals.handle('waitingForLinkButton');
      } else {
        console.log(that.logName + "Key received from bridge");

        BridgeSetting.create ({
          bridgeId: that.logName,
          key: 'userId',
          value: key
        }).exec(function (error, created) {
          if (!error) {
            sails.log.info(that.logName + "Saved key")
            that.connectWithKey(key);
          } else {
            sails.log.error(that.logName + error);
          }
        });
      }
    });
  },

  initializeBridge: function initializeBridge() {
    var that = this;
    sails.log.debug(that.logName + "Initializing bridge");

    var that = this;
    BridgeSetting.findOne({bridgeId: that.logName, key: 'userId'}).exec(
      function (err, record) {
        if (record) {
          that.connectWithKey(record.value);

        } else {
          that.registerWithBridge();
        }
    });
  },

  searchBridges: function searchBridges() {
    sails.log.debug(this.logName + "Searching for hue bridges");
    var that = this;
    hue.nupnpSearch(function (err, result) {
      if (err) {
        sails.log.error(that.logName + "Error searching for bridges:" + err);
        that.signals.handle('bridgeNotFound');
      } else {
        if (result.length === 0) {
          sails.log.debug(that.logName + "No Hue bridges Found.");
          that.signals.handle('bridgeNotFound');
        } else {
          var bridge = result[0];
          sails.log.debug(that.logName + "Bridge found: " + JSON.stringify(bridge));
          that.hueBridge = bridge;
          that.signals.handle('initializeBridge');
        }
      }
    });
  },

  fetchingLights: function fetchingLights() {
    sails.log.debug(this.logName + "Fetching lights");
    var that = this;
    that.hueApi.lights(function (err, result) {
      if (err) {
        sails.log.error(that.logName + "Error fetching lights from bridge:" + err);
        that.signals.handle('bridgeNotFound');
      } else {
        if (result.lights.length === 0) {
          sails.log.debug(that.logName + "No Hue lights Found.");
          that.signals.handle('bridgeNotFound');
        } else {
          _.each(result.lights, function(light) {
            sails.log.debug(that.logName + "Found light " + light.name + " (" + light.uniqueid + ")");
          });
        }
      }
    });
  },

  init: function () {
    sails.log.info(this.logName + ": Starting");
    var that = this;
    this.signals.on('searchBridges', function() { that.searchBridges(); });
    this.signals.on('initializeBridge', function() { that.initializeBridge(); });
    this.signals.on('fetchingLights', function() { that.fetchingLights(); });
    this.signals.handle('init');
  },

  getStatus: function getStatus() {
    return this.signals.compositeState()
  }
};

<|endoftext|>


<commit_before>const fetch = require('node-fetch');
const URL = require('url');

const ORIGIN = '18.195.228.187';

function analyzeSpeedKit(urlToTest) {
  const url = {
    protocol: 'http',
    host: ORIGIN,
    pathname: '/config',
    search: `url=${encodeURIComponent(urlToTest)}`,
  };

  const urlString = URL.format(url);
  return fetch(urlString)
    .then((res) => {
      if (res.status === 404) {
        throw new Error(`Not a valid Speed Kit URL: ${urlString}`);
      }

      return res.json();
    });
}

exports.analyzeSpeedKit = analyzeSpeedKit;
<commit_msg>Change host used for analyzeSpeedKit code<commit_after>const fetch = require('node-fetch');
const URL = require('url');
const credentials = require('./credentials');

const ORIGIN = credentials.makefast_ip;

function analyzeSpeedKit(urlToTest) {
  const url = {
    protocol: 'http',
    host: ORIGIN,
    pathname: '/config',
    search: `url=${encodeURIComponent(urlToTest)}`,
  };

  const urlString = URL.format(url);
  return fetch(urlString)
    .then((res) => {
      if (res.status === 404) {
        throw new Error(`Not a valid Speed Kit URL: ${urlString}`);
      }

      return res.json();
    });
}

exports.analyzeSpeedKit = analyzeSpeedKit;
<|endoftext|>


<commit_before>// api/policies/flashMessage.js
"use strict";

/**
 * Policy to check if flash messages are set from controllers.
 *
 * @param   {Request}   request     Request object
 * @param   {Response}  response    Response object
 * @param   {Function}  next        Callback function to call after policy is processed
 */
module.exports = function(request, response, next) {
    var session = request.session;

    /**
     * Setter method for flash messages. This will store message to session and it will
     * be shown in next request. Actual messages are shown via noty in client side.
     *
     * @param   {String}    message Message to show
     * @param   {String}    type    Message type, defaults to "success"
     * @param   {{}}        options Extra options for message
     */
    request.flash.message = function(message, type, options) {
        type = type || "success";
        options = options || {};

        // Store message to session
        request.session.messages.push({
            "message": message,
            "type": type,
            "options": options
        });
    };

    // Get messages from session or initialize message session
    var messages = session.messages || (session.messages = []);

    // Store current messages to res.locals so they can be accessed from views
    response.locals({
        flashMessages: (!messages.length) ? false : messages
    });

    // Clear existing messages from session
    request.session.messages = [];
};<commit_msg>Bug fix for policy.<commit_after>// api/policies/flashMessage.js
"use strict";

/**
 * Policy to check if flash messages are set from controllers.
 *
 * @param   {Request}   request     Request object
 * @param   {Response}  response    Response object
 * @param   {Function}  next        Callback function to call after policy is processed
 */
module.exports = function flashMessage(request, response, next) {
    sails.log.verbose(" POLICY - api/policies/flashMessage.js");

    var session = request.session;

    /**
     * Setter method for flash messages. This will store message to session and it will
     * be shown in next request. Actual messages are shown via noty in client side.
     *
     * @param   {String}    message Message to show
     * @param   {String}    type    Message type, defaults to "success"
     * @param   {{}}        options Extra options for message
     */
    request.flash.message = function(message, type, options) {
        type = type || "success";
        options = options || {};

        // Store message to session
        request.session.messages.push({
            "message": message,
            "type": type,
            "options": options
        });
    };

    // Get messages from session or initialize message session
    var messages = session.messages || (session.messages = []);

    // Store current messages to res.locals so they can be accessed from views
    response.locals({
        flashMessages: (!messages.length) ? false : messages
    });

    // Clear existing messages from session
    request.session.messages = [];

    next();
};<|endoftext|>


<commit_before>var cron = require('node-cron');

////////// UTILS
var logFunction = function log() {
    return "Function fired at: >>> " + new Date().toLocaleString();
};

var messageTestFunction = function (req, res) {

    MessageServices.sendMailGun("fsilvapucci@gmail.com",
        "Cron Message = " + new Date().toLocaleString(),
        "This is an automatic Cron Message = " + new Date().toLocaleString(),
        res);
};

var lastExecution = "N/A";

var task = null;

//USAGE ONLY IN DEVELOPMENT
//FOR FUTURE SPRINTS, EXPRESSION WILL SEND IN POST, ON START

/// Node-Cron Instructions
/**
 *
 # ┌────────────── second (optional)
 # │ ┌──────────── minute
 # │ │ ┌────────── hour
 # │ │ │ ┌──────── day of month
 # │ │ │ │ ┌────── month
 # │ │ │ │ │ ┌──── day of week
 # │ │ │ │ │ │
 # │ │ │ │ │ │
 # * * * * * *

 Example:

 Every second divisible by 10 (ended with 0)
 "* /10 * * * * *"
 */
var cronExpression = '0 */5 * * * *';//5 minutes refreshing
//var cronExpression = '*/5 * * * * *';//5 seconds refreshing

var CronServices = {

    startCron: function fcnStartCron() {

        sails.log("Starting CRON feature");

        try {
            task = cron.schedule(cronExpression, function () {
                console.log(logFunction());

                //CALLING KEEP-ALIVE REQUEST
                KeepAliveServices.keep_alive();

                //messageTestFunction();

                //CALLING FUNCTION TO ENQUEUE NEXT TASKS
                KeepAliveServices.nextQueue();

                //CALLING FUNCTION TO EXECUTE QUEUED TASKS
                KeepAliveServices.executeQueue();
                lastExecution = new Date().toLocaleString();

            });

            task.start();

        } catch (err) {
            sails.log.error("Function START ERROR: " + err);
            return ("Function START ERROR: " + err);
        }

        sails.log("DONE");
        return 200;

    },

    stopCron: function fcnStopCron() {

        sails.log("Stopping CRON feature");

        try {
            if (task !== null) {

                task.stop();
                task = null;

            } else {
                sails.log.error("There's NOT any TASK running!");
                return ("There's NOT any TASK running!");
            }

        } catch (err) {
            sails.log.error("Function STOP ERROR: " + err);
            return ("Function STOP ERROR: " + err);
        }

        sails.log("DONE");
        return 200;
    },

    checkCron: function fcnCheckCron() {

        sails.log("Checking CRON status");

        if (task !== null) {
            sails.log("HEALTHCHECK:\nTASK running!\n" +
                "Configuration: " + cronExpression +
                "\nLast Execution at: " + lastExecution);

            return ("HEALTHCHECK:\nTASK running!\n" +
                "Configuration: " + cronExpression +
                "\nLast Execution at: " + lastExecution);
        } else {
            sails.log("HEALTHCHECK:\nThere's NOT any TASK running!");
            return ("HEALTHCHECK:\nThere's NOT any TASK running!" + "\n"
                + sails.config.environment_config.teste);
        }
    }
};

module.exports = CronServices; <commit_msg>Refactoring to prevent start multiple Cron Tasks<commit_after>var cron = require('node-cron');

////////// UTILS
var logFunction = function log() {
  return "Function fired at: >>> " + new Date().toLocaleString();
};

var messageTestFunction = function (req, res) {

  MessageServices.sendMailGun("fsilvapucci@gmail.com",
    "Cron Message = " + new Date().toLocaleString(),
    "This is an automatic Cron Message = " + new Date().toLocaleString(),
    res);
};

var lastExecution = "N/A";

var task = null;

//USAGE ONLY IN DEVELOPMENT
//FOR FUTURE SPRINTS, EXPRESSION WILL SEND IN POST, ON START

/// Node-Cron Instructions
/**
 *
 # ┌────────────── second (optional)
 # │ ┌──────────── minute
 # │ │ ┌────────── hour
 # │ │ │ ┌──────── day of month
 # │ │ │ │ ┌────── month
 # │ │ │ │ │ ┌──── day of week
 # │ │ │ │ │ │
 # │ │ │ │ │ │
 # * * * * * *

 Example:

 Every second divisible by 10 (ended with 0)
 "* /10 * * * * *"
 */
var cronExpression = '0 */5 * * * *'; //5 minutes refreshing
//var cronExpression = '*/5 * * * * *';//5 seconds refreshing

var CronServices = {

  startCron: function fcnStartCron() {

    if (!task) {
      sails.log("Starting CRON feature");

      try {
        task = cron.schedule(cronExpression, function () {
          console.log(logFunction());

          //CALLING KEEP-ALIVE REQUEST
          KeepAliveServices.keep_alive();

          //messageTestFunction();

          //CALLING FUNCTION TO ENQUEUE NEXT TASKS
          KeepAliveServices.nextQueue();

          //CALLING FUNCTION TO EXECUTE QUEUED TASKS
          KeepAliveServices.executeQueue();
          lastExecution = new Date().toLocaleString();

        });

        task.start();

      } catch (err) {
        sails.log.error("Function START ERROR: " + err);
        return ("Function START ERROR: " + err);
      }

      sails.log("DONE");
    } else {
      sails.log("START:\n You have a TASK running and can't start another! Please call STOP before\n" +
        "Configuration: " + cronExpression +
        "\nLast Execution at: " + lastExecution);

      return "START:\n You have a TASK running and can't start another! Please call STOP before\n" +
        "Configuration: " + cronExpression +
        "\nLast Execution at: " + lastExecution;
    }
    return 200;

  },

  stopCron: function fcnStopCron() {

    sails.log("Stopping CRON feature");

    try {
      if (task !== null) {

        task.stop();
        task = null;

      } else {
        sails.log.error("There's NOT any TASK running!");
        return ("There's NOT any TASK running!");
      }

    } catch (err) {
      sails.log.error("Function STOP ERROR: " + err);
      return ("Function STOP ERROR: " + err);
    }

    sails.log("DONE");
    return 200;
  },

  checkCron: function fcnCheckCron() {

    sails.log("Checking CRON status");

    if (task !== null) {
      sails.log("HEALTHCHECK:\nTASK running!\n" +
        "Configuration: " + cronExpression +
        "\nLast Execution at: " + lastExecution);

      return ("HEALTHCHECK:\nTASK running!\n" +
        "Configuration: " + cronExpression +
        "\nLast Execution at: " + lastExecution);
    } else {
      sails.log("HEALTHCHECK:\nThere's NOT any TASK running!");
      return ("HEALTHCHECK:\nThere's NOT any TASK running!" + "\n" +
        sails.config.environment_config.teste);
    }
  }
};

module.exports = CronServices;
<|endoftext|>


<commit_before>import _ from 'lodash';

import * as constants from '../constants';
import Settings from '../WDLSettings';
import Port from '../../../model/Port';

import { buildDeclarations } from '../utils/utils';

export default class WorkflowGenerator {
  constructor(wfStep, settings) {
    this.wfBodyElementGenerators = {
      call: this.genCall,
      scatter: this.genScatter,
      whileloop: this.genWhile,
      if: this.genIf,
      workflow: this.genWorkflow,
    };
    this.wfName = wfStep.name;
    this.wfStep = wfStep;

    const action = wfStep.action;
    this.declarations = this.getDeclarations(wfStep);
    this.outputMappings = wfStep.o;

    this.children = wfStep.children;

    this.meta = action.data.meta;
    this.parameterMeta = action.data.parameterMeta;

    this.wfBlockString = '';

    this.settings = new Settings(settings);
  }

  getDeclarations(step) {
    const declarations = {};
    _.forEach(step.action.i || {}, (input, name) => {
      declarations[name] = input;
    });
    _.forEach(step.ownDeclarations || {}, (declaration, name) => {
      declarations[name] = {
        default: declaration.expression.string,
        type: declaration.desc.type,
      };
    });
    return declarations;
  }

  renderWorkflow() {
    const EOL = this.settings.getValue('style.eol');

    if (this.wfBlockString === '') {
      this.wfBlockString += `${constants.WORKFLOW} ${this.wfName} ${constants.SCOPE_OPEN}${EOL}`;

      const prosessed = [];
      this.wfBlockString += this.renderStepMainBody(this.wfStep, prosessed);
      this.wfBlockString += this.buildSegment(constants.META, this.meta);
      this.wfBlockString += this.buildSegment(constants.PARAMETER_META, this.parameterMeta);
      this.wfBlockString += this.buildOutputMap(this.outputMappings);

      this.wfBlockString += `${constants.SCOPE_CLOSE}${EOL}${EOL}`;
    }
    return this.wfBlockString;
  }

  renderStepMainBody(step, prosessed) {
    const declarations = this.getDeclarations(step);
    const children = step.children;

    let res = '';

    res += buildDeclarations(declarations, this.settings);

    for (let i = 0, size = _.size(children); i < size; ++i) {
      const childName = this.getNextOrderedChild(children, prosessed);
      prosessed.push(childName);

      const child = children[childName];
      res += this.wfBodyElementGenerators[child.type || 'call'].call(this, child, prosessed);
    }

    return res;
  }

  getNextOrderedChild(children, processed) {
    let res = '';

    _.forEach(children, (child) => {
      if (_.indexOf(processed, child.name) < 0) {
        res = child.name;
        return false;
      }

      return true;
    });

    if (res === '') {
      throw new Error('Cycled links are not allowed');
    }
    return res;
  }

  buildPortValue(value) {
    if (value.desc && value.desc.default && !_.isUndefined(value.desc.default)) {
      return `${value.desc.default}`;
    } else if (value.desc && value.desc.expression && !_.isUndefined(value.desc.expression)) {
      return `${value.desc.expression}`;
    } else if (value.expression && value.expression.type.toLowerCase() !== 'identifier'
      && value.expression.type.toLowerCase() !== 'memberaccess' && !_.isUndefined(value.expression.string)) {
      return `${value.expression.string}`;
    } else if (value.inputs && _.size(value.inputs) > 0) {
      if (_.size(value.inputs) > 1) {
        throw new Error('Multiple links into one input are prohibited');
      }

      const connection = value.inputs[0];
      if (connection.from instanceof Port) {
        const outStep = connection.from.step;
        const outStepName = outStep.name;
        const outVarName = connection.from.name;

        if (outStepName === this.wfName || outStep.type) {
          return outVarName;
        }
        return `${outStepName}.${outVarName}`;
      }
      return connection.from;
    }
    return '';
  }

  genCall(child) {
    const EOL = this.settings.getValue('style.eol');
    const SCOPE_INDENT = this.settings.getValue('style.scope_indent');
    const DOUBLE_SCOPE_INDENT = `${SCOPE_INDENT}${SCOPE_INDENT}`;
    const TRIPLE_SCOPE_INDENT = `${DOUBLE_SCOPE_INDENT}${SCOPE_INDENT}`;

    let res = '';

    const val = child;
    let callString = `${SCOPE_INDENT}${constants.CALL} `;

    if (val.action.name === val.name) {
      callString += `${val.name}`;
    } else {
      callString += `${val.action.name} ${constants.AS} ${val.name}`;
    }

    res += `${callString}`;

    if (_.size(val.i) > 0) {
      let mappingWasFounded = false;

      _.forEach(val.i, (pVal, pKey) => {
        if (pVal.inputs && _.size(pVal.inputs) > 0) {
          if (!mappingWasFounded) {
            res += ` ${constants.SCOPE_OPEN}${EOL}`;
            res += `${DOUBLE_SCOPE_INDENT}${constants.INPUT}${constants.COLON}${EOL}`;
            mappingWasFounded = true;
          }
          res += `${TRIPLE_SCOPE_INDENT}${pKey} ${constants.EQ} ${this.buildPortValue(pVal)},${EOL}`;
        }
      });
      if (mappingWasFounded) {
        res += `${SCOPE_INDENT}${constants.SCOPE_CLOSE}`;
      }
    }

    return `${res}${EOL}`;
  }

  genScatter(child, prosessed) {
    const EOL = this.settings.getValue('style.eol');
    const SCOPE_INDENT = this.settings.getValue('style.scope_indent');

    let res = '';

    let item;
    _.forEach(child.i, (val) => {
      if (val.desc.type === 'ScatterItem') {
        item = val;
      }
    });

    if (_.isUndefined(item)) {
      throw new Error('Scatter model is not valid');
    }

    res += `${SCOPE_INDENT}${constants.SCATTER} (${item.name} ${constants.IN} ${this.buildPortValue(item)}) {${EOL}`;

    return this.genBodyCloser(res, child, prosessed);
  }

  genIf(child, prosessed) {
    const EOL = this.settings.getValue('style.eol');
    const SCOPE_INDENT = this.settings.getValue('style.scope_indent');

    let res = '';

    const expression = child.action.data.expression;
    res += `${SCOPE_INDENT}${constants.IF} (${expression}) ${constants.SCOPE_OPEN}${EOL}`;

    return this.genBodyCloser(res, child, prosessed);
  }

  genWhile(child, prosessed) {
    const EOL = this.settings.getValue('style.eol');
    const SCOPE_INDENT = this.settings.getValue('style.scope_indent');

    let res = '';

    const expression = child.action.data.expression;
    res += `${SCOPE_INDENT}${constants.WHILE} (${expression}) ${constants.SCOPE_OPEN}${EOL}`;

    return this.genBodyCloser(res, child, prosessed);
  }

  genBodyCloser(res, child, prosessed) {
    const EOL = this.settings.getValue('style.eol');
    const SCOPE_INDENT = this.settings.getValue('style.scope_indent');

    const innerBody = this.renderStepMainBody(child, prosessed);
    const bodyStringArr = innerBody.split(EOL);

    _.forEach(bodyStringArr, (str) => {
      if (str !== '') {
        res += `${SCOPE_INDENT}${str}${EOL}`;
      }
    });

    res += `${SCOPE_INDENT}${constants.SCOPE_CLOSE}${EOL}`;
    return res;
  }

  genWorkflow(child) {
    // TODO: add generation workflow
    this.genCall(child);
  }

  buildOutputMap(outputMappings) {
    const EOL = this.settings.getValue('style.eol');
    const SCOPE_INDENT = this.settings.getValue('style.scope_indent');
    const DOUBLE_SCOPE_INDENT = `${SCOPE_INDENT}${SCOPE_INDENT}`;

    let res = '';
    if (outputMappings && _.size(outputMappings) > 0) {
      res += `${SCOPE_INDENT}${constants.OUTPUT} ${constants.SCOPE_OPEN}${EOL}`;

      _.forEach(outputMappings, (val, key) => {
        if (key.indexOf('.') >= 0) {
          res += `${DOUBLE_SCOPE_INDENT}${key}${EOL}`;
        } else {
          res += `${DOUBLE_SCOPE_INDENT}${val.desc.type} ${key} ${constants.EQ} ${this.buildPortValue(val)}${EOL}`;
        }
      });

      res += `${SCOPE_INDENT}${constants.SCOPE_CLOSE}${EOL}`;
    }

    return res;
  }

  buildSegment(segmentName, data) {
    const EOL = this.settings.getValue('style.eol');
    const SCOPE_INDENT = this.settings.getValue('style.scope_indent');
    const DOUBLE_SCOPE_INDENT = `${SCOPE_INDENT}${SCOPE_INDENT}`;

    const buildValue = value => ` ${constants.EQ} ${value.toString()}`;

    let res = '';
    if (data && _.size(data) > 0) {
      res += `${SCOPE_INDENT}${segmentName} ${constants.SCOPE_OPEN}${EOL}`;

      _.forEach(data, (val, key) => {
        res += `${DOUBLE_SCOPE_INDENT}${key}${buildValue(val)}${EOL}`;
      });

      res += `${SCOPE_INDENT}${constants.SCOPE_CLOSE}${EOL}`;
    }

    return res;
  }
}
<commit_msg>fixed eslint<commit_after>import _ from 'lodash';

import * as constants from '../constants';
import Settings from '../WDLSettings';
import Port from '../../../model/Port';

import { buildDeclarations } from '../utils/utils';

export default class WorkflowGenerator {
  constructor(wfStep, settings) {
    this.wfBodyElementGenerators = {
      call: this.genCall,
      scatter: this.genScatter,
      whileloop: this.genWhile,
      if: this.genIf,
      workflow: this.genWorkflow,
    };
    this.wfName = wfStep.name;
    this.wfStep = wfStep;

    const action = wfStep.action;
    this.declarations = this.getDeclarations(wfStep);
    this.outputMappings = wfStep.o;

    this.children = wfStep.children;

    this.meta = action.data.meta;
    this.parameterMeta = action.data.parameterMeta;

    this.wfBlockString = '';

    this.settings = new Settings(settings);
  }

  // eslint-disable-next-line class-methods-use-this
  getDeclarations(step) {
    const declarations = {};
    _.forEach(step.action.i || {}, (input, name) => {
      declarations[name] = input;
    });
    _.forEach(step.ownDeclarations || {}, (declaration, name) => {
      declarations[name] = {
        default: declaration.expression.string,
        type: declaration.desc.type,
      };
    });
    return declarations;
  }

  renderWorkflow() {
    const EOL = this.settings.getValue('style.eol');

    if (this.wfBlockString === '') {
      this.wfBlockString += `${constants.WORKFLOW} ${this.wfName} ${constants.SCOPE_OPEN}${EOL}`;

      const prosessed = [];
      this.wfBlockString += this.renderStepMainBody(this.wfStep, prosessed);
      this.wfBlockString += this.buildSegment(constants.META, this.meta);
      this.wfBlockString += this.buildSegment(constants.PARAMETER_META, this.parameterMeta);
      this.wfBlockString += this.buildOutputMap(this.outputMappings);

      this.wfBlockString += `${constants.SCOPE_CLOSE}${EOL}${EOL}`;
    }
    return this.wfBlockString;
  }

  renderStepMainBody(step, prosessed) {
    const declarations = this.getDeclarations(step);
    const children = step.children;

    let res = '';

    res += buildDeclarations(declarations, this.settings);

    for (let i = 0, size = _.size(children); i < size; ++i) {
      const childName = this.getNextOrderedChild(children, prosessed);
      prosessed.push(childName);

      const child = children[childName];
      res += this.wfBodyElementGenerators[child.type || 'call'].call(this, child, prosessed);
    }

    return res;
  }

  // eslint-disable-next-line class-methods-use-this
  getNextOrderedChild(children, processed) {
    let res = '';

    _.forEach(children, (child) => {
      if (_.indexOf(processed, child.name) < 0) {
        res = child.name;
        return false;
      }

      return true;
    });

    if (res === '') {
      throw new Error('Cycled links are not allowed');
    }
    return res;
  }

  buildPortValue(value) {
    if (value.desc && value.desc.default && !_.isUndefined(value.desc.default)) {
      return `${value.desc.default}`;
    } else if (value.desc && value.desc.expression && !_.isUndefined(value.desc.expression)) {
      return `${value.desc.expression}`;
    } else if (value.expression && value.expression.type.toLowerCase() !== 'identifier'
      && value.expression.type.toLowerCase() !== 'memberaccess' && !_.isUndefined(value.expression.string)) {
      return `${value.expression.string}`;
    } else if (value.inputs && _.size(value.inputs) > 0) {
      if (_.size(value.inputs) > 1) {
        throw new Error('Multiple links into one input are prohibited');
      }

      const connection = value.inputs[0];
      if (connection.from instanceof Port) {
        const outStep = connection.from.step;
        const outStepName = outStep.name;
        const outVarName = connection.from.name;

        if (outStepName === this.wfName || outStep.type) {
          return outVarName;
        }
        return `${outStepName}.${outVarName}`;
      }
      return connection.from;
    }
    return '';
  }

  genCall(child) {
    const EOL = this.settings.getValue('style.eol');
    const SCOPE_INDENT = this.settings.getValue('style.scope_indent');
    const DOUBLE_SCOPE_INDENT = `${SCOPE_INDENT}${SCOPE_INDENT}`;
    const TRIPLE_SCOPE_INDENT = `${DOUBLE_SCOPE_INDENT}${SCOPE_INDENT}`;

    let res = '';

    const val = child;
    let callString = `${SCOPE_INDENT}${constants.CALL} `;

    if (val.action.name === val.name) {
      callString += `${val.name}`;
    } else {
      callString += `${val.action.name} ${constants.AS} ${val.name}`;
    }

    res += `${callString}`;

    if (_.size(val.i) > 0) {
      let mappingWasFounded = false;

      _.forEach(val.i, (pVal, pKey) => {
        if (pVal.inputs && _.size(pVal.inputs) > 0) {
          if (!mappingWasFounded) {
            res += ` ${constants.SCOPE_OPEN}${EOL}`;
            res += `${DOUBLE_SCOPE_INDENT}${constants.INPUT}${constants.COLON}${EOL}`;
            mappingWasFounded = true;
          }
          res += `${TRIPLE_SCOPE_INDENT}${pKey} ${constants.EQ} ${this.buildPortValue(pVal)},${EOL}`;
        }
      });
      if (mappingWasFounded) {
        res += `${SCOPE_INDENT}${constants.SCOPE_CLOSE}`;
      }
    }

    return `${res}${EOL}`;
  }

  genScatter(child, prosessed) {
    const EOL = this.settings.getValue('style.eol');
    const SCOPE_INDENT = this.settings.getValue('style.scope_indent');

    let res = '';

    let item;
    _.forEach(child.i, (val) => {
      if (val.desc.type === 'ScatterItem') {
        item = val;
      }
    });

    if (_.isUndefined(item)) {
      throw new Error('Scatter model is not valid');
    }

    res += `${SCOPE_INDENT}${constants.SCATTER} (${item.name} ${constants.IN} ${this.buildPortValue(item)}) {${EOL}`;

    return this.genBodyCloser(res, child, prosessed);
  }

  genIf(child, prosessed) {
    const EOL = this.settings.getValue('style.eol');
    const SCOPE_INDENT = this.settings.getValue('style.scope_indent');

    let res = '';

    const expression = child.action.data.expression;
    res += `${SCOPE_INDENT}${constants.IF} (${expression}) ${constants.SCOPE_OPEN}${EOL}`;

    return this.genBodyCloser(res, child, prosessed);
  }

  genWhile(child, prosessed) {
    const EOL = this.settings.getValue('style.eol');
    const SCOPE_INDENT = this.settings.getValue('style.scope_indent');

    let res = '';

    const expression = child.action.data.expression;
    res += `${SCOPE_INDENT}${constants.WHILE} (${expression}) ${constants.SCOPE_OPEN}${EOL}`;

    return this.genBodyCloser(res, child, prosessed);
  }

  genBodyCloser(res, child, prosessed) {
    const EOL = this.settings.getValue('style.eol');
    const SCOPE_INDENT = this.settings.getValue('style.scope_indent');

    const innerBody = this.renderStepMainBody(child, prosessed);
    const bodyStringArr = innerBody.split(EOL);

    _.forEach(bodyStringArr, (str) => {
      if (str !== '') {
        res += `${SCOPE_INDENT}${str}${EOL}`;
      }
    });

    res += `${SCOPE_INDENT}${constants.SCOPE_CLOSE}${EOL}`;
    return res;
  }

  genWorkflow(child) {
    // TODO: add generation workflow
    this.genCall(child);
  }

  buildOutputMap(outputMappings) {
    const EOL = this.settings.getValue('style.eol');
    const SCOPE_INDENT = this.settings.getValue('style.scope_indent');
    const DOUBLE_SCOPE_INDENT = `${SCOPE_INDENT}${SCOPE_INDENT}`;

    let res = '';
    if (outputMappings && _.size(outputMappings) > 0) {
      res += `${SCOPE_INDENT}${constants.OUTPUT} ${constants.SCOPE_OPEN}${EOL}`;

      _.forEach(outputMappings, (val, key) => {
        if (key.indexOf('.') >= 0) {
          res += `${DOUBLE_SCOPE_INDENT}${key}${EOL}`;
        } else {
          res += `${DOUBLE_SCOPE_INDENT}${val.desc.type} ${key} ${constants.EQ} ${this.buildPortValue(val)}${EOL}`;
        }
      });

      res += `${SCOPE_INDENT}${constants.SCOPE_CLOSE}${EOL}`;
    }

    return res;
  }

  buildSegment(segmentName, data) {
    const EOL = this.settings.getValue('style.eol');
    const SCOPE_INDENT = this.settings.getValue('style.scope_indent');
    const DOUBLE_SCOPE_INDENT = `${SCOPE_INDENT}${SCOPE_INDENT}`;

    const buildValue = value => ` ${constants.EQ} ${value.toString()}`;

    let res = '';
    if (data && _.size(data) > 0) {
      res += `${SCOPE_INDENT}${segmentName} ${constants.SCOPE_OPEN}${EOL}`;

      _.forEach(data, (val, key) => {
        res += `${DOUBLE_SCOPE_INDENT}${key}${buildValue(val)}${EOL}`;
      });

      res += `${SCOPE_INDENT}${constants.SCOPE_CLOSE}${EOL}`;
    }

    return res;
  }
}
<|endoftext|>