<commit_before>/**
 * Author: Russell Toris
 * Version: October 8, 2012
 *
 * Converted to AMD by Jihoon Lee
 * Version: September 27, 2012
 */

(function(root, factory) {
  if (typeof define === 'function' && define.amd) {
    define([ 'eventemitter2', 'actionclient', 'map' ], factory);
  } else {
    root.Nav2D = factory(root.EventEmitter2, root.ActionClient, root.Map);
  }
}
    (
        this,
        function(EventEmitter2, ActionClient, Map) {
          var Nav2D = function(options) {
            var nav2D = this;
            options = options || {};
            nav2D.ros = options.ros;
            nav2D.serverName = options.serverName || '/move_base';
            nav2D.actionName = options.actionName
                || 'move_base_msgs/MoveBaseAction';
            nav2D.serverTimeout = options.serverTimeout || 5000;
            nav2D.mapTopic = options.mapTopic || '/map';
            nav2D.continuous = options.continuous;
            nav2D.canvasID = options.canvasID;
            // optional (used if you do not want to stream /map or use a custom image)
            nav2D.image = options.image;
            nav2D.mapMetaTopic = options.mapMetaTopic || '/map_metadata';
            // optional color settings
            nav2D.clickColor = options.clickColor || '#543210';
            nav2D.robotColor = options.robotColor || '#012345';
            nav2D.initialPoseTopic = options.initialPoseTopic || '/initialpose';

            // draw robot
            nav2D.drawrobot = options.drawrobot;

            nav2D.mode = 'none';

            // current robot pose message
            nav2D.robotPose = null;
            // current goal
            nav2D.goalMessage = null;

            // icon information for displaying robot and click positions
            var clickRadius = 1;
            var clickUpdate = true;
            var maxClickRadius = 5;
            var robotRadius = 1;
            var robotRadiusGrow = true;
            var maxRobotRadius = 10;

            // position information
            var robotX;
            var robotY;
            var robotRotZ;
            var clickX;
            var clickY;

            // map and metadata
            var map;
            var mapWidth;
            var mapHeight;
            var mapResolution;
            var mapX;
            var mapY;
            var drawInterval;

            // flag to see if everything (map image, metadata, and robot pose) is available
            var available = false;

            // grab the canvas
            var canvas = document.getElementById(nav2D.canvasID);

            // check if we need to fetch a map or if an image was provided
            if (nav2D.image) {
              // set the image
              map = new Image();
              map.src = nav2D.image;

              // get the meta information
              var metaListener = new nav2D.ros.Topic({
                name : nav2D.mapMetaTopic,
                messageType : 'nav_msgs/MapMetaData'
              });
              metaListener.subscribe(function(metadata) {
                // set the metadata
                mapWidth = metadata.width;
                mapHeight = metadata.height;
                mapResolution = metadata.resolution;
                mapX = metadata.origin.position.x;
                mapY = metadata.origin.position.y;

                // we only need the metadata once
                metaListener.unsubscribe();
              });
            } else {
              // create a map object
              var mapFetcher = new Map({
                ros : nav2D.ros,
                mapTopic : nav2D.mapTopic,
                continuous : nav2D.continuous
              });
              mapFetcher.on('available', function() {
                // store the image
                map = mapFetcher.image;

                // set the metadata
                mapWidth = mapFetcher.info.width;
                mapHeight = mapFetcher.info.height;
                mapResolution = mapFetcher.info.resolution;
                mapX = mapFetcher.info.origin.position.x;
                mapY = mapFetcher.info.origin.position.y;
              });
            }

            // setup a listener for the robot pose
            var poseListener = new nav2D.ros.Topic({
              name : '/robot_pose',
              messageType : 'geometry_msgs/Pose',
              throttle_rate : 100,
            });
            poseListener
                .subscribe(function(pose) {
                  // set the public field
                  nav2D.robotPose = pose;

                  // only update once we know the map metadata
                  if (mapWidth && mapHeight && mapResolution) {
                    // get the current canvas size
                    var canvasWidth = canvas.getAttribute('width');
                    var canvasHeight = canvas.getAttribute('height');

                    // set the pixel location with (0, 0) at the top left
                    robotX = ((pose.position.x - mapX) / mapResolution)
                        * (canvasWidth / mapWidth);
                    robotY = canvasHeight
                        - (((pose.position.y - mapY) / mapResolution) * (canvasHeight / mapHeight));

                    // get the rotation Z
                    var q0 = pose.orientation.w;
                    var q1 = pose.orientation.x;
                    var q2 = pose.orientation.y;
                    var q3 = pose.orientation.z;

                    robotRotZ = -Math.atan2(2 * ( q0 * q3 + q1 * q2) , 1 - 2 * (Math.pow(q2,2) +Math.pow(q3,2)));

                    // check if this is the first time we have all information
                    if (!available) {
                      available = true;
                      // notify the user we are available
                      nav2D.emit('available');
                      // set the interval for the draw function
                      drawInterval = setInterval(draw, 30);
                    }
                  }
                });

            // setup the actionlib client
            var actionClient = new ActionClient({
              ros : nav2D.ros,
              actionName : nav2D.actionName,
              serverName : nav2D.serverName,
              timeout : nav2D.serverTimeout
            });
            // pass the event up
            actionClient.on('timeout', function() {
              nav2D.emit('timeout');
            });

            // create a cancel
            nav2D.cancel = function() {
              actionClient.cancel();
            };

            nav2D.drawrobot = nav2D.drawrobot || function(context,robotX,robotY) {
              context.fillStyle = nav2D.robotColor;
              context.beginPath();
              context.arc(robotX, robotY, robotRadius, 0, Math.PI * 2, true);
              context.closePath();
              context.fill();

              // grow and shrink the icon
              if (robotRadiusGrow) {
                robotRadius++;
              } else {
                robotRadius--;
              }
              if (robotRadius == maxRobotRadius || robotRadius == 1) {
                robotRadiusGrow = !robotRadiusGrow;
              }
            };

            // create the draw function
            var draw = function() {
              // grab the drawing context
              var context = canvas.getContext('2d');

              // grab the current sizes
              var width = canvas.getAttribute('width');
              var height = canvas.getAttribute('height');

              // add the image back to the canvas
              context.drawImage(map, 0, 0, width, height);

              // check if the user clicked yet
              if (clickX && clickY && nav2D.mode == 'none') {
                // draw the click point
                context.fillStyle = nav2D.clickColor;
                context.beginPath();
                context.arc(clickX, clickY, clickRadius, 0, Math.PI * 2,true);
                context.closePath();
                context.fill();

                // grow half the speed of the refresh rate
                if (clickUpdate) {
                  clickRadius++;
                }

                // reset at the threshold (i.e., blink)
                if (clickRadius == maxClickRadius) {
                  clickRadius = 1;
                }

                clickUpdate = !clickUpdate;
              }

              // draw the robot location
              nav2D.drawrobot(context,robotX,robotY,robotRotZ);
            };

            // get the position in the world from a point clicked by the user
            nav2D.getPoseFromEvent = function(event) {
              // only go if we have the map data
              if (available) {
                // get the y location with (0, 0) at the top left
                var offsetLeft = 0;
                var offsetTop = 0;
                var element = canvas;
                while (element && !isNaN(element.offsetLeft)
                    && !isNaN(element.offsetTop)) {
                  offsetLeft += element.offsetLeft - element.scrollLeft;
                  offsetTop += element.offsetTop - element.scrollTop;
                  element = element.offsetParent;
                }
                clickX = event.pageX - offsetLeft;
                clickY = event.pageY - offsetTop;

                // convert the pixel location to a pose
                var canvasWidth = canvas.getAttribute('width');
                var canvasHeight = canvas.getAttribute('height');
                var x = (clickX * (mapWidth / canvasWidth) * mapResolution)
                    + mapX;
                var y = ((canvasHeight - clickY) * (mapHeight / canvasHeight) * mapResolution)
                    + mapY;
                return [ x, y ];
              } else {
                return null;
              }
            };

            // a function to send the robot to the given goal location
            nav2D.sendGoalPose = function(x, y) {
              // create a goal
              var goal = new actionClient.Goal({
                target_pose : {
                  header : {
                    frame_id : '/map'
                  },
                  pose : {
                    position : {
                      x : x,
                      y : y,
                      z : 0
                    },
                    orientation : {
                      x : 0,
                      y : 0,
                      z : 0.6,
                      w : 0.8
                    }
                  }
                }
              });
              goal.send();

              nav2D.goalMessage = goal.goalMessage;

              // pass up the events to the user
              goal.on('result', function(result) {
                nav2D.emit('result', result);
                nav2D.mode = 'none';

                // clear the click icon
                clickX = null;
                clickY = null;
              });
              goal.on('status', function(status) {
                nav2D.emit('status', status);
              });
              goal.on('feedback', function(feedback) {
                nav2D.emit('feedback', feedback);
              });
            };

           canvas.addEventListener('click',function(event) {
             if(nav2D.mode == 'none') {           }
             else if(nav2D.mode == 'init')
             {
               var poses = nav2D.getPoseFromEvent(event);
               if (poses != null) {
                 nav2D.sendInitPose(poses[0], poses[1]);
               } else {
                 nav2D.emit('error',"All of the necessary navigation information is not yet available.");
               }
             }
             else if(nav2D.mode == 'goal') {
               var poses = nav2D.getPoseFromEvent(event);
               if (poses != null) {
                 nav2D.sendGoalPose(poses[0], poses[1]);
               } else {
                 nav2D.emit('error',"All of the necessary navigation information is not yet available.");
               }
             }
             else {
               nav2D.emit('error',"Wrong mode..");
             }
             nav2D.mode = 'none';
            });

            nav2D.setmode = function(mode) {
              nav2D.mode = mode;
              clickX = null;
              clickY = null;
            };

            nav2D.initPosePub = new nav2D.ros.Topic({
              name : nav2D.initialPoseTopic,
              type : 'geometry_msgs/PoseWithCovarianceStamped',
            });

            nav2D.sendInitPose = function(x,y) {
              var pose_msg = new ros.Message({
                header : {
                    frame_id : '/map'
                },
                pose : {
                  pose : {
                    position: {
                      x : x,
                      y : y,
                      z : 0,
                    },
                    orientation : {
                      x : 0,
                      y : 0,
                      z : 0,
                      w : 1,
                    },
                  },
                  covariance: [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]
                },
              });
              nav2D.initPosePub.publish(pose_msg);
              nav2D.setmode('none');
            };

            canvas
                .addEventListener(
                    'dblclick',
                    function(event) {
                      var poses = nav2D.getPoseFromEvent(event);
                      if (poses != null) {
                        nav2D.sendGoalPose(poses[0], poses[1]);
                      } else {
                        nav2D
                            .emit('error',
                                "All of the necessary navigation information is not yet available.");
                      }
                    });
          };
          Nav2D.prototype.__proto__ = EventEmitter2.prototype;
          return Nav2D;
        }));
<commit_msg>read only mode added<commit_after>/**
 * Author: Russell Toris
 * Version: October 8, 2012
 *
 * Converted to AMD by Jihoon Lee
 * Version: September 27, 2012
 */

(function(root, factory) {
  if (typeof define === 'function' && define.amd) {
    define([ 'eventemitter2', 'actionclient', 'map' ], factory);
  } else {
    root.Nav2D = factory(root.EventEmitter2, root.ActionClient, root.Map);
  }
}
    (
        this,
        function(EventEmitter2, ActionClient, Map) {
          var Nav2D = function(options) {
            var nav2D = this;
            options = options || {};
            nav2D.ros = options.ros;
            nav2D.serverName = options.serverName || '/move_base';
            nav2D.actionName = options.actionName
                || 'move_base_msgs/MoveBaseAction';
            nav2D.serverTimeout = options.serverTimeout || 5000;
            nav2D.mapTopic = options.mapTopic || '/map';
            nav2D.continuous = options.continuous;
            nav2D.canvasID = options.canvasID;
            // optional (used if you do not want to stream /map or use a custom image)
            nav2D.image = options.image;
            nav2D.mapMetaTopic = options.mapMetaTopic || '/map_metadata';
            // optional color settings
            nav2D.clickColor = options.clickColor || '#543210';
            nav2D.robotColor = options.robotColor || '#012345';
            nav2D.initialPoseTopic = options.initialPoseTopic || '/initialpose';
            nav2D.readOnly = options.readOnly;

            // draw robot
            nav2D.drawrobot = options.drawrobot;

            nav2D.mode = 'none';

            // current robot pose message
            nav2D.robotPose = null;
            // current goal
            nav2D.goalMessage = null;

            // icon information for displaying robot and click positions
            var clickRadius = 1;
            var clickUpdate = true;
            var maxClickRadius = 5;
            var robotRadius = 1;
            var robotRadiusGrow = true;
            var maxRobotRadius = 10;

            // position information
            var robotX;
            var robotY;
            var robotRotZ;
            var clickX;
            var clickY;

            // map and metadata
            var map;
            var mapWidth;
            var mapHeight;
            var mapResolution;
            var mapX;
            var mapY;
            var drawInterval;

            // flag to see if everything (map image, metadata, and robot pose) is available
            var available = false;

            // grab the canvas
            var canvas = document.getElementById(nav2D.canvasID);

            // check if we need to fetch a map or if an image was provided
            if (nav2D.image) {
              // set the image
              map = new Image();
              map.src = nav2D.image;

              // get the meta information
              var metaListener = new nav2D.ros.Topic({
                name : nav2D.mapMetaTopic,
                messageType : 'nav_msgs/MapMetaData'
              });
              metaListener.subscribe(function(metadata) {
                // set the metadata
                mapWidth = metadata.width;
                mapHeight = metadata.height;
                mapResolution = metadata.resolution;
                mapX = metadata.origin.position.x;
                mapY = metadata.origin.position.y;

                // we only need the metadata once
                metaListener.unsubscribe();
              });
            } else {
              // create a map object
              var mapFetcher = new Map({
                ros : nav2D.ros,
                mapTopic : nav2D.mapTopic,
                continuous : nav2D.continuous
              });
              mapFetcher.on('available', function() {
                // store the image
                map = mapFetcher.image;

                // set the metadata
                mapWidth = mapFetcher.info.width;
                mapHeight = mapFetcher.info.height;
                mapResolution = mapFetcher.info.resolution;
                mapX = mapFetcher.info.origin.position.x;
                mapY = mapFetcher.info.origin.position.y;
              });
            }

            // setup a listener for the robot pose
            var poseListener = new nav2D.ros.Topic({
              name : '/robot_pose',
              messageType : 'geometry_msgs/Pose',
              throttle_rate : 100,
            });
            poseListener
                .subscribe(function(pose) {
                  // set the public field
                  nav2D.robotPose = pose;

                  // only update once we know the map metadata
                  if (mapWidth && mapHeight && mapResolution) {
                    // get the current canvas size
                    var canvasWidth = canvas.getAttribute('width');
                    var canvasHeight = canvas.getAttribute('height');

                    // set the pixel location with (0, 0) at the top left
                    robotX = ((pose.position.x - mapX) / mapResolution)
                        * (canvasWidth / mapWidth);
                    robotY = canvasHeight
                        - (((pose.position.y - mapY) / mapResolution) * (canvasHeight / mapHeight));

                    // get the rotation Z
                    var q0 = pose.orientation.w;
                    var q1 = pose.orientation.x;
                    var q2 = pose.orientation.y;
                    var q3 = pose.orientation.z;

                    robotRotZ = -Math.atan2(2 * ( q0 * q3 + q1 * q2) , 1 - 2 * (Math.pow(q2,2) +Math.pow(q3,2)));

                    // check if this is the first time we have all information
                    if (!available) {
                      available = true;
                      // notify the user we are available
                      nav2D.emit('available');
                      // set the interval for the draw function
                      drawInterval = setInterval(draw, 30);
                    }
                  }
                });

            // setup the actionlib client
            var actionClient = new ActionClient({
              ros : nav2D.ros,
              actionName : nav2D.actionName,
              serverName : nav2D.serverName,
              timeout : nav2D.serverTimeout
            });
            // pass the event up
            actionClient.on('timeout', function() {
              nav2D.emit('timeout');
            });

            // create a cancel
            nav2D.cancel = function() {
              actionClient.cancel();
            };

            nav2D.drawrobot = nav2D.drawrobot || function(context,robotX,robotY) {
              context.fillStyle = nav2D.robotColor;
              context.beginPath();
              context.arc(robotX, robotY, robotRadius, 0, Math.PI * 2, true);
              context.closePath();
              context.fill();

              // grow and shrink the icon
              if (robotRadiusGrow) {
                robotRadius++;
              } else {
                robotRadius--;
              }
              if (robotRadius == maxRobotRadius || robotRadius == 1) {
                robotRadiusGrow = !robotRadiusGrow;
              }
            };

            // create the draw function
            var draw = function() {
              // grab the drawing context
              var context = canvas.getContext('2d');

              // grab the current sizes
              var width = canvas.getAttribute('width');
              var height = canvas.getAttribute('height');

              // add the image back to the canvas
              context.drawImage(map, 0, 0, width, height);

              // check if the user clicked yet
              if (clickX && clickY && nav2D.mode == 'none') {
                // draw the click point
                context.fillStyle = nav2D.clickColor;
                context.beginPath();
                context.arc(clickX, clickY, clickRadius, 0, Math.PI * 2,true);
                context.closePath();
                context.fill();

                // grow half the speed of the refresh rate
                if (clickUpdate) {
                  clickRadius++;
                }

                // reset at the threshold (i.e., blink)
                if (clickRadius == maxClickRadius) {
                  clickRadius = 1;
                }

                clickUpdate = !clickUpdate;
              }

              // draw the robot location
              nav2D.drawrobot(context,robotX,robotY,robotRotZ);
            };

            // get the position in the world from a point clicked by the user
            nav2D.getPoseFromEvent = function(event) {
              // only go if we have the map data
              if (available) {
                // get the y location with (0, 0) at the top left
                var offsetLeft = 0;
                var offsetTop = 0;
                var element = canvas;
                while (element && !isNaN(element.offsetLeft)
                    && !isNaN(element.offsetTop)) {
                  offsetLeft += element.offsetLeft - element.scrollLeft;
                  offsetTop += element.offsetTop - element.scrollTop;
                  element = element.offsetParent;
                }
                clickX = event.pageX - offsetLeft;
                clickY = event.pageY - offsetTop;

                // convert the pixel location to a pose
                var canvasWidth = canvas.getAttribute('width');
                var canvasHeight = canvas.getAttribute('height');
                var x = (clickX * (mapWidth / canvasWidth) * mapResolution)
                    + mapX;
                var y = ((canvasHeight - clickY) * (mapHeight / canvasHeight) * mapResolution)
                    + mapY;
                return [ x, y ];
              } else {
                return null;
              }
            };

            // a function to send the robot to the given goal location
            nav2D.sendGoalPose = function(x, y) {
              // create a goal
              var goal = new actionClient.Goal({
                target_pose : {
                  header : {
                    frame_id : '/map'
                  },
                  pose : {
                    position : {
                      x : x,
                      y : y,
                      z : 0
                    },
                    orientation : {
                      x : 0,
                      y : 0,
                      z : 0.6,
                      w : 0.8
                    }
                  }
                }
              });
              goal.send();

              nav2D.goalMessage = goal.goalMessage;

              // pass up the events to the user
              goal.on('result', function(result) {
                nav2D.emit('result', result);
                nav2D.mode = 'none';

                // clear the click icon
                clickX = null;
                clickY = null;
              });
              goal.on('status', function(status) {
                nav2D.emit('status', status);
              });
              goal.on('feedback', function(feedback) {
                nav2D.emit('feedback', feedback);
              });
            };

           canvas.addEventListener('click',function(event) {
             if(nav2D.mode == 'none') {           }
             else if(nav2D.mode == 'init')
             {
               var poses = nav2D.getPoseFromEvent(event);
               if (poses != null) {
                 nav2D.sendInitPose(poses[0], poses[1]);
               } else {
                 nav2D.emit('error',"All of the necessary navigation information is not yet available.");
               }
             }
             else if(nav2D.mode == 'goal') {
               var poses = nav2D.getPoseFromEvent(event);
               if (poses != null) {
                 nav2D.sendGoalPose(poses[0], poses[1]);
               } else {
                 nav2D.emit('error',"All of the necessary navigation information is not yet available.");
               }
             }
             else {
               nav2D.emit('error',"Wrong mode..");
             }
             nav2D.mode = 'none';
            });

            nav2D.setmode = function(mode) {
              nav2D.mode = mode;
              clickX = null;
              clickY = null;
            };

            nav2D.initPosePub = new nav2D.ros.Topic({
              name : nav2D.initialPoseTopic,
              type : 'geometry_msgs/PoseWithCovarianceStamped',
            });

            nav2D.sendInitPose = function(x,y) {
              var pose_msg = new ros.Message({
                header : {
                    frame_id : '/map'
                },
                pose : {
                  pose : {
                    position: {
                      x : x,
                      y : y,
                      z : 0,
                    },
                    orientation : {
                      x : 0,
                      y : 0,
                      z : 0,
                      w : 1,
                    },
                  },
                  covariance: [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]
                },
              });
              nav2D.initPosePub.publish(pose_msg);
              nav2D.setmode('none');
            };

            // check for read only
            if(!nav2D.readOnly) {
              canvas
                  .addEventListener(
                      'dblclick',
                      function(event) {
                        var poses = nav2D.getPoseFromEvent(event);
                        if (poses != null) {
                          nav2D.sendGoalPose(poses[0], poses[1]);
                        } else {
                          nav2D
                              .emit('error',
                                  "All of the necessary navigation information is not yet available.");
                        }
                      });
            }
          };
          Nav2D.prototype.__proto__ = EventEmitter2.prototype;
          return Nav2D;
        }));
<|endoftext|>


<commit_before>'use strict';

const fs = require('fs');
const url = require('url');
var formidable = require('formidable');
const settings = require('../../lib/settings');
var mongo = require('../../lib/mongo');
var parse = require('../../lib/parse');

class SettingsService {
  constructor() {
    this.defaultSettings = {
      'logo_file': null,
      'language': 'en',
      'currency_code': 'USD',
      'currency_symbol': '$',
      'currency_format': '${amount}',
      'thousand_separator': ',',
      'decimal_separator': '.',
      'decimal_number': 2,
      'timezone': 'Asia/Singapore',
      'date_format': 'MMMM D, YYYY',
      'time_format': 'h:mm a',
      'default_shipping_country': 'SG',
      'default_shipping_state': '',
      'default_shipping_city': '',
      'default_product_sorting': 'stock_status,price,position',
      'weight_unit': 'kg',
      'length_unit': 'cm'
    }
  }

  getSettings() {
    return mongo.db.collection('settings').findOne().then(settings => {
      return this.changeProperties(settings);
    });
  }

  updateSettings(data) {
    const settings = this.getValidDocumentForUpdate(data);
    return this.insertDefaultSettingsIfEmpty().then(() => mongo.db.collection('settings').updateOne({}, {
      $set: settings
    }, {upsert: true}).then(res => this.getSettings()));
  }

  insertDefaultSettingsIfEmpty() {
    return mongo.db.collection('settings').count().then(count => {
      if (count === 0) {
        return mongo.db.collection('settings').insertOne(this.defaultSettings);
      } else {
        return;
      }
    });
  }

  getValidDocumentForUpdate(data) {
    if (Object.keys(data).length === 0) {
      return new Error('Required fields are missing');
    }

    let settings = {}

    if (data.language !== undefined) {
      settings.language = parse.getString(data.language);
    }

    if (data.currency_code !== undefined) {
      settings.currency_code = parse.getString(data.currency_code);
    }

    if (data.currency_symbol !== undefined) {
      settings.currency_symbol = parse.getString(data.currency_symbol);
    }

    if (data.currency_format !== undefined) {
      settings.currency_format = parse.getString(data.currency_format);
    }

    if (data.thousand_separator !== undefined) {
      settings.thousand_separator = parse.getString(data.thousand_separator);
    }

    if (data.decimal_separator !== undefined) {
      settings.decimal_separator = parse.getString(data.decimal_separator);
    }

    if (data.decimal_number !== undefined) {
      settings.decimal_number = parse.getNumberIfPositive(data.decimal_number) || 2;
    }

    if (data.timezone !== undefined) {
      settings.timezone = parse.getString(data.timezone);
    }

    if (data.date_format !== undefined) {
      settings.date_format = parse.getString(data.date_format);
    }

    if (data.time_format !== undefined) {
      settings.time_format = parse.getString(data.time_format);
    }

    if (data.default_shipping_country !== undefined) {
      settings.default_shipping_country = parse.getString(data.default_shipping_country);
    }

    if (data.default_shipping_state !== undefined) {
      settings.default_shipping_state = parse.getString(data.default_shipping_state);
    }

    if (data.default_shipping_city !== undefined) {
      settings.default_shipping_city = parse.getString(data.default_shipping_city);
    }

    if (data.default_product_sorting !== undefined) {
      settings.default_product_sorting = parse.getString(data.default_product_sorting);
    }

    if (data.weight_unit !== undefined) {
      settings.weight_unit = parse.getString(data.weight_unit);
    }

    if (data.length_unit !== undefined) {
      settings.length_unit = parse.getString(data.length_unit);
    }

    if (data.logo_file !== undefined) {
      settings.logo_file = parse.getString(data.logo_file);
    }

    return settings;
  }

  changeProperties(data) {
    if (data) {
      delete data._id;
      data.logo = (data.logo_file && data.logo_file.length > 0) ? settings.url.files + '/' + data.logo_file : null;
      return data;
    } else {
      return this.defaultSettings;
    }
  }

  deleteLogo() {
    return this.getSettings().then(settings => {
      if(settings.logo_file && settings.logo_file.length > 0) {
        let filePath = settings.path.files + '/' + settings.logo_file;
        fs.unlink(filePath, (err) => {
          this.updateSettings({ 'logo_file': null });
        })
      }
    })
  }

  uploadLogo(req, res, next) {
    let form = new formidable.IncomingForm(),
        file_name = null,
        file_size = 0;

    form
      .on('fileBegin', (name, file) => {
        // Emitted whenever a field / value pair has been received.
        file.path = settings.path.files + '/' + file.name;
      })
      .on('file', function(field, file) {
        // every time a file has been uploaded successfully,
        file_name = file.name;
        file_size = file.size;
      })
      .on('error', (err) => {
        res.status(500).send(this.getErrorMessage(err));
      })
      .on('end', () => {
        //Emitted when the entire request has been received, and all contained files have finished flushing to disk.
        if(file_name) {
          this.updateSettings({ 'logo_file': file_name });
          res.send({ 'file': file_name, 'size': file_size });
        } else {
          res.status(400).send(this.getErrorMessage('Required fields are missing'));
        }
      });

    form.parse(req);
  }

  getErrorMessage(err) {
    return { 'error': true, 'message': err.toString() };
  }
}

module.exports = new SettingsService();
<commit_msg>Fix settings name<commit_after>'use strict';

const fs = require('fs');
const url = require('url');
var formidable = require('formidable');
const settings = require('../../lib/settings');
var mongo = require('../../lib/mongo');
var parse = require('../../lib/parse');

class SettingsService {
  constructor() {
    this.defaultSettings = {
      'logo_file': null,
      'language': 'en',
      'currency_code': 'USD',
      'currency_symbol': '$',
      'currency_format': '${amount}',
      'thousand_separator': ',',
      'decimal_separator': '.',
      'decimal_number': 2,
      'timezone': 'Asia/Singapore',
      'date_format': 'MMMM D, YYYY',
      'time_format': 'h:mm a',
      'default_shipping_country': 'SG',
      'default_shipping_state': '',
      'default_shipping_city': '',
      'default_product_sorting': 'stock_status,price,position',
      'weight_unit': 'kg',
      'length_unit': 'cm'
    }
  }

  getSettings() {
    return mongo.db.collection('settings').findOne().then(settings => {
      return this.changeProperties(settings);
    });
  }

  updateSettings(data) {
    const settings = this.getValidDocumentForUpdate(data);
    return this.insertDefaultSettingsIfEmpty().then(() => mongo.db.collection('settings').updateOne({}, {
      $set: settings
    }, {upsert: true}).then(res => this.getSettings()));
  }

  insertDefaultSettingsIfEmpty() {
    return mongo.db.collection('settings').count().then(count => {
      if (count === 0) {
        return mongo.db.collection('settings').insertOne(this.defaultSettings);
      } else {
        return;
      }
    });
  }

  getValidDocumentForUpdate(data) {
    if (Object.keys(data).length === 0) {
      return new Error('Required fields are missing');
    }

    let settings = {}

    if (data.language !== undefined) {
      settings.language = parse.getString(data.language);
    }

    if (data.currency_code !== undefined) {
      settings.currency_code = parse.getString(data.currency_code);
    }

    if (data.currency_symbol !== undefined) {
      settings.currency_symbol = parse.getString(data.currency_symbol);
    }

    if (data.currency_format !== undefined) {
      settings.currency_format = parse.getString(data.currency_format);
    }

    if (data.thousand_separator !== undefined) {
      settings.thousand_separator = parse.getString(data.thousand_separator);
    }

    if (data.decimal_separator !== undefined) {
      settings.decimal_separator = parse.getString(data.decimal_separator);
    }

    if (data.decimal_number !== undefined) {
      settings.decimal_number = parse.getNumberIfPositive(data.decimal_number) || 2;
    }

    if (data.timezone !== undefined) {
      settings.timezone = parse.getString(data.timezone);
    }

    if (data.date_format !== undefined) {
      settings.date_format = parse.getString(data.date_format);
    }

    if (data.time_format !== undefined) {
      settings.time_format = parse.getString(data.time_format);
    }

    if (data.default_shipping_country !== undefined) {
      settings.default_shipping_country = parse.getString(data.default_shipping_country);
    }

    if (data.default_shipping_state !== undefined) {
      settings.default_shipping_state = parse.getString(data.default_shipping_state);
    }

    if (data.default_shipping_city !== undefined) {
      settings.default_shipping_city = parse.getString(data.default_shipping_city);
    }

    if (data.default_product_sorting !== undefined) {
      settings.default_product_sorting = parse.getString(data.default_product_sorting);
    }

    if (data.weight_unit !== undefined) {
      settings.weight_unit = parse.getString(data.weight_unit);
    }

    if (data.length_unit !== undefined) {
      settings.length_unit = parse.getString(data.length_unit);
    }

    if (data.logo_file !== undefined) {
      settings.logo_file = parse.getString(data.logo_file);
    }

    return settings;
  }

  changeProperties(data) {
    if (data) {
      delete data._id;
      data.logo = (data.logo_file && data.logo_file.length > 0) ? settings.url.files + '/' + data.logo_file : null;
      return data;
    } else {
      return this.defaultSettings;
    }
  }

  deleteLogo() {
    return this.getSettings().then(data => {
      if(data.logo_file && data.logo_file.length > 0) {
        let filePath = settings.path.files + '/' + data.logo_file;
        fs.unlink(filePath, (err) => {
          this.updateSettings({ 'logo_file': null });
        })
      }
    })
  }

  uploadLogo(req, res, next) {
    let form = new formidable.IncomingForm(),
        file_name = null,
        file_size = 0;

    form
      .on('fileBegin', (name, file) => {
        // Emitted whenever a field / value pair has been received.
        file.path = settings.path.files + '/' + file.name;
      })
      .on('file', function(field, file) {
        // every time a file has been uploaded successfully,
        file_name = file.name;
        file_size = file.size;
      })
      .on('error', (err) => {
        res.status(500).send(this.getErrorMessage(err));
      })
      .on('end', () => {
        //Emitted when the entire request has been received, and all contained files have finished flushing to disk.
        if(file_name) {
          this.updateSettings({ 'logo_file': file_name });
          res.send({ 'file': file_name, 'size': file_size });
        } else {
          res.status(400).send(this.getErrorMessage('Required fields are missing'));
        }
      });

    form.parse(req);
  }

  getErrorMessage(err) {
    return { 'error': true, 'message': err.toString() };
  }
}

module.exports = new SettingsService();
<|endoftext|>


<commit_before>import React from 'react';
import { mount } from 'enzyme';
import FormRenderer from '@data-driven-forms/react-form-renderer';
import SetServiceOwnershipForm from '../../components/set-service-ownership-form';
import createSchema from '../../components/set-service-ownership-form/schema';
import { http } from '../../http_api';

describe('Set service ownership form component', () => {
  let initialProps;
  const httpSpy = jest.spyOn(http, 'post');
  const submitSpy = jest.spyOn(window, 'miqAjaxButton');
  const flashSpy = jest.spyOn(window, 'add_flash');

  beforeEach(() => {
    initialProps = {
      ownershipIds: ['123456'],
      groupOptions: [['Foo', '1'], ['Bar', '2']],
      ownerOptions: [['Baz', '3'], ['Quxx', '4']],
    };
    global.ManageIQ.controller = 'service';
  });

  afterEach(() => {
    submitSpy.mockReset();
    flashSpy.mockReset();
    global.ManageIQ.controller = null;
  });

  it('should correctly map group and owner options ', () => {
    const expectedResult = [
      expect.objectContaining({
        options: [{
          value: '3',
          label: 'Baz',
        }, {
          value: '4',
          label: 'Quxx',
        }],
      }),
      expect.objectContaining({
        options: [{
          value: '1',
          label: 'Foo',
        }, {
          value: '2',
          label: 'Bar',
        }],
      }),
    ];
    const { fields } = createSchema(initialProps.ownerOptions, initialProps.groupOptions);
    expect(fields).toEqual(expectedResult);
  });

  // TO DO replace with actual request mock
  it('should request initialForm values after mount', () => {
    mount(<SetServiceOwnershipForm {...initialProps} />);
    expect(httpSpy).toHaveBeenCalledWith('/service/ownership_form_fields', { object_ids: ['123456'] });
  });

  it('should send correct data on save', () => {
    const wrapper = mount(<SetServiceOwnershipForm {...initialProps} />);
    const Form = wrapper.find(FormRenderer).childAt(0);
    Form.instance().form.change('user', 'foo');
    wrapper.find('button').at(0).simulate('click');
    expect(submitSpy).toHaveBeenCalledWith('/service/ownership_update/?button=save', { objectIds: ['123456'], user: 'foo' });
  });

  it('should send correct data on cancel', () => {
    const wrapper = mount(<SetServiceOwnershipForm {...initialProps} />);
    wrapper.find('button').last().simulate('click');
    expect(submitSpy).toHaveBeenCalledWith('/service/ownership_update/?button=cancel');
  });

  it('should reset formValues and add flash messages on reset click', () => {
    const wrapper = mount(<SetServiceOwnershipForm {...initialProps} />);
    const Form = wrapper.find(FormRenderer).childAt(0);
    Form.instance().form.change('user', 'foo');
    expect(Form.instance().form.getState().values).toEqual({ user: 'foo' });
    wrapper.find('button').at(1).simulate('click');
    expect(Form.instance().form.getState().values).toEqual({});
    expect(flashSpy).toHaveBeenCalledWith(expect.any(String), 'warn');
  });
});
<commit_msg>Fix set service ownership form spec<commit_after>import React from 'react';
import { mount } from 'enzyme';
import FormRenderer from '@data-driven-forms/react-form-renderer';
import SetServiceOwnershipForm from '../../components/set-service-ownership-form';
import createSchema from '../../components/set-service-ownership-form/schema';
import { http } from '../../http_api';
import '../helpers/miqAjaxButton';
import '../helpers/addFlash';

describe('Set service ownership form component', () => {
  let initialProps;
  const httpSpy = jest.spyOn(http, 'post');
  const submitSpy = jest.spyOn(window, 'miqAjaxButton');
  const flashSpy = jest.spyOn(window, 'add_flash');

  beforeEach(() => {
    initialProps = {
      ownershipIds: ['123456'],
      groupOptions: [['Foo', '1'], ['Bar', '2']],
      ownerOptions: [['Baz', '3'], ['Quxx', '4']],
    };
    global.ManageIQ.controller = 'service';
  });

  afterEach(() => {
    submitSpy.mockReset();
    flashSpy.mockReset();
    global.ManageIQ.controller = null;
  });

  it('should correctly map group and owner options ', () => {
    const expectedResult = [
      expect.objectContaining({
        options: [{
          value: '3',
          label: 'Baz',
        }, {
          value: '4',
          label: 'Quxx',
        }],
      }),
      expect.objectContaining({
        options: [{
          value: '1',
          label: 'Foo',
        }, {
          value: '2',
          label: 'Bar',
        }],
      }),
    ];
    const { fields } = createSchema(initialProps.ownerOptions, initialProps.groupOptions);
    expect(fields).toEqual(expectedResult);
  });

  // TO DO replace with actual request mock
  it('should request initialForm values after mount', () => {
    mount(<SetServiceOwnershipForm {...initialProps} />);
    expect(httpSpy).toHaveBeenCalledWith('/service/ownership_form_fields', { object_ids: ['123456'] });
  });

  it('should send correct data on save', () => {
    const wrapper = mount(<SetServiceOwnershipForm {...initialProps} />);
    const Form = wrapper.find(FormRenderer).childAt(0);
    Form.instance().form.change('user', 'foo');
    wrapper.find('button').at(0).simulate('click');
    expect(submitSpy).toHaveBeenCalledWith('/service/ownership_update/?button=save', { objectIds: ['123456'], user: 'foo' });
  });

  it('should send correct data on cancel', () => {
    const wrapper = mount(<SetServiceOwnershipForm {...initialProps} />);
    wrapper.find('button').last().simulate('click');
    expect(submitSpy).toHaveBeenCalledWith('/service/ownership_update/?button=cancel');
  });

  it('should reset formValues and add flash messages on reset click', () => {
    const wrapper = mount(<SetServiceOwnershipForm {...initialProps} />);
    const Form = wrapper.find(FormRenderer).childAt(0);
    Form.instance().form.change('user', 'foo');
    expect(Form.instance().form.getState().values).toEqual({ user: 'foo' });
    wrapper.find('button').at(1).simulate('click');
    expect(Form.instance().form.getState().values).toEqual({});
    expect(flashSpy).toHaveBeenCalledWith(expect.any(String), 'warn');
  });
});
<|endoftext|>


<commit_before>// Copyright (c) 2013, Web Notes Technologies Pvt. Ltd.
// License: GNU General Public License v3. See license.txt

var current_module;

wn.provide('erpnext.startup');

erpnext.startup.start = function() {
	console.log('Starting up...');
	$('#startup_div').html('Starting up...').toggle(true);

	if(user != 'Guest'){
		// setup toolbar
		erpnext.toolbar.setup();

		// complete registration
		if(in_list(user_roles,'System Manager') && (wn.boot.setup_complete==='No')) {
			wn.require("app/js/complete_setup.js");
			erpnext.complete_setup.show();
		} else if(!wn.boot.customer_count) {
			if(wn.get_route()[0]!=="Setup") {
				msgprint(""
					+ wn._("Proceed to Setup") + "\

"+
					wn._("This message goes away after you create your first customer.")+
					"
", wn._("Welcome"));
			}
		} else if(wn.boot.expires_on && in_list(user_roles, 'System Manager')) {
			erpnext.startup.show_expiry_banner();
		}
	}
}

erpnext.startup.show_expiry_banner = function() {
	var today = dateutil.str_to_obj(wn.boot.server_date);
	var expires_on = dateutil.str_to_obj(wn.boot.expires_on);
	var diff = dateutil.get_diff(expires_on, today);
	var payment_link = "\
		Click here to buy subscription.";

	var msg = "";
	if (0 <= diff && diff <= 10) {
		var expiry_string = diff==0 ? "today" : repl("in %(diff)s day(s)", { diff: diff });
		msg = repl('Your ERPNext subscription will expire %(expiry_string)s. %(payment_link)s',
			{ expiry_string: expiry_string, payment_link: payment_link });
	} else if (diff < 0) {
		msg = repl('This ERPNext subscription has expired. %(payment_link)s', {payment_link: payment_link});
	}

	if(msg) wn.ui.toolbar.show_banner(msg);
}

// start
$(document).bind('startup', function() {
	erpnext.startup.start();
});
<commit_msg>Fix translate startup.js<commit_after>// Copyright (c) 2013, Web Notes Technologies Pvt. Ltd.
// License: GNU General Public License v3. See license.txt

var current_module;

wn.provide('erpnext.startup');

erpnext.startup.start = function() {
	console.log(wn._('Starting up...'));
	$('#startup_div').html('Starting up...').toggle(true);

	if(user != 'Guest'){
		// setup toolbar
		erpnext.toolbar.setup();

		// complete registration
		if(in_list(user_roles,'System Manager') && (wn.boot.setup_complete==='No')) {
			wn.require("app/js/complete_setup.js");
			erpnext.complete_setup.show();
		} else if(!wn.boot.customer_count) {
			if(wn.get_route()[0]!=="Setup") {
				msgprint(""
					+ wn._("Proceed to Setup") + "\

"+
					wn._("This message goes away after you create your first customer.")+
					"
", wn._("Welcome"));
			}
		} else if(wn.boot.expires_on && in_list(user_roles, 'System Manager')) {
			erpnext.startup.show_expiry_banner();
		}
	}
}

erpnext.startup.show_expiry_banner = function() {
	var today = dateutil.str_to_obj(wn.boot.server_date);
	var expires_on = dateutil.str_to_obj(wn.boot.expires_on);
	var diff = dateutil.get_diff(expires_on, today);
	var payment_link = ""+
		wn._("Click here to buy subscription.")+"";

	var msg = "";
	if (0 <= diff && diff <= 10) {
		var expiry_string = diff==0 ? "today" : repl("in %(diff)s day(s)", { diff: diff });
		msg = repl(wn._('Your ERPNext subscription will expire %(expiry_string)s. %(payment_link)s')),
			{ expiry_string: expiry_string, payment_link: payment_link });
	} else if (diff < 0) {
		msg = repl(wn._('This ERPNext subscription has expired. %(payment_link)s'), {payment_link: payment_link});
	}

	if(msg) wn.ui.toolbar.show_banner(msg);
}

// start
$(document).bind('startup', function() {
	erpnext.startup.start();
});
<|endoftext|>


<commit_before>CT.require("CT.Pager");
CT.require("CT.Prompt");
CT.require("CT.align");
CT.require("CT.data");
CT.require("CT.dom");
CT.require("CT.log");
CT.require("CT.mobile");
CT.require("CT.panel");
CT.require("CT.parse");
CT.require("CT.pubsub");
CT.require("CT.recaptcha");
CT.require("CT.upload");
CT.require("CT.video");

// import CT.rte as needed (large script import)<commit_msg>added CT.gesture to all import list<commit_after>CT.require("CT.Pager");
CT.require("CT.Prompt");
CT.require("CT.align");
CT.require("CT.data");
CT.require("CT.dom");
CT.require("CT.gesture");
CT.require("CT.log");
CT.require("CT.mobile");
CT.require("CT.panel");
CT.require("CT.parse");
CT.require("CT.pubsub");
CT.require("CT.recaptcha");
CT.require("CT.upload");
CT.require("CT.video");

// import CT.rte as needed (large script import)<|endoftext|>


<commit_before>import find from 'lodash/find';
import { calcZIndex } from 'components/map-vis/map-vis-helper';

/**
 * This function will add all necessary attributes to work in explore page.
 * Furthermore it will set initial params from url.
 * @param {Array} items
 * @param {Array} activeDatasets
 */
function addExploreAttributes(items, activeDatasets) {
  return items.map((dataset) => {
    const existingDataset = find(activeDatasets, { id: dataset.id });

    const layers = dataset.layer.map(l => ({
      ...l,
      isActive: l.default
    }));

    return Object.assign({}, {
      opacity: 1,
      visibility: true,
      zIndex: 0,
      layerIndex: 0,
      isLayerActive: !!existingDataset
    }, existingDataset || {}, dataset, {
      layer: layers
    });
  });
}

export const fetchDatasets = state => ({
  ...state,
  datasets: { ...state.datasets, isFetching: true }
});

export const receiveDatasets = (state, { payload }) => ({
  ...state,
  datasets: {
    ...state.datasets,
    isFetching: false,
    status: 'success',
    items: addExploreAttributes(payload, state.datasets.activeDatasets)
  }
});

export const failureDatasets = (state, { payload }) => ({
  ...state,
  datasets: { ...state.datasets, isFetching: false, status: 'error', message: payload }
});

export const filterQuery = (state, { payload }) => ({
  ...state,
  datasets: { ...state.datasets, filterQuery: payload }
});

export const toggleDataset = (state, { payload }) => {
  const activeDatasets = state.datasets.activeDatasets;
  const { length } = activeDatasets;
  return {
    ...state,
    datasets: {
      ...state.datasets,
      items: state.datasets.items.map((item) => {
        const zIndex = (length + 1) === 1 ? 0 : length;
        if (item.id === payload.id) {
          return Object.assign({}, item, {
            isLayerActive: !item.isLayerActive,
            zIndex
          });
        }
        return item;
      })
    }
  };
};

export const toggleInfo = (state, { payload }) => ({
  ...state,
  datasets: {
    ...state.datasets,
    items: state.datasets.items.map(item => (item.id === payload.id ?
      Object.assign({}, item, { isSelected: !item.isSelected }) :
      Object.assign({}, item, { isSelected: false })))
  }
});

export const toggleVisibility = (state, { payload }) => ({
  ...state,
  datasets: {
    ...state.datasets,
    items: state.datasets.items.map(item => (item.id === payload.id ?
      Object.assign({}, item, { visibility: !item.visibility }) : item))
  }
});

export const setActiveDatasets = (state, { payload }) => ({
  ...state,
  datasets: {
    ...state.datasets,
    activeDatasets: typeof payload === 'string' ? [payload] : payload
  }
});

export const updateActiveDatasets = state => ({
  ...state,
  datasets: {
    ...state.datasets,
    activeDatasets: state.datasets.items.filter(d => d.isLayerActive)
  }
});

export const updateZIndex = (state, { payload }) => {
  const layers = payload.map((l, index) => ({ id: l.dataset, zIndex: index }));
  const { length } = layers;
  const items = state.datasets.items.slice(0).map((item) => {
    const itemFound = find(layers, { id: item.id });
    if (itemFound) {
      const { zIndex } = itemFound;
      return Object.assign({}, item, {
        zIndex,
        layerIndex: calcZIndex(length, zIndex)
      });
    }
    return item;
  });

  return {
    ...state,
    datasets: {
      ...state.datasets,
      items
    }
  };
};

export const updateOpacity = (state, { payload }) => {
  const { id, opacity } = payload;
  const datasets = [...state.datasets.items];

  const items = datasets.map((dataset) => {
    if (dataset.id === id) return { ...dataset, opacity };
    return dataset;
  });

  return {
    ...state,
    datasets: {
      ...state.datasets,
      items
    }
  };
};

export const setMultiActiveLayer = (state, { payload }) => {
  const { temporalResolution, period, scenario, id, layerId } = payload;

  const items = state.datasets.items.map((d) => {

    if (d.id === id && (d.provider === 'nexgddp' || d.provider === 'loca')) {
      const currentLayer = d.metadata[0].info.nexgddp.layers.find(l =>
        l.temp_resolution === temporalResolution.value &&
        l.scenario === scenario.value
      );

      if (!currentLayer) {
        console.error('There is no layer with the params selected. Check that metadata has all the possibilities');
        return d;
      }

      d.layer = [{
        ...d.layer[0],
        ...currentLayer,
        opacity: d.opacity,
        visibility: d.visibility,
        layerIndex: d.layerIndex,
        dataset: id,
        id: currentLayer.layerId,
        isActive: true,
        period
      }];
    }

    if (d.id === id && (d.provider !== 'nexgddp' || d.provider !== 'loca')) {
      d.layer = d.layer.map(l => ({
        ...l,
        isActive: l.id === layerId
      }));
    }

    return d;
  });

  return {
    ...state,
    datasets: {
      ...state.datasets,
      items
    }
  };
};
<commit_msg>explore loca toolbar<commit_after>import find from 'lodash/find';
import { calcZIndex } from 'components/map-vis/map-vis-helper';

/**
 * This function will add all necessary attributes to work in explore page.
 * Furthermore it will set initial params from url.
 * @param {Array} items
 * @param {Array} activeDatasets
 */
function addExploreAttributes(items, activeDatasets) {
  return items.map((dataset) => {
    const existingDataset = find(activeDatasets, { id: dataset.id });

    const layers = dataset.layer.map(l => ({
      ...l,
      isActive: l.default
    }));

    return Object.assign({}, {
      opacity: 1,
      visibility: true,
      zIndex: 0,
      layerIndex: 0,
      isLayerActive: !!existingDataset
    }, existingDataset || {}, dataset, {
      layer: layers
    });
  });
}

export const fetchDatasets = state => ({
  ...state,
  datasets: { ...state.datasets, isFetching: true }
});

export const receiveDatasets = (state, { payload }) => ({
  ...state,
  datasets: {
    ...state.datasets,
    isFetching: false,
    status: 'success',
    items: addExploreAttributes(payload, state.datasets.activeDatasets)
  }
});

export const failureDatasets = (state, { payload }) => ({
  ...state,
  datasets: { ...state.datasets, isFetching: false, status: 'error', message: payload }
});

export const filterQuery = (state, { payload }) => ({
  ...state,
  datasets: { ...state.datasets, filterQuery: payload }
});

export const toggleDataset = (state, { payload }) => {
  const activeDatasets = state.datasets.activeDatasets;
  const { length } = activeDatasets;
  return {
    ...state,
    datasets: {
      ...state.datasets,
      items: state.datasets.items.map((item) => {
        const zIndex = (length + 1) === 1 ? 0 : length;
        if (item.id === payload.id) {
          return Object.assign({}, item, {
            isLayerActive: !item.isLayerActive,
            zIndex
          });
        }
        return item;
      })
    }
  };
};

export const toggleInfo = (state, { payload }) => ({
  ...state,
  datasets: {
    ...state.datasets,
    items: state.datasets.items.map(item => (item.id === payload.id ?
      Object.assign({}, item, { isSelected: !item.isSelected }) :
      Object.assign({}, item, { isSelected: false })))
  }
});

export const toggleVisibility = (state, { payload }) => ({
  ...state,
  datasets: {
    ...state.datasets,
    items: state.datasets.items.map(item => (item.id === payload.id ?
      Object.assign({}, item, { visibility: !item.visibility }) : item))
  }
});

export const setActiveDatasets = (state, { payload }) => ({
  ...state,
  datasets: {
    ...state.datasets,
    activeDatasets: typeof payload === 'string' ? [payload] : payload
  }
});

export const updateActiveDatasets = state => ({
  ...state,
  datasets: {
    ...state.datasets,
    activeDatasets: state.datasets.items.filter(d => d.isLayerActive)
  }
});

export const updateZIndex = (state, { payload }) => {
  const layers = payload.map((l, index) => ({ id: l.dataset, zIndex: index }));
  const { length } = layers;
  const items = state.datasets.items.slice(0).map((item) => {
    const itemFound = find(layers, { id: item.id });
    if (itemFound) {
      const { zIndex } = itemFound;
      return Object.assign({}, item, {
        zIndex,
        layerIndex: calcZIndex(length, zIndex)
      });
    }
    return item;
  });

  return {
    ...state,
    datasets: {
      ...state.datasets,
      items
    }
  };
};

export const updateOpacity = (state, { payload }) => {
  const { id, opacity } = payload;
  const datasets = [...state.datasets.items];

  const items = datasets.map((dataset) => {
    if (dataset.id === id) return { ...dataset, opacity };
    return dataset;
  });

  return {
    ...state,
    datasets: {
      ...state.datasets,
      items
    }
  };
};

export const setMultiActiveLayer = (state, { payload }) => {
  const { temporalResolution, period, scenario, id, layerId } = payload;

  const items = state.datasets.items.map((d) => {
    if (d.id === id && (d.provider === 'nexgddp' || d.provider === 'loca')) {
      const currentLayer = d.metadata[0].info[d.provider].layers.find(l =>
        l.temp_resolution === temporalResolution.value &&
        l.scenario === scenario.value
      );

      if (!currentLayer) {
        console.error('There is no layer with the params selected. Check that metadata has all the possibilities');
        return d;
      }

      d.layer = [{
        ...d.layer[0],
        ...currentLayer,
        opacity: d.opacity,
        visibility: d.visibility,
        layerIndex: d.layerIndex,
        dataset: id,
        id: currentLayer.layerId,
        isActive: true,
        period
      }];
    }

    if (d.id === id && (d.provider !== 'nexgddp' && d.provider !== 'loca')) {
      d.layer = d.layer.map(l => ({
        ...l,
        isActive: l.id === layerId
      }));
    }

    return d;
  });

  return {
    ...state,
    datasets: {
      ...state.datasets,
      items
    }
  };
};
<|endoftext|>


<commit_before>(function () {
  'use strict';

  angular.module('RkyApp.controllers')
    .controller('selectRky', ['$scope','$http', 'partage', function($scope,$http,partage){
      var url = "/api/v1/list/scale";

      $scope.title = "selectRky";
      $scope.data = {};
      $http.get(url).
        then(function(response) {
          $scope.data =  {
          model: null,
          availableOptions: response.data
          }
          $scope.data.model = $scope.data.availableOptions[3];
        });

      function updateCapteur() {
        partage.capteur = $scope.data.model.scale;
        console.log('update: ' + partage.capteur);
      };

      $scope.$watchCollection('data.model.scale',  updateCapteur);

}])

    .service('partage', function() {
      var Data = {
        capteur: '',
        dateFrom: '',
        dateTo: ''
      };
      return Data;
    })
//xx  } ());

// --------
// recuperation des valeur depuis MongoDB
//xx(function () {
//xx  'use strict';

//xx  angular.module('RkyApp.controllers')
    .controller('httpRky', ['$scope', '$http','$filter' ,'partage', function($scope, $http, $filter, partage) {
      $scope.title = "httpRky ... in progress";
      $scope.partage = partage;
      console.log('httpRky: ' + $scope.partage.model);
      $scope.after = "2016/11/17";
      $scope.before = "2016/11/18";
      $scope.moyenne = 0.0;
      $scope.somme = 0.0;
      $scope.nb = 0;
      var urlBase ="/api/v1/search?name=Rky_P&source=*";
      var url = urlBase + $scope.date;
      var data = [];

      function getData () {
        $http.get(url)
        .then(function(response){
        angular.forEach(response.data,function(value){
          data.push({ date: value.date, heure: value.heure, value: value.value });
          $scope.somme += parseFloat(value.value);
          $scope.nb += 1;
          $scope.moyenne = ($scope.somme / $scope.nb).toFixed(2);
         });
        });
      }

      function calculMoyenne() {
        $scope.moyenne = $scope.somme / $scope.nb;
        console.log($scope.somme,$scope.nb,$scope.moyenne);
      }

      $scope.d3Data = data;

      function updateData() {
        urlBase = "/api/v1/search?name="+partage.capteur+"&source=*";
        url = urlBase +"&after="+ $scope.after+"&before=" +$scope.before;
          data.length = 0;
          $scope.nb=0;
          $scope.somme=0.0;
          $scope.moyenne = "waiting for data";
          console.log(url);
          getData();
      }

      $scope.clickButton = function() {
        var now = new Date();
        var demain = now;
        demain.setDate(now.getDate() + 1);
        console.log(demain);
        $scope.jour = $filter('date')(now,"yyyy/MM/dd");
        console.log('date :',$scope.jour);
          updateData();
        }

      $scope.$watch(data,calculMoyenne);

      $scope.$watchCollection('partage.capteur',updateData);
      $scope.$watch('after',updateData);
      $scope.$watch('before',updateData);

  }]);

 }());<commit_msg>et la ;<commit_after>(function () {
  'use strict';

  angular.module('RkyApp.controllers')
    .controller('selectRky', ['$scope','$http', 'partage', function($scope,$http,partage){
      var url = "/api/v1/list/scale";

      $scope.title = "selectRky";
      $scope.data = {};
      $http.get(url).
        then(function(response) {
          $scope.data =  {
          model: null,
          availableOptions: response.data
          }
          $scope.data.model = $scope.data.availableOptions[3];
        });

      function updateCapteur() {
        partage.capteur = $scope.data.model.scale;
        console.log('update: ' + partage.capteur);
      };

      $scope.$watchCollection('data.model.scale',  updateCapteur);

}])

    .service('partage', function() {
      var Data = {
        capteur: '',
        dateFrom: '',
        dateTo: ''
      };
      return Data;
    })
//xx  } ());

// --------
// recuperation des valeur depuis MongoDB
//xx(function () {
//xx  'use strict';

//xx  angular.module('RkyApp.controllers')
    .controller('httpRky', ['$scope', '$http','$filter' ,'partage', function($scope, $http, $filter, partage) {
      $scope.title = "httpRky ... in progress";
      $scope.partage = partage;
      console.log('httpRky: ' + $scope.partage.model);
      $scope.after = "2016/11/17";
      $scope.before = "2016/11/18";
      $scope.moyenne = 0.0;
      $scope.somme = 0.0;
      $scope.nb = 0;
      var urlBase ="/api/v1/search?name=Rky_P&source=*";
      var url = urlBase + $scope.date;
      var data = [];

      function getData () {
        $http.get(url)
        .then(function(response){
        angular.forEach(response.data,function(value){
          data.push({ date: value.date, heure: value.heure, value: value.value });
          $scope.somme += parseFloat(value.value);
          $scope.nb += 1;
          $scope.moyenne = ($scope.somme / $scope.nb).toFixed(2);
         });
        });
      }

      function calculMoyenne() {
        $scope.moyenne = $scope.somme / $scope.nb;
        console.log($scope.somme,$scope.nb,$scope.moyenne);
      }

      $scope.d3Data = data;

      function updateData() {
        urlBase = "/api/v1/search?name="+partage.capteur+"&source=*";
        url = urlBase +"&after="+ $scope.after+"&before=" +$scope.before;
          data.length = 0;
          $scope.nb=0;
          $scope.somme=0.0;
          $scope.moyenne = "waiting for data";
          console.log(url);
          getData();
      }

      $scope.clickButton = function() {
        var now = new Date();
        var demain = new Date();
        demain.setDate(demain.getDate() + 1);
        console.log(demain);
        $scope.jour = $filter('date')(now,"yyyy/MM/dd");
        console.log('date :',$scope.jour);
          updateData();
        }

      $scope.$watch(data,calculMoyenne);

      $scope.$watchCollection('partage.capteur',updateData);
      $scope.$watch('after',updateData);
      $scope.$watch('before',updateData);

  }]);

 }());<|endoftext|>


<commit_before>(function () {
  'use strict';

  angular.module('RkyApp.controllers')
    .controller('selectRky', ['$scope','$http', 'partage', function($scope,$http,partage){
      var url = "/api/v1/list/scale";

      $scope.title = "selectRky";
      $scope.data = {};
      $http.get(url).
        then(function(response) {
          $scope.data =  {
          model: null,
          availableOptions: response.data
          }
          $scope.data.model = $scope.data.availableOptions[3];
        });

      function updateCapteur() {
        partage.capteur = $scope.data.model.scale;
        console.log('update: ' + partage.capteur);
      };

      $scope.$watchCollection('data.model.scale',  updateCapteur);

}])

    .service('partage', function() {
      var Data = {
        capteur: '',
        dateFrom: '',
        dateTo: ''
      };
      return Data;
    })
//xx  } ());

// --------
// recuperation des valeur depuis MongoDB
//xx(function () {
//xx  'use strict';

//xx  angular.module('RkyApp.controllers')
    .controller('httpRky', ['$scope', '$http','$filter' ,'partage', function($scope, $http, $filter, partage) {
      $scope.title = "httpRky ... in progress";
      $scope.partage = partage;
      console.log('httpRky: ' + $scope.partage.model);
      $scope.after = "2016/11/17";
      $scope.before = "2016/11/18";
      $scope.moyenne = 0.0;
      $scope.somme = 0.0;
      $scope.nb = 0;
      var urlBase ="/api/v1/search?name=Rky_P&source=*";
      var url = urlBase + $scope.date;
      var data = [];

      function getData () {
        $http.get(url)
        .then(function(response){
        angular.forEach(response.data,function(value){
          data.push({ date: value.date, heure: value.heure, value: value.value });
          $scope.somme += parseFloat(value.value);
          $scope.nb += 1;
          $scope.moyenne = ($scope.somme / $scope.nb).toFixed(2);
         });
        });
      }

      function calculMoyenne() {
        $scope.moyenne = $scope.somme / $scope.nb;
        console.log($scope.somme,$scope.nb,$scope.moyenne);
      }

      $scope.d3Data = data;

      function updateData() {
        urlBase = "/api/v1/search?name="+partage.capteur+"&source=*";
        url = urlBase +"&after="+ $scope.after+"&before=" +$scope.before;
          data.length = 0;
          $scope.nb=0;
          $scope.somme=0.0;
          $scope.moyenne = "waiting for data";
          console.log(url);
          getData();
      }

      $scope.clickButton = function() {
        $scope.jour = $filter('date')(new Date(),"yyyy/MM/dd");
        console.log('date :',$scope.jour);
          updateData();
        }

      $scope.$watch(data,calculMoyenne);

      $scope.$watchCollection('partage.capteur',updateData);
      $scope.$watch('after',updateData);
      $scope.$watch('before',updateData);

  }]);

 }());<commit_msg>date +<commit_after>(function () {
  'use strict';

  angular.module('RkyApp.controllers')
    .controller('selectRky', ['$scope','$http', 'partage', function($scope,$http,partage){
      var url = "/api/v1/list/scale";

      $scope.title = "selectRky";
      $scope.data = {};
      $http.get(url).
        then(function(response) {
          $scope.data =  {
          model: null,
          availableOptions: response.data
          }
          $scope.data.model = $scope.data.availableOptions[3];
        });

      function updateCapteur() {
        partage.capteur = $scope.data.model.scale;
        console.log('update: ' + partage.capteur);
      };

      $scope.$watchCollection('data.model.scale',  updateCapteur);

}])

    .service('partage', function() {
      var Data = {
        capteur: '',
        dateFrom: '',
        dateTo: ''
      };
      return Data;
    })
//xx  } ());

// --------
// recuperation des valeur depuis MongoDB
//xx(function () {
//xx  'use strict';

//xx  angular.module('RkyApp.controllers')
    .controller('httpRky', ['$scope', '$http','$filter' ,'partage', function($scope, $http, $filter, partage) {
      $scope.title = "httpRky ... in progress";
      $scope.partage = partage;
      console.log('httpRky: ' + $scope.partage.model);
      $scope.after = "2016/11/17";
      $scope.before = "2016/11/18";
      $scope.moyenne = 0.0;
      $scope.somme = 0.0;
      $scope.nb = 0;
      var urlBase ="/api/v1/search?name=Rky_P&source=*";
      var url = urlBase + $scope.date;
      var data = [];

      function getData () {
        $http.get(url)
        .then(function(response){
        angular.forEach(response.data,function(value){
          data.push({ date: value.date, heure: value.heure, value: value.value });
          $scope.somme += parseFloat(value.value);
          $scope.nb += 1;
          $scope.moyenne = ($scope.somme / $scope.nb).toFixed(2);
         });
        });
      }

      function calculMoyenne() {
        $scope.moyenne = $scope.somme / $scope.nb;
        console.log($scope.somme,$scope.nb,$scope.moyenne);
      }

      $scope.d3Data = data;

      function updateData() {
        urlBase = "/api/v1/search?name="+partage.capteur+"&source=*";
        url = urlBase +"&after="+ $scope.after+"&before=" +$scope.before;
          data.length = 0;
          $scope.nb=0;
          $scope.somme=0.0;
          $scope.moyenne = "waiting for data";
          console.log(url);
          getData();
      }

      $scope.clickButton = function() {
        var now = new Date();
        var demain = now + 1;
        console.log(demain);
        $scope.jour = $filter('date')(now,"yyyy/MM/dd");
        console.log('date :',$scope.jour);
          updateData();
        }

      $scope.$watch(data,calculMoyenne);

      $scope.$watchCollection('partage.capteur',updateData);
      $scope.$watch('after',updateData);
      $scope.$watch('before',updateData);

  }]);

 }());<|endoftext|>


<commit_before>/*:
 * Imported.RS_MultipleViewports.js
 * @plugindesc This plugin provides Multiple Viewport (WebGL only)
 * @author biud436
 */

var Imported = Imported || {};
Imported.RS_MultipleViewports = true;

(function () {

  if(PIXI.VERSION !== 'v2.2.9') return false;

  /**
   * Renders the stage to its webGL view
   *
   * @method render
   * @param stage {Stage} the Stage element to be rendered
   */
  PIXI.WebGLRenderer.prototype.render = function(stage)
  {
      // no point rendering if our context has been blown up!
      if(this.contextLost)return;

      // if rendering a new stage clear the batches..
      if(this.__stage !== stage)
      {
          if(stage.interactive)stage.interactionManager.removeEvents();

          // TODO make this work
          // dont think this is needed any more?
          this.__stage = stage;
      }

      // update the scene graph
      stage.updateTransform();

      var gl = this.gl;

      // interaction
      if(stage._interactive)
      {
          //need to add some events!
          if(!stage._interactiveEventsAdded)
          {
              stage._interactiveEventsAdded = true;
              stage.interactionManager.setTarget(this);
          }
      }
      else
      {
          if(stage._interactiveEventsAdded)
          {
              stage._interactiveEventsAdded = false;
              stage.interactionManager.setTarget(this);
          }
      }

      // make sure we are bound to the main frame buffer
      gl.bindFramebuffer(gl.FRAMEBUFFER, null);

      if (this.clearBeforeRender)
          {
          if(this.transparent)
          {
              gl.clearColor(0, 0, 0, 0);
          }
          else
          {
              gl.clearColor(stage.backgroundColorSplit[0],stage.backgroundColorSplit[1],stage.backgroundColorSplit[2], 1);
          }

          gl.clear (gl.COLOR_BUFFER_BIT);
      }

      gl.viewport(0, 0, this.width / 2, this.height / 2);
      this.lastRender(stage);
      gl.viewport(0, this.height / 2, this.width / 2, this.height / 2);
      this.lastRender(stage);
      gl.viewport(this.width / 2, 0, this.width / 2, this.height / 2);
      this.lastRender(stage);
      gl.viewport(this.width / 2, this.height / 2, this.width / 2, this.height / 2);
      this.lastRender(stage);
  };

  PIXI.WebGLRenderer.prototype.lastRender = function(stage) {
    this.renderDisplayObject( stage, this.projection );
  };

})();
<commit_msg>Now RPG Maker MV 1.3.0 or more is supported.<commit_after>/*:
 * Imported.RS_MultipleViewports.js
 * @plugindesc This plugin provides Multiple Viewport (WebGL only)
 * @author biud436
 *
 * @help
 * -----------------------------------------------------------------------------
 * Changle Log
 * -----------------------------------------------------------------------------
 * 2016.06.13 (v1.0.0) - First Release.
 * 2016.08.24 (v1.1.0) - Now RPG Maker MV 1.3.0 or more is supported.
 */

var Imported = Imported || {};
Imported.RS_MultipleViewports = true;

(function () {

  var isFilterPIXI4 = (PIXI.VERSION === "4.0.0" && Utils.RPGMAKER_VERSION >= "1.3.0");
  var isWebGL = PIXI.utils.isWebGLSupported();
  var isUseCanvas = Utils.isOptionValid('canvas');
  if(isUseCanvas) {
    console.error('This plugin does not support in Canvas Mode');
    return;
  }

  Graphics.getRenderPosition = function(width, height) {
    var positionType = [];
    positionType[0] = new Rectangle(0, 0, width / 2, height / 2);
    positionType[1] = new Rectangle(0, height / 2, width / 2, height / 2);
    positionType[2] = new Rectangle(width / 2, 0, width / 2, height / 2);
    positionType[3] = new Rectangle(width / 2, height / 2, width / 2, height / 2);
    return positionType;
  };

  var alias_Graphics__createRenderer = Graphics._createRenderer;
  Graphics._createRenderer = function() {
    alias_Graphics__createRenderer.call(this);
    this._createRenderTexture();
  };

  Graphics._createRenderTexture = function () {
    var sprite; var rect; var self = Graphics;
    if(!self._renderer) { return; }
    var gl = self._renderer.gl;
    self._renderSprite = [];

    // Calculrate Screen
    self._frameWidth = gl.drawingBufferWidth || 816;
    self._frameHeight = gl.drawingBufferHeight || 624;

    // Create RenderTexture
    self._renderTexture = PIXI.RenderTexture.create(self._frameWidth,
                                                    self._frameHeight,
                                                    PIXI.SCALE_MODES.NEAREST);

    // Create Rect
    self._rect = self.getRenderPosition(self._frameWidth, self._frameHeight);

    // Create RenderTarget
    self._renderTarget = new PIXI.RenderTarget(gl, self._frameWidth,
                                                    self._frameHeight,
                                                    PIXI.SCALE_MODES.NEAREST);

    // Create Sprite
    self._renderSprite = new Sprite();

    // Add Child Sprite
    for(var i = 0; i < 4; i++) {
      self._renderSprite.addChild(new Sprite());
    }

  }

  Graphics.setRenderSprite = function (i) {
    this._renderSprite.children[i].x = this._rect[i].x;
    this._renderSprite.children[i].y = this._rect[i].y;
    this._renderSprite.children[i].texture = this._renderTexture;
    this._renderSprite.children[i].scale.x = 0.5;
    this._renderSprite.children[i].scale.y = 0.5;
  };

  Graphics.render = function(stage) {
    if (this._skipCount === 0) {
        var startTime = Date.now();
        if (stage) {
          this._renderer.bindRenderTexture(this._renderTexture);
          this._renderer.render(stage, this._renderTexture);
          this._renderer.bindRenderTarget(this._renderTarget);
          for(var i = 0; i < 4; i++) this.setRenderSprite(i);
          this._renderer.render(this._renderSprite);

        }
        var endTime = Date.now();
        var elapsed = endTime - startTime;
        this._skipCount = Math.min(Math.floor(elapsed / 15), this._maxSkip);
        this._rendered = true;
    } else {
        this._skipCount--;
        this._rendered = false;
    }
    this.frameCount++;
  };

})();
<|endoftext|>


<commit_before>var Texture = {

	maxTextures: 0,
	loadedTextures: 0,
	map: new Array(),
	initTextures: function ()
	{
		Texture.addTexture("desk","assets/img/desk.png");
		Texture.addTexture("barcode","assets/img/barcode.png");
		Texture.addTexture("sky_night","assets/img/sky_night.png");
	},

	addTexture: function(name,source)
	{
		this.maxTextures+=1;

		var img = new Image();

		var capt = this;

		img.onload = function()
		{
			capt.textureLoaded(img, name);
		};

		img.onerror = function()
		{
			console.log("Failed to load texture " + name + " from "+ source);
			capt.textureFailedToLoad(name);
		};

		img.src = source;
	},

	textureLoaded: function(image, name)
	{
		Texture.map[name] = image;
		Texture.loadedTextures++;
	},
	textureFailedToLoad: function(name)
	{
		Texture.map[name] = null;
		Texture.loadedTextures++;
	}

}<commit_msg>Update texture.js<commit_after>var Texture = {

	maxTextures: 0,
	loadedTextures: 0,
	map: new Array(),
	initTextures: function ()
	{
		Texture.addTexture("desk","assets/img/desk.png");
		Texture.addTexture("barcode","assets/img/barcode.png");
		Texture.addTexture("sky_day","assets/img/sky_day.png");
	},

	addTexture: function(name,source)
	{
		this.maxTextures+=1;

		var img = new Image();

		var capt = this;

		img.onload = function()
		{
			capt.textureLoaded(img, name);
		};

		img.onerror = function()
		{
			console.log("Failed to load texture " + name + " from "+ source);
			capt.textureFailedToLoad(name);
		};

		img.src = source;
	},

	textureLoaded: function(image, name)
	{
		Texture.map[name] = image;
		Texture.loadedTextures++;
	},
	textureFailedToLoad: function(name)
	{
		Texture.map[name] = null;
		Texture.loadedTextures++;
	}

}
<|endoftext|>


<commit_before>CT.log = function(msg, level) {
	if (CT.log._silent)
		return;
	msg = CT.log._fix(msg);
	for (var i = 0; i < CT.log.grep._ins.length; i++)
		if (msg.indexOf(CT.log.grep._ins[i]) == -1)
			return;
	for (var i = 0; i < CT.log.grep._outs.length; i++)
		if (msg.indexOf(CT.log.grep._outs[i]) != -1)
			return;
	var s = Date() + " ::";
	if (level) for (var i = 0; i < level; i++)
		s += "  ";
	console.log(s, msg);
};

CT.log.grep = function(ins, outs) {
	CT.log.grep._ins = ins || [];
	CT.log.grep._outs = outs || [];
};
CT.log.grep._ins = [];
CT.log.grep._outs = [];

CT.log._fix = function(a) {
	return (typeof(a) == "object") ? JSON.stringify(a) : a;
}
CT.log.set = function(bool) {
	CT.log._silent = bool;
};
CT.log.getLogger = function(component) {
	var logger = function() {
		var str_arr = [];
		for (var i = 0; i < logger.arguments.length; i++)
			str_arr.push(CT.log._fix(logger.arguments[i]));
		CT.log("[" + component + "] " + str_arr.join(" "));
	};
	return logger;
};<commit_msg>CT.log._silent assignment in CT.log (for compiler)<commit_after>CT.log = function(msg, level) {
	if (CT.log._silent)
		return;
	msg = CT.log._fix(msg);
	for (var i = 0; i < CT.log.grep._ins.length; i++)
		if (msg.indexOf(CT.log.grep._ins[i]) == -1)
			return;
	for (var i = 0; i < CT.log.grep._outs.length; i++)
		if (msg.indexOf(CT.log.grep._outs[i]) != -1)
			return;
	var s = Date() + " ::";
	if (level) for (var i = 0; i < level; i++)
		s += "  ";
	console.log(s, msg);
};

CT.log._silent = false;
CT.log.grep._ins = [];
CT.log.grep._outs = [];
CT.log.grep = function(ins, outs) {
	CT.log.grep._ins = ins || [];
	CT.log.grep._outs = outs || [];
};
CT.log._fix = function(a) {
	return (typeof(a) == "object") ? JSON.stringify(a) : a;
}
CT.log.set = function(bool) {
	CT.log._silent = bool;
};
CT.log.getLogger = function(component) {
	var logger = function() {
		var str_arr = [];
		for (var i = 0; i < logger.arguments.length; i++)
			str_arr.push(CT.log._fix(logger.arguments[i]));
		CT.log("[" + component + "] " + str_arr.join(" "));
	};
	return logger;
};<|endoftext|>


<commit_before>const { format } = require('path');
const { runCLI } = require('jest-cli');

const src = 'src/**/*.js';
const dist = 'lib';

export async function clean(fly) {
    await fly.clear(dist);
}

export async function build(fly, opts) {
    await fly.source(opts.src || src).unflow().target(dist);
}

export async function lint(fly) {
    await fly.source(src).prettier({
        tabWidth: 4,
        parser: 'flow',
        singleQuote: true,
        trailingComma: 'es5',
        printWidth: 90
    }).target('src');
}

export async function test(fly) {
    await fly.source('__tests__/*.js').jest({ collectCoverage:true });
}

export async function watch(fly) {
    await fly.watch(src, ['build', 'test']);
}
<commit_msg>rerun tests when test or mock files change<commit_after>const tests = '__tests__/*.js';
const mocks = '__mocks__/*.js';
const src = 'src/**/*.js';
const dist = 'lib';

export async function clean(fly) {
    await fly.clear(dist);
}

export async function build(fly, opts) {
    await fly.source(opts.src || src).unflow().target(dist);
}

export async function lint(fly) {
    await fly.source(src).prettier({
        tabWidth: 4,
        parser: 'flow',
        singleQuote: true,
        trailingComma: 'es5',
        printWidth: 90
    }).target('src');
}

export async function test(fly) {
    await fly.source(tests).jest({ collectCoverage:true });
}

export async function watch(fly) {
    await fly.watch(src, ['build', 'test']);
    await fly.watch([tests, mocks], 'test');
}
<|endoftext|>