<commit_before>// Copyright (C) 2016 Allegorithmic
//
// This software may be modified and distributed under the terms
// of the MIT license.  See the LICENSE file for details.

function PhotoshopExporter() {
  //Padding's struct
  this.mapInfo = {}
  if (!alg.settings.value("padding", false)) {
    this.mapInfo = {padding: "Transparent", dilation: 0};
  }
  this.mapInfo.bitDepth = alg.settings.value("bitDepth", 8);

  //Get the project name
  var projectName = alg.project.url().split('/');
  projectName = projectName[projectName.length - 1].replace(".spp", "");

  //The export path is the working directory
  this.exportPath = alg.mapexport.exportPath() + "/" + projectName + "_photoshop_export/";

  //Add the header photoshop script
  var headerScript = alg.fileIO.open(alg.plugin_root_directory + "/header.jsx", 'r');
  this.photoshopScript = headerScript.readAll();
  headerScript.close();

  //Run the script
  this.run(this);

  //Add the footer photoshop script
  var footerScript = alg.fileIO.open(alg.plugin_root_directory + "/footer.jsx", 'r');
  this.photoshopScript += footerScript.readAll();
  footerScript.close();

  try{
    var scriptFile = alg.fileIO.open(this.exportPath + "/photoshopScript.jsx", 'w');
    scriptFile.write(this.photoshopScript);
    scriptFile.close();
  } catch (error) {
    alg.log.error(error.message);
    return;
  }

  alg.log.warn(" Export done");
  if (alg.settings.value("launchPhotoshop", false)) {
    alg.log.warn(" Starting Photoshop...");
    if (Qt.platform.os == "windows") {
      alg.subprocess.startDetached(["\"" + alg.settings.value("photoshopPath", "") + "\"", "\"" + this.exportPath.split('/').join('\\') + "photoshopScript.jsx\""]);
    } else if (Qt.platform.os == "osx") {
      alg.subprocess.startDetached(["open", "-a", alg.settings.value("photoshopPath", "").split(' ').join('\ '), this.exportPath.split(' ').join('\ ') + "photoshopScript.jsx"]);
    }
  }
}

PhotoshopExporter.prototype = {

  /*
  * Main function of the script
  * Browsing of all layers into the document structure
  */
  run: function() {
    var doc_str = alg.mapexport.documentStructure();
    //Browse material
    for (var materialId = 0; materialId < doc_str.materials.length; materialId++) {
      var material = doc_str.materials[materialId];
      this.materialName = material.name;
      //Update the progress bar
      this.photoshopScript += "progressBar.material.value = " + 100/doc_str.materials.length*(materialId+1) + ";\n";
      //Browse stacks
      for (var stackId = 0; stackId < material.stacks.length; ++stackId) {
        var stack = material.stacks[stackId];
        this.stackName = stack.name;
        //Browse channels
        for (var channelId = 0; channelId < stack.channels.length; ++channelId) {
          this.channel = stack.channels[channelId];
          //Update the progress bar
          this.photoshopScript += "progressBar.channel.value = " + 100/stack.channels.length*(channelId+1) + ";\n";
          //PNG export of a channel snapshot into the path export
          var filename = this.createFilename(".png");
          alg.mapexport.save([this.materialName, this.stackName, this.channel], filename, this.mapInfo);
          //Create a new document into photoshop
          this.photoshopScript += this.newPSDDocumentStr(filename);
          alg.log.warn(" " + "Export the channel " + this.channel + " of the material " + this.materialName);
          //Browse layers roots forest
          for (var layerId = 0; layerId < stack.layers.length; ++layerId) {
            var layer = stack.layers[layerId];
            //Update the progress bar
            this.photoshopScript += "progressBar.layer.value = " + 100/stack.layers.length*(layerId+1) + ";\n";
            //Browse layer tree from root
            this.layersDFS(layer, this);
          }
          //Rasterize all layers
          this.photoshopScript += "app.activeDocument.rasterizeAllLayers(); \n";
          //Update the progress bar
          this.photoshopScript += "progressBar.layer.value = 0; \n";
          //Gamma correction for sRGB channel
          if(this.channel == "basecolor" || this.channel == "diffuse" || this.channel == "specular" || this.channel == "emissive" || this.channel == "transmissive" ) {
            this.photoshopScript += " convert_to_profile(); \n";
          }
          //Move the snapshot to the document head
          this.photoshopScript += "snapshot.move(app.activeDocument.activeLayer, ElementPlacement.PLACEBEFORE); \n";
          //Hide the snapshot
          this.photoshopScript += "snapshot.visible = false; \n";
        }
        //Update the progress bar
        this.photoshopScript += "progressBar.channel.value = 0; \n";
      }
    }
  },

  /*
   * Recursive function to explore a hierarchy of layers
   * Leaf has exported as photoshop layer
   * Folder has exported as photoshop groupe
   */
  layersDFS: function(layer) {
    //The layer is a leaf
    if (layer.layers == undefined) {
      //PNG export of the leaf into the path export
      var filename = this.createFilename(layer.uid + ".png");
      alg.mapexport.save([layer.uid, this.channel], filename, this.mapInfo);
      //Create the layer into photoshop
      this.photoshopScript += this.newLayerStr(filename, layer, this.channel);
      //Add his mask if exist
      if (layer.hasMask == true) {
        this.addMask(layer, this);
      }
    }
    //The layer is a folder
    else {
      //Create the folder into photoshop
      this.photoshopScript += this.newFolderStr(layer, this.channel);
      //Add his mask if exist
      if (layer.hasMask == true) {
        this.addMask(layer, this);
      }
      //Browse layer tree from the current layer
      for (var layerId = 0; layerId < layer.layers.length; ++layerId) {
        this.layersDFS(layer.layers[layerId], this);
      }
      //Pull folder up
      this.photoshopScript += " app.activeDocument.activeLayer = folders.pop();\n";
    }
  },

  /*
   * Add the layer/folder mask if exist
   */
  addMask: function(layer) {
    //PNG export of the mask into the path export
    var filename = this.createFilename(layer.uid + "_mask.png");
    alg.mapexport.save([layer.uid, "mask"], filename, this.mapInfo);
    //Create the mask into photoshop
    this.photoshopScript += this.newMaskStr(filename);
  },

  /**********Photoshop generation script**********/

  createFilename: function(concate) {
    return this.exportPath + this.materialName + "_" +this.stackName + "_" + this.channel + "_" + concate;
  },

  /*
   * Return the string to open a new photoshop document
   */
  newPSDDocumentStr: function(filename) {
    return "\n\n//New Document \n\
   var exportFile = File(\"" + filename + "\"); \n\
   open(exportFile); \n\
   exportFile.remove();
   var folders = []; \n\
   folders.push(app.activeDocument); \n\
   var snapshot = app.activeDocument.activeLayer; \n\
   snapshot.name = \"snapshot\"; ";
  },

  /*
   * Return the string to assign a mask to a photoshop layer
   */
  newMaskStr: function(filename) {
    return " //Add mask \n\
   var maskFile = File(\"" + filename + "\"); \n\
   open_png(maskFile); \n\
   maskFile.remove(); \n\
   layerToMask();";
  },

  /*
   * Return the string to create a new photoshop folder
   */
  newFolderStr: function(folder, channel) {
    var blending = alg.mapexport.layerBlendingModes(folder.uid)[channel];
    return "\n\n //Add folder \n\
   folders.push(folders[folders.length - 1].layerSets.add()); \n\
   app.activeDocument.activeLayer.opacity = " + blending.opacity + ";\n\
   " + this.convertBlendingMode(blending.mode, 1) + "; \n\
   app.activeDocument.activeLayer.name = \"" + folder.name + "\"; ";
  },

  /*
   * Return the string to create a new photoshop layer
   */
  newLayerStr: function(filename, layer, channel) {
    var blending = alg.mapexport.layerBlendingModes(layer.uid)[channel];
    return "\n\n //Add layer \n\
   folders[folders.length - 1].artLayers.add(); \n\
   var layerFile = File(\"" + filename + "\"); \n\
   open_png(layerFile); \n\
   layerFile.remove(); \n\
   app.activeDocument.activeLayer.opacity = " + blending.opacity + ";\n\
   " + this.convertBlendingMode(blending.mode, 0) + ";\n\
   app.activeDocument.activeLayer.name = \"" + layer.name + "\"; ";
  },

  /*
   * Return the string to assign a blending mode to the current photoshop layer/folder
   * Folder in Passthrough mode have to be assign to PASSTHROUGH but layer
   */
  convertBlendingMode: function(painterMode, isFolder) {
    var blendingMode = "app.activeDocument.activeLayer.blendMode = BlendMode.";
    if (painterMode == "Passthrough") {
      if (isFolder == 1) {
        blendingMode = blendingMode + "PASSTHROUGH";
      } else {
        blendingMode = blendingMode + "NORMAL";
      }
      return blendingMode;
    }
    switch(painterMode) {
    case "Normal":
    case "Replace":                      blendingMode = blendingMode + "NORMAL";
      break;
    case "Multiply":                     blendingMode = blendingMode + "MULTIPLY"; break;
    case "Divide":                       blendingMode = blendingMode + "DIVIDE"; break;
    case "Linear dodge (Add)":           blendingMode = blendingMode + "LINEARDODGE"; break;
    case "Subtract":                     blendingMode = blendingMode + "SUBTRACT"; break;
    case "Difference":                   blendingMode = blendingMode + "DIFFERENCE"; break;
    case "Exclusion":                    blendingMode = blendingMode + "EXCLUSION"; break;
    case "Overlay":                      blendingMode = blendingMode + "OVERLAY"; break;
    case "Screen":                       blendingMode = blendingMode + "SCREEN"; break;
    case "Linear burn":                  blendingMode = blendingMode + "LINEARBURN"; break;
    case "Color burn":                   blendingMode = blendingMode + "COLORBURN"; break;
    case "Color dodge":                  blendingMode = blendingMode + "COLORDODGE"; break;
    case "Soft light":                   blendingMode = blendingMode + "SOFTLIGHT"; break;
    case "Hard light":                   blendingMode = blendingMode + "HARDLIGHT"; break;
    case "Vivid light":                  blendingMode = blendingMode + "VIVIDLIGHT"; break;
    case "Pin light":                    blendingMode = blendingMode + "PINLIGHT"; break;
    case "Saturation":                   blendingMode = blendingMode + "SATURATION"; break;
    case "Color":                        blendingMode = blendingMode + "COLORBLEND"; break;
    case "Normal map combine":           blendingMode = "Overlay_Normal()"; break;
    case "Normal map detail":            blendingMode = "Overlay_Normal()"; break;
    case "Normal map inverse detail":    blendingMode = "Overlay_Normal()"; break;
    case "Disable":
    case "Inverse divide":
    case "Darken (Min)":
    case "Lighten (Max)":
    case "Inverse Subtract":
    case "Signed addition (AddSub)":
    case "Tint":
    case "Value":
    default:
      blendingMode = ""
    }
    return blendingMode;
  }

}

function importPainterDocument() {
  new PhotoshopExporter();
}
<commit_msg>Refactor infor logging<commit_after>// Copyright (C) 2016 Allegorithmic
//
// This software may be modified and distributed under the terms
// of the MIT license.  See the LICENSE file for details.

function logUserInfo(str) {
  alg.log.info(""+str+"")
}

function PhotoshopExporter() {
  //Padding's struct
  this.mapInfo = {}
  if (!alg.settings.value("padding", false)) {
    this.mapInfo = {padding: "Transparent", dilation: 0};
  }
  this.mapInfo.bitDepth = alg.settings.value("bitDepth", 8);

  //Get the project name
  var projectName = alg.project.url().split('/');
  projectName = projectName[projectName.length - 1].replace(".spp", "");

  //The export path is the working directory
  this.exportPath = alg.mapexport.exportPath() + "/" + projectName + "_photoshop_export/";

  //Add the header photoshop script
  var headerScript = alg.fileIO.open(alg.plugin_root_directory + "/header.jsx", 'r');
  this.photoshopScript = headerScript.readAll();
  headerScript.close();

  //Run the script
  this.run(this);

  //Add the footer photoshop script
  var footerScript = alg.fileIO.open(alg.plugin_root_directory + "/footer.jsx", 'r');
  this.photoshopScript += footerScript.readAll();
  footerScript.close();

  try{
    var scriptFile = alg.fileIO.open(this.exportPath + "/photoshopScript.jsx", 'w');
    scriptFile.write(this.photoshopScript);
    scriptFile.close();
  } catch (error) {
    alg.log.error(error.message);
    return;
  }

  logUserInfo("Export done");
  if (alg.settings.value("launchPhotoshop", false)) {
    logUserInfo("Starting Photoshop...");
    if (Qt.platform.os == "windows") {
      alg.subprocess.startDetached(["\"" + alg.settings.value("photoshopPath", "") + "\"", "\"" + this.exportPath.split('/').join('\\') + "photoshopScript.jsx\""]);
    } else if (Qt.platform.os == "osx") {
      alg.subprocess.startDetached(["open", "-a", alg.settings.value("photoshopPath", "").split(' ').join('\ '), this.exportPath.split(' ').join('\ ') + "photoshopScript.jsx"]);
    }
  }
}

PhotoshopExporter.prototype = {

  /*
  * Main function of the script
  * Browsing of all layers into the document structure
  */
  run: function() {
    var doc_str = alg.mapexport.documentStructure();
    //Browse material
    for (var materialId = 0; materialId < doc_str.materials.length; materialId++) {
      var material = doc_str.materials[materialId];
      this.materialName = material.name;
      //Update the progress bar
      this.photoshopScript += "progressBar.material.value = " + 100/doc_str.materials.length*(materialId+1) + ";\n";
      //Browse stacks
      for (var stackId = 0; stackId < material.stacks.length; ++stackId) {
        var stack = material.stacks[stackId];
        this.stackName = stack.name;
        //Browse channels
        for (var channelId = 0; channelId < stack.channels.length; ++channelId) {
          this.channel = stack.channels[channelId];
          //Update the progress bar
          this.photoshopScript += "progressBar.channel.value = " + 100/stack.channels.length*(channelId+1) + ";\n";
          //PNG export of a channel snapshot into the path export
          var filename = this.createFilename(".png");
          alg.mapexport.save([this.materialName, this.stackName, this.channel], filename, this.mapInfo);
          //Create a new document into photoshop
          this.photoshopScript += this.newPSDDocumentStr(filename);
          logUserInfo("Export the channel " + this.channel + " of the material " + this.materialName);
          //Browse layers roots forest
          for (var layerId = 0; layerId < stack.layers.length; ++layerId) {
            var layer = stack.layers[layerId];
            //Update the progress bar
            this.photoshopScript += "progressBar.layer.value = " + 100/stack.layers.length*(layerId+1) + ";\n";
            //Browse layer tree from root
            this.layersDFS(layer, this);
          }
          //Rasterize all layers
          this.photoshopScript += "app.activeDocument.rasterizeAllLayers(); \n";
          //Update the progress bar
          this.photoshopScript += "progressBar.layer.value = 0; \n";
          //Gamma correction for sRGB channel
          if(this.channel == "basecolor" || this.channel == "diffuse" || this.channel == "specular" || this.channel == "emissive" || this.channel == "transmissive" ) {
            this.photoshopScript += " convert_to_profile(); \n";
          }
          //Move the snapshot to the document head
          this.photoshopScript += "snapshot.move(app.activeDocument.activeLayer, ElementPlacement.PLACEBEFORE); \n";
          //Hide the snapshot
          this.photoshopScript += "snapshot.visible = false; \n";
        }
        //Update the progress bar
        this.photoshopScript += "progressBar.channel.value = 0; \n";
      }
    }
  },

  /*
   * Recursive function to explore a hierarchy of layers
   * Leaf has exported as photoshop layer
   * Folder has exported as photoshop groupe
   */
  layersDFS: function(layer) {
    //The layer is a leaf
    if (layer.layers == undefined) {
      //PNG export of the leaf into the path export
      var filename = this.createFilename(layer.uid + ".png");
      alg.mapexport.save([layer.uid, this.channel], filename, this.mapInfo);
      //Create the layer into photoshop
      this.photoshopScript += this.newLayerStr(filename, layer, this.channel);
      //Add his mask if exist
      if (layer.hasMask == true) {
        this.addMask(layer, this);
      }
    }
    //The layer is a folder
    else {
      //Create the folder into photoshop
      this.photoshopScript += this.newFolderStr(layer, this.channel);
      //Add his mask if exist
      if (layer.hasMask == true) {
        this.addMask(layer, this);
      }
      //Browse layer tree from the current layer
      for (var layerId = 0; layerId < layer.layers.length; ++layerId) {
        this.layersDFS(layer.layers[layerId], this);
      }
      //Pull folder up
      this.photoshopScript += " app.activeDocument.activeLayer = folders.pop();\n";
    }
  },

  /*
   * Add the layer/folder mask if exist
   */
  addMask: function(layer) {
    //PNG export of the mask into the path export
    var filename = this.createFilename(layer.uid + "_mask.png");
    alg.mapexport.save([layer.uid, "mask"], filename, this.mapInfo);
    //Create the mask into photoshop
    this.photoshopScript += this.newMaskStr(filename);
  },

  /**********Photoshop generation script**********/

  createFilename: function(concate) {
    return this.exportPath + this.materialName + "_" +this.stackName + "_" + this.channel + "_" + concate;
  },

  /*
   * Return the string to open a new photoshop document
   */
  newPSDDocumentStr: function(filename) {
    return "\n\n//New Document \n\
   var exportFile = File(\"" + filename + "\"); \n\
   open(exportFile); \n\
   exportFile.remove();
   var folders = []; \n\
   folders.push(app.activeDocument); \n\
   var snapshot = app.activeDocument.activeLayer; \n\
   snapshot.name = \"snapshot\"; ";
  },

  /*
   * Return the string to assign a mask to a photoshop layer
   */
  newMaskStr: function(filename) {
    return " //Add mask \n\
   var maskFile = File(\"" + filename + "\"); \n\
   open_png(maskFile); \n\
   maskFile.remove(); \n\
   layerToMask();";
  },

  /*
   * Return the string to create a new photoshop folder
   */
  newFolderStr: function(folder, channel) {
    var blending = alg.mapexport.layerBlendingModes(folder.uid)[channel];
    return "\n\n //Add folder \n\
   folders.push(folders[folders.length - 1].layerSets.add()); \n\
   app.activeDocument.activeLayer.opacity = " + blending.opacity + ";\n\
   " + this.convertBlendingMode(blending.mode, 1) + "; \n\
   app.activeDocument.activeLayer.name = \"" + folder.name + "\"; ";
  },

  /*
   * Return the string to create a new photoshop layer
   */
  newLayerStr: function(filename, layer, channel) {
    var blending = alg.mapexport.layerBlendingModes(layer.uid)[channel];
    return "\n\n //Add layer \n\
   folders[folders.length - 1].artLayers.add(); \n\
   var layerFile = File(\"" + filename + "\"); \n\
   open_png(layerFile); \n\
   layerFile.remove(); \n\
   app.activeDocument.activeLayer.opacity = " + blending.opacity + ";\n\
   " + this.convertBlendingMode(blending.mode, 0) + ";\n\
   app.activeDocument.activeLayer.name = \"" + layer.name + "\"; ";
  },

  /*
   * Return the string to assign a blending mode to the current photoshop layer/folder
   * Folder in Passthrough mode have to be assign to PASSTHROUGH but layer
   */
  convertBlendingMode: function(painterMode, isFolder) {
    var blendingMode = "app.activeDocument.activeLayer.blendMode = BlendMode.";
    if (painterMode == "Passthrough") {
      if (isFolder == 1) {
        blendingMode = blendingMode + "PASSTHROUGH";
      } else {
        blendingMode = blendingMode + "NORMAL";
      }
      return blendingMode;
    }
    switch(painterMode) {
    case "Normal":
    case "Replace":                      blendingMode = blendingMode + "NORMAL";
      break;
    case "Multiply":                     blendingMode = blendingMode + "MULTIPLY"; break;
    case "Divide":                       blendingMode = blendingMode + "DIVIDE"; break;
    case "Linear dodge (Add)":           blendingMode = blendingMode + "LINEARDODGE"; break;
    case "Subtract":                     blendingMode = blendingMode + "SUBTRACT"; break;
    case "Difference":                   blendingMode = blendingMode + "DIFFERENCE"; break;
    case "Exclusion":                    blendingMode = blendingMode + "EXCLUSION"; break;
    case "Overlay":                      blendingMode = blendingMode + "OVERLAY"; break;
    case "Screen":                       blendingMode = blendingMode + "SCREEN"; break;
    case "Linear burn":                  blendingMode = blendingMode + "LINEARBURN"; break;
    case "Color burn":                   blendingMode = blendingMode + "COLORBURN"; break;
    case "Color dodge":                  blendingMode = blendingMode + "COLORDODGE"; break;
    case "Soft light":                   blendingMode = blendingMode + "SOFTLIGHT"; break;
    case "Hard light":                   blendingMode = blendingMode + "HARDLIGHT"; break;
    case "Vivid light":                  blendingMode = blendingMode + "VIVIDLIGHT"; break;
    case "Pin light":                    blendingMode = blendingMode + "PINLIGHT"; break;
    case "Saturation":                   blendingMode = blendingMode + "SATURATION"; break;
    case "Color":                        blendingMode = blendingMode + "COLORBLEND"; break;
    case "Normal map combine":           blendingMode = "Overlay_Normal()"; break;
    case "Normal map detail":            blendingMode = "Overlay_Normal()"; break;
    case "Normal map inverse detail":    blendingMode = "Overlay_Normal()"; break;
    case "Disable":
    case "Inverse divide":
    case "Darken (Min)":
    case "Lighten (Max)":
    case "Inverse Subtract":
    case "Signed addition (AddSub)":
    case "Tint":
    case "Value":
    default:
      blendingMode = ""
    }
    return blendingMode;
  }

}

function importPainterDocument() {
  new PhotoshopExporter();
}
<|endoftext|>


<commit_before>import React, { Component } from 'react';
import { Text, Image, View } from 'react-native';
import styles from './styles/GameplayScreenStyle';
import ActorImage from '../components/ActorImage';
import { StackNagivator } from 'react-navigation';

export default class StartingActorsMovies extends Component {
  constructor(props) {
    super(props);
    this.state = {
      isLoading: true,
    }
  }

  componentDidMount() {
    return fetch('http://localhost:3000/games/'+this.props.navigation.state.params.game_id+'/paths', {
      method: 'POST',
      headers: {
        'Accept': 'application/json',
        'Content-Type': 'application/json',
      },
      body: JSON.stringify({
        game_id: this.props.navigation.state.params.game_id,
        traceable_id: this.props.navigation.state.params.traceable_id,
        traceable_type: this.props.navigation.state.params.traceable_type,
      })
    })
    .then((response) => response.json())
    .then((responseJson) => {
      this.setState({
        isLoading: false,
        pathinfo: responseJson,
      })
    })
    .catch((error) => {
      console.error(error)
    })
  }

  render() {
    return (
      <View>
        <Text>Hello</Text>
      </View>
    )
  }
}
<commit_msg>Change ActorImage to ClickableImage<commit_after>import React, { Component } from 'react';
import { Text, Image, View } from 'react-native';
import styles from './styles/GameplayScreenStyle';
import ClickableImage from '../components/ClickableImage';
import { StackNagivator } from 'react-navigation';

export default class GameplayScreen extends Component {
  constructor(props) {
    super(props);
    this.state = {
      isLoading: true,
    }
  }

  componentDidMount() {
    return fetch('http://localhost:3000/games/'+this.props.navigation.state.params.game_id+'/paths', {
      method: 'POST',
      headers: {
        'Accept': 'application/json',
        'Content-Type': 'application/json',
      },
      body: JSON.stringify({
        game_id: this.props.navigation.state.params.game_id,
        traceable_id: this.props.navigation.state.params.traceable_id,
        traceable_type: this.props.navigation.state.params.traceable_type,
      })
    })
    .then((response) => response.json())
    .then((responseJson) => {
      this.setState({
        isLoading: false,
        pathinfo: responseJson,
      })
    })
    .catch((error) => {
      console.error(error)
    })
  }

  render() {
    return (
      <View>
        <Text>Hello</Text>
      </View>
    )
  }
}
<|endoftext|>


<commit_before>/**
 * Activate a state.
 *
 * @public
 * @param {object} The error object.
 * @param {object} The data object.
*/
exports.state = function (data, stream, forceState) {

    if (typeof data !== 'object') {
        data = {name: data};
    }

    if (forceState) {
        data.name = forceState;
    }

    var template = this.templates[data.template || this._config.defaultTemplate];

    // check if state exists
    if (template && this.states[data.name]) {

        // activate state elements
        for (var i = 0, state, selector, element; i < this.states[data.name].length; ++i) {
            state = this.states[data.name][i];
            element = template.elements[data.element || state.element];
            selector = state.sel || data.selector;

            // get dynamic or static selector
            if (!element && !selector) {

                // retrun if no selector is found
                return;
            }

            // auto hide pages before activate a state
            if (template.page && !data.noPaging) {

                // add "hide" class to all pages
                manipulateClasses(
                  (template.to || document).querySelectorAll('.' + template.page),
                  {add: ['hide']}
                );
            }

            // call other states
            if (state.states) {
                for (var s = 0, l = state.states.length; i < l; ++i) {
                    activateState.call(this, err, {name: state.states[i]});
                }
            }

            // manipulate classes
            selector = typeof selector !== 'string' ? selector : (template.to || document).querySelectorAll(selector);
            manipulateClasses(element || selector, state);
        }
    }
};

/**
 * Manipulate css classes (add, rm, toggle).
 *
 * @private
*/
function manipulateClasses (elms, state) {

    if (!(elms instanceof NodeList)) {
      elms = [elms];
    }

    // manipulate classes
    for (var i = 0; i < elms.length; ++i) {

        // remove classes
        state.rm && elms[i].classList.remove.apply(elms[i].classList, state.rm);

        // add classes
        state.add && elms[i].classList.add.apply(elms[i].classList, state.add);

        // toggle classes
        state.toggle && elms[i].classList.toggle.apply(elms[i].classList, state.toggle);
    }
}
<commit_msg>make "state" option work again<commit_after>/**
 * Activate a state.
 *
 * @public
 * @param {object} The error object.
 * @param {object} The data object.
*/
exports.state = function activateState (data, stream, forceState) {

    if (typeof data !== 'object') {
        data = {name: data};
    }

    if (forceState) {
        data.name = forceState;
    }

    var template = this.templates[data.template || this._config.defaultTemplate];

    // check if state exists
    if (template && this.states[data.name]) {

        // activate state elements
        for (var i = 0, state, selector, element; i < this.states[data.name].length; ++i) {
            state = this.states[data.name][i];
            element = template.elements[data.element || state.element];
            selector = state.sel || data.selector;

            // get dynamic or static selector
            if (!element && !selector) {

                // retrun if no selector is found
                return;
            }

            // auto hide pages before activate a state
            if (template.page && !data.noPaging) {

                // add "hide" class to all pages
                manipulateClasses(
                  (template.to || document).querySelectorAll('.' + template.page),
                  {add: ['hide']}
                );
            }

            // call other states
            if (state.states) {
                for (var s = 0, l = state.states.length; i < l; ++i) {
                    activateState.call(this, {name: state.states[i]});
                }
            }

            // manipulate classes
            selector = typeof selector !== 'string' ? selector : (template.to || document).querySelectorAll(selector);
            manipulateClasses(element || selector, state);
        }
    }
};

/**
 * Manipulate css classes (add, rm, toggle).
 *
 * @private
*/
function manipulateClasses (elms, state) {

    if (!(elms instanceof NodeList)) {
      elms = [elms];
    }

    // manipulate classes
    for (var i = 0; i < elms.length; ++i) {

        // remove classes
        state.rm && elms[i].classList.remove.apply(elms[i].classList, state.rm);

        // add classes
        state.add && elms[i].classList.add.apply(elms[i].classList, state.add);

        // toggle classes
        state.toggle && elms[i].classList.toggle.apply(elms[i].classList, state.toggle);
    }
}
<|endoftext|>


<commit_before>/*jshint node:true, laxcomma:true */

var util    = require('util')
  , net    = require('net')
  , config = require('./lib/config')
  , helpers = require('./lib/helpers')
  , fs     = require('fs')
  , events = require('events')
  , logger = require('./lib/logger')
  , set = require('./lib/set')
  , pm = require('./lib/process_metrics')
  , process_mgmt = require('./lib/process_mgmt')
  , mgmt = require('./lib/mgmt_console');

// initialize data structures with defaults for statsd stats
var keyCounter = {};
var counters = {};
var timers = {};
var timer_counters = {};
var gauges = {};
var sets = {};
var counter_rates = {};
var timer_data = {};
var pctThreshold = null;
var flushInterval, keyFlushInt, serverLoaded, mgmtServer;
var startup_time = Math.round(new Date().getTime() / 1000);
var backendEvents = new events.EventEmitter();
var healthStatus = config.healthStatus || 'up';
var old_timestamp = 0;
var timestamp_lag_namespace;
var keyNameSanitize = true;

// Load and init the backend from the backends/ directory.
function loadBackend(config, name) {
  var backendmod = require(name);

  if (config.debug) {
    l.log("Loading backend: " + name, 'DEBUG');
  }

  var ret = backendmod.init(startup_time, config, backendEvents, l);
  if (!ret) {
    l.log("Failed to load backend: " + name);
    process.exit(1);
  }
}

// Load and init the server from the servers/ directory.
// The callback mimics the dgram 'message' event parameters (msg, rinfo)
//   msg: the message received by the server. may contain more than one metric
//   rinfo: contains remote address information and message length
//      (attributes are .address, .port, .family, .size - you're welcome)
function startServer(config, name, callback) {
  var servermod = require(name);

  if (config.debug) {
    l.log("Loading server: " + name, 'DEBUG');
  }

  var ret = servermod.start(config, callback);
  if (!ret) {
    l.log("Failed to load server: " + name);
    process.exit(1);
  }
}

// global for conf
var conf;

// Flush metrics to each backend.
function flushMetrics() {
  var time_stamp = Math.round(new Date().getTime() / 1000);
  if (old_timestamp > 0) {
    gauges[timestamp_lag_namespace] = (time_stamp - old_timestamp - (Number(conf.flushInterval)/1000));
  }
  old_timestamp = time_stamp;

  var metrics_hash = {
    counters: counters,
    gauges: gauges,
    timers: timers,
    timer_counters: timer_counters,
    sets: sets,
    counter_rates: counter_rates,
    timer_data: timer_data,
    pctThreshold: pctThreshold,
    histogram: conf.histogram
  };

  // After all listeners, reset the stats
  backendEvents.once('flush', function clear_metrics(ts, metrics) {
    // TODO: a lot of this should be moved up into an init/constructor so we don't have to do it every
    // single flushInterval....
    // allows us to flag all of these on with a single config but still override them individually
    conf.deleteIdleStats = conf.deleteIdleStats !== undefined ? conf.deleteIdleStats : false;
    if (conf.deleteIdleStats) {
      conf.deleteCounters = conf.deleteCounters !== undefined ? conf.deleteCounters : true;
      conf.deleteTimers = conf.deleteTimers !== undefined ? conf.deleteTimers : true;
      conf.deleteSets = conf.deleteSets !== undefined ? conf.deleteSets : true;
      conf.deleteGauges = conf.deleteGauges !== undefined ? conf.deleteGauges : true;
    }

    // Clear the counters
    conf.deleteCounters = conf.deleteCounters || false;
    for (var counter_key in metrics.counters) {
      if (conf.deleteCounters) {
        if ((counter_key.indexOf("packets_received") != -1) ||
            (counter_key.indexOf("metrics_received") != -1) ||
            (counter_key.indexOf("bad_lines_seen") != -1)) {
          metrics.counters[counter_key] = 0;
        } else {
         delete(metrics.counters[counter_key]);
        }
      } else {
        metrics.counters[counter_key] = 0;
      }
    }

    // Clear the timers
    conf.deleteTimers = conf.deleteTimers || false;
    for (var timer_key in metrics.timers) {
      if (conf.deleteTimers) {
        delete(metrics.timers[timer_key]);
        delete(metrics.timer_counters[timer_key]);
      } else {
        metrics.timers[timer_key] = [];
        metrics.timer_counters[timer_key] = 0;
     }
    }

    // Clear the sets
    conf.deleteSets = conf.deleteSets || false;
    for (var set_key in metrics.sets) {
      if (conf.deleteSets) {
        delete(metrics.sets[set_key]);
      } else {
        metrics.sets[set_key] = new set.Set();
      }
    }

	// normally gauges are not reset.  so if we don't delete them, continue to persist previous value
    conf.deleteGauges = conf.deleteGauges || false;
    if (conf.deleteGauges) {
      for (var gauge_key in metrics.gauges) {
        delete(metrics.gauges[gauge_key]);
      }
    }
  });

  pm.process_metrics(metrics_hash, flushInterval, time_stamp, function emitFlush(metrics) {
      backendEvents.emit('flush', time_stamp, whitelistFlush(metrics));
  });

}

// apply a filter to the metrics that will be flushed to the backend
// to remove metrics and are not included in the configuration: config.whitelistFlush
function whitelistFlush(metrics) {
    if (conf.whitelistFlush) {
        for (var metric in metrics.timer_data) {
            for (var key in metrics.timer_data[metric]) {
                if (conf.whitelistFlush.indexOf(key) < 0) {
                    delete metrics.timer_data[metric][key];
                }
            }
        }
    }
    return metrics;
}

var stats = {
  messages: {
    last_msg_seen: startup_time,
    bad_lines_seen: 0
  }
};

function sanitizeKeyName(key) {
  if (keyNameSanitize) {
    return key.replace(/\s+/g, '_')
              .replace(/\//g, '-')
              .replace(/[^a-zA-Z_\-0-9\.]/g, '');
  } else {
    return key;
  }
}

// Global for the logger
var l;

config.configFile(process.argv[2], function (config) {
  conf = config;

  process_mgmt.init(config);

  l = new logger.Logger(config.log || {});

  // setup config for stats prefix
  var prefixStats = config.prefixStats;
  prefixStats = prefixStats !== undefined ? prefixStats : "statsd";
  //setup the names for the stats stored in counters{}
  bad_lines_seen   = prefixStats + ".bad_lines_seen";
  packets_received = prefixStats + ".packets_received";
  metrics_received = prefixStats + ".metrics_received";
  timestamp_lag_namespace = prefixStats + ".timestamp_lag";

  //now set to zero so we can increment them
  counters[bad_lines_seen]   = 0;
  counters[packets_received] = 0;
  counters[metrics_received] = 0;

  if (config.keyNameSanitize !== undefined) {
    keyNameSanitize = config.keyNameSanitize;
  }
    if (!serverLoaded) {
    // key counting
    var keyFlushInterval = Number((config.keyFlush && config.keyFlush.interval) || 0);

    // The default server is UDP
    var server = config.server || './servers/udp'
    serverLoaded = startServer(config, server, function (msg, rinfo) {
      backendEvents.emit('packet', msg, rinfo);
      counters[packets_received]++;
      var packet_data = msg.toString();
      if (packet_data.indexOf("\n") > -1) {
        var metrics = packet_data.split("\n");
      } else {
        var metrics = [ packet_data ] ;
      }

      for (var midx in metrics) {
        if (metrics[midx].length === 0) {
          continue;
        }

        counters[metrics_received]++;
        if (config.dumpMessages) {
          l.log(metrics[midx].toString());
        }
        var bits = metrics[midx].toString().split(':');
        var key = sanitizeKeyName(bits.shift());

        if (keyFlushInterval > 0) {
          if (! keyCounter[key]) {
            keyCounter[key] = 0;
          }
          keyCounter[key] += 1;
        }

        if (bits.length === 0) {
          bits.push("1");
        }

        for (var i = 0; i < bits.length; i++) {
          var sampleRate = 1;
          var fields = bits[i].split("|");
          if (!helpers.is_valid_packet(fields)) {
              l.log('Bad line: ' + fields + ' in msg "' + metrics[midx] +'"');
              counters[bad_lines_seen]++;
              stats.messages.bad_lines_seen++;
              continue;
          }
          if (fields[2]) {
            sampleRate = Number(fields[2].match(/^@([\d\.]+)/)[1]);
          }

          var metric_type = fields[1].trim();
          if (metric_type === "ms") {
            if (! timers[key]) {
              timers[key] = [];
              timer_counters[key] = 0;
            }
            timers[key].push(Number(fields[0] || 0));
            timer_counters[key] += (1 / sampleRate);
          } else if (metric_type === "g") {
            if (gauges[key] && fields[0].match(/^[-+]/)) {
              gauges[key] += Number(fields[0] || 0);
            } else {
              gauges[key] = Number(fields[0] || 0);
            }
          } else if (metric_type === "s") {
            if (! sets[key]) {
              sets[key] = new set.Set();
            }
            sets[key].insert(fields[0] || '0');
          } else {
            if (! counters[key]) {
              counters[key] = 0;
            }
            counters[key] += Number(fields[0] || 1) * (1 / sampleRate);
          }
        }
      }

      stats.messages.last_msg_seen = Math.round(new Date().getTime() / 1000);
    });

    mgmtServer = net.createServer(function(stream) {
      stream.setEncoding('ascii');

      stream.on('error', function(err) {
        l.log('Caught ' + err +', Moving on');
      });

      stream.on('data', function(data) {
        var cmdline = data.trim().split(" ");
        var cmd = cmdline.shift();

        switch(cmd) {
          case "help":
            stream.write("Commands: stats, counters, timers, gauges, delcounters, deltimers, delgauges, health, config, quit\n\n");
            break;

          case "config":
            stream.write("\n");
            for (var prop in config) {
              if (!config.hasOwnProperty(prop)) {
                continue;
              }
              if (typeof config[prop] !== 'object') {
                stream.write(prop + ": " + config[prop] + "\n");
                continue;
              }
              subconfig = config[prop];
              for (var subprop in subconfig) {
                if (!subconfig.hasOwnProperty(subprop)) {
                  continue;
                }
                stream.write(prop + " > " + subprop + ": " + subconfig[subprop] + "\n");
              }
            }
            break;

          case "health":
            if (cmdline.length > 0) {
              var cmdaction = cmdline[0].toLowerCase();
              if (cmdaction === 'up') {
                healthStatus = 'up';
              } else if (cmdaction === 'down') {
                healthStatus = 'down';
              }
            }
            stream.write("health: " + healthStatus + "\n");
            break;

          case "stats":
            var now    = Math.round(new Date().getTime() / 1000);
            var uptime = now - startup_time;

            stream.write("uptime: " + uptime + "\n");

            var stat_writer = function(group, metric, val) {
              var delta;

              if (metric.match("^last_")) {
                delta = now - val;
              }
              else {
                delta = val;
              }

              stream.write(group + "." + metric + ": " + delta + "\n");
            };

            // Loop through the base stats
            for (var group in stats) {
              for (var metric in stats[group]) {
                stat_writer(group, metric, stats[group][metric]);
              }
            }

            backendEvents.once('status', function(writeCb) {
              stream.write("END\n\n");
            });

            // Let each backend contribute its status
            backendEvents.emit('status', function(err, name, stat, val) {
              if (err) {
                l.log("Failed to read stats for backend " +
                        name + ": " + err);
              } else {
                stat_writer(name, stat, val);
              }
            });

            break;

          case "counters":
            stream.write(util.inspect(counters) + "\n");
            stream.write("END\n\n");
            break;

          case "timers":
            stream.write(util.inspect(timers) + "\n");
            stream.write("END\n\n");
            break;

          case "gauges":
            stream.write(util.inspect(gauges) + "\n");
            stream.write("END\n\n");
            break;

          case "delcounters":
            mgmt.delete_stats(counters, cmdline, stream);
            break;

          case "deltimers":
            mgmt.delete_stats(timers, cmdline, stream);
            break;

          case "delgauges":
            mgmt.delete_stats(gauges, cmdline, stream);
            break;

          case "quit":
            stream.end();
            break;

          default:
            stream.write("ERROR\n");
            break;
        }

      });
    });

    mgmtServer.listen(config.mgmt_port || 8126, config.mgmt_address || undefined);

    util.log("server is up");

    pctThreshold = config.percentThreshold || 90;
    if (!Array.isArray(pctThreshold)) {
      pctThreshold = [ pctThreshold ]; // listify percentiles so single values work the same
    }

    flushInterval = Number(config.flushInterval || 10000);
    config.flushInterval = flushInterval;

    if (config.backends) {
      for (var i = 0; i < config.backends.length; i++) {
        loadBackend(config, config.backends[i]);
      }
    } else {
      // The default backend is graphite
      loadBackend(config, './backends/graphite');
    }

    // Setup the flush timer
    var flushInt = setInterval(flushMetrics, flushInterval);

    if (keyFlushInterval > 0) {
      var keyFlushPercent = Number((config.keyFlush && config.keyFlush.percent) || 100);
      var keyFlushLog = config.keyFlush && config.keyFlush.log;

      keyFlushInt = setInterval(function () {
        var sortedKeys = [];

        for (var key in keyCounter) {
          sortedKeys.push([key, keyCounter[key]]);
        }

        sortedKeys.sort(function(a, b) { return b[1] - a[1]; });

        var logMessage = "";
        var timeString = (new Date()) + "";

        // only show the top "keyFlushPercent" keys
        for (var i = 0, e = sortedKeys.length * (keyFlushPercent / 100); i < e; i++) {
          logMessage += timeString + " count=" + sortedKeys[i][1] + " key=" + sortedKeys[i][0] + "\n";
        }

        if (keyFlushLog) {
          var logFile = fs.createWriteStream(keyFlushLog, {flags: 'a+'});
          logFile.write(logMessage);
          logFile.end();
        } else {
          process.stdout.write(logMessage);
        }

        // clear the counter
        keyCounter = {};
      }, keyFlushInterval);
    }
  }
});

process.on('exit', function () {
  flushMetrics();
});
<commit_msg>Fix typo and usage of delete to be inline with the rest of the code<commit_after>/*jshint node:true, laxcomma:true */

var util    = require('util')
  , net    = require('net')
  , config = require('./lib/config')
  , helpers = require('./lib/helpers')
  , fs     = require('fs')
  , events = require('events')
  , logger = require('./lib/logger')
  , set = require('./lib/set')
  , pm = require('./lib/process_metrics')
  , process_mgmt = require('./lib/process_mgmt')
  , mgmt = require('./lib/mgmt_console');

// initialize data structures with defaults for statsd stats
var keyCounter = {};
var counters = {};
var timers = {};
var timer_counters = {};
var gauges = {};
var sets = {};
var counter_rates = {};
var timer_data = {};
var pctThreshold = null;
var flushInterval, keyFlushInt, serverLoaded, mgmtServer;
var startup_time = Math.round(new Date().getTime() / 1000);
var backendEvents = new events.EventEmitter();
var healthStatus = config.healthStatus || 'up';
var old_timestamp = 0;
var timestamp_lag_namespace;
var keyNameSanitize = true;

// Load and init the backend from the backends/ directory.
function loadBackend(config, name) {
  var backendmod = require(name);

  if (config.debug) {
    l.log("Loading backend: " + name, 'DEBUG');
  }

  var ret = backendmod.init(startup_time, config, backendEvents, l);
  if (!ret) {
    l.log("Failed to load backend: " + name);
    process.exit(1);
  }
}

// Load and init the server from the servers/ directory.
// The callback mimics the dgram 'message' event parameters (msg, rinfo)
//   msg: the message received by the server. may contain more than one metric
//   rinfo: contains remote address information and message length
//      (attributes are .address, .port, .family, .size - you're welcome)
function startServer(config, name, callback) {
  var servermod = require(name);

  if (config.debug) {
    l.log("Loading server: " + name, 'DEBUG');
  }

  var ret = servermod.start(config, callback);
  if (!ret) {
    l.log("Failed to load server: " + name);
    process.exit(1);
  }
}

// global for conf
var conf;

// Flush metrics to each backend.
function flushMetrics() {
  var time_stamp = Math.round(new Date().getTime() / 1000);
  if (old_timestamp > 0) {
    gauges[timestamp_lag_namespace] = (time_stamp - old_timestamp - (Number(conf.flushInterval)/1000));
  }
  old_timestamp = time_stamp;

  var metrics_hash = {
    counters: counters,
    gauges: gauges,
    timers: timers,
    timer_counters: timer_counters,
    sets: sets,
    counter_rates: counter_rates,
    timer_data: timer_data,
    pctThreshold: pctThreshold,
    histogram: conf.histogram
  };

  // After all listeners, reset the stats
  backendEvents.once('flush', function clear_metrics(ts, metrics) {
    // TODO: a lot of this should be moved up into an init/constructor so we don't have to do it every
    // single flushInterval....
    // allows us to flag all of these on with a single config but still override them individually
    conf.deleteIdleStats = conf.deleteIdleStats !== undefined ? conf.deleteIdleStats : false;
    if (conf.deleteIdleStats) {
      conf.deleteCounters = conf.deleteCounters !== undefined ? conf.deleteCounters : true;
      conf.deleteTimers = conf.deleteTimers !== undefined ? conf.deleteTimers : true;
      conf.deleteSets = conf.deleteSets !== undefined ? conf.deleteSets : true;
      conf.deleteGauges = conf.deleteGauges !== undefined ? conf.deleteGauges : true;
    }

    // Clear the counters
    conf.deleteCounters = conf.deleteCounters || false;
    for (var counter_key in metrics.counters) {
      if (conf.deleteCounters) {
        if ((counter_key.indexOf("packets_received") != -1) ||
            (counter_key.indexOf("metrics_received") != -1) ||
            (counter_key.indexOf("bad_lines_seen") != -1)) {
          metrics.counters[counter_key] = 0;
        } else {
         delete(metrics.counters[counter_key]);
        }
      } else {
        metrics.counters[counter_key] = 0;
      }
    }

    // Clear the timers
    conf.deleteTimers = conf.deleteTimers || false;
    for (var timer_key in metrics.timers) {
      if (conf.deleteTimers) {
        delete(metrics.timers[timer_key]);
        delete(metrics.timer_counters[timer_key]);
      } else {
        metrics.timers[timer_key] = [];
        metrics.timer_counters[timer_key] = 0;
     }
    }

    // Clear the sets
    conf.deleteSets = conf.deleteSets || false;
    for (var set_key in metrics.sets) {
      if (conf.deleteSets) {
        delete(metrics.sets[set_key]);
      } else {
        metrics.sets[set_key] = new set.Set();
      }
    }

	// normally gauges are not reset.  so if we don't delete them, continue to persist previous value
    conf.deleteGauges = conf.deleteGauges || false;
    if (conf.deleteGauges) {
      for (var gauge_key in metrics.gauges) {
        delete(metrics.gauges[gauge_key]);
      }
    }
  });

  pm.process_metrics(metrics_hash, flushInterval, time_stamp, function emitFlush(metrics) {
      backendEvents.emit('flush', time_stamp, whitelistFlush(metrics));
  });

}

// apply a filter to the metrics that will be flushed to the backend
// to remove metrics that are not included in the configuration: config.whitelistFlush
function whitelistFlush(metrics) {
    if (conf.whitelistFlush) {
        for (var metric in metrics.timer_data) {
            for (var key in metrics.timer_data[metric]) {
                if (conf.whitelistFlush.indexOf(key) < 0) {
                    delete(metrics.timer_data[metric][key]);
                }
            }
        }
    }
    return metrics;
}

var stats = {
  messages: {
    last_msg_seen: startup_time,
    bad_lines_seen: 0
  }
};

function sanitizeKeyName(key) {
  if (keyNameSanitize) {
    return key.replace(/\s+/g, '_')
              .replace(/\//g, '-')
              .replace(/[^a-zA-Z_\-0-9\.]/g, '');
  } else {
    return key;
  }
}

// Global for the logger
var l;

config.configFile(process.argv[2], function (config) {
  conf = config;

  process_mgmt.init(config);

  l = new logger.Logger(config.log || {});

  // setup config for stats prefix
  var prefixStats = config.prefixStats;
  prefixStats = prefixStats !== undefined ? prefixStats : "statsd";
  //setup the names for the stats stored in counters{}
  bad_lines_seen   = prefixStats + ".bad_lines_seen";
  packets_received = prefixStats + ".packets_received";
  metrics_received = prefixStats + ".metrics_received";
  timestamp_lag_namespace = prefixStats + ".timestamp_lag";

  //now set to zero so we can increment them
  counters[bad_lines_seen]   = 0;
  counters[packets_received] = 0;
  counters[metrics_received] = 0;

  if (config.keyNameSanitize !== undefined) {
    keyNameSanitize = config.keyNameSanitize;
  }
    if (!serverLoaded) {
    // key counting
    var keyFlushInterval = Number((config.keyFlush && config.keyFlush.interval) || 0);

    // The default server is UDP
    var server = config.server || './servers/udp'
    serverLoaded = startServer(config, server, function (msg, rinfo) {
      backendEvents.emit('packet', msg, rinfo);
      counters[packets_received]++;
      var packet_data = msg.toString();
      if (packet_data.indexOf("\n") > -1) {
        var metrics = packet_data.split("\n");
      } else {
        var metrics = [ packet_data ] ;
      }

      for (var midx in metrics) {
        if (metrics[midx].length === 0) {
          continue;
        }

        counters[metrics_received]++;
        if (config.dumpMessages) {
          l.log(metrics[midx].toString());
        }
        var bits = metrics[midx].toString().split(':');
        var key = sanitizeKeyName(bits.shift());

        if (keyFlushInterval > 0) {
          if (! keyCounter[key]) {
            keyCounter[key] = 0;
          }
          keyCounter[key] += 1;
        }

        if (bits.length === 0) {
          bits.push("1");
        }

        for (var i = 0; i < bits.length; i++) {
          var sampleRate = 1;
          var fields = bits[i].split("|");
          if (!helpers.is_valid_packet(fields)) {
              l.log('Bad line: ' + fields + ' in msg "' + metrics[midx] +'"');
              counters[bad_lines_seen]++;
              stats.messages.bad_lines_seen++;
              continue;
          }
          if (fields[2]) {
            sampleRate = Number(fields[2].match(/^@([\d\.]+)/)[1]);
          }

          var metric_type = fields[1].trim();
          if (metric_type === "ms") {
            if (! timers[key]) {
              timers[key] = [];
              timer_counters[key] = 0;
            }
            timers[key].push(Number(fields[0] || 0));
            timer_counters[key] += (1 / sampleRate);
          } else if (metric_type === "g") {
            if (gauges[key] && fields[0].match(/^[-+]/)) {
              gauges[key] += Number(fields[0] || 0);
            } else {
              gauges[key] = Number(fields[0] || 0);
            }
          } else if (metric_type === "s") {
            if (! sets[key]) {
              sets[key] = new set.Set();
            }
            sets[key].insert(fields[0] || '0');
          } else {
            if (! counters[key]) {
              counters[key] = 0;
            }
            counters[key] += Number(fields[0] || 1) * (1 / sampleRate);
          }
        }
      }

      stats.messages.last_msg_seen = Math.round(new Date().getTime() / 1000);
    });

    mgmtServer = net.createServer(function(stream) {
      stream.setEncoding('ascii');

      stream.on('error', function(err) {
        l.log('Caught ' + err +', Moving on');
      });

      stream.on('data', function(data) {
        var cmdline = data.trim().split(" ");
        var cmd = cmdline.shift();

        switch(cmd) {
          case "help":
            stream.write("Commands: stats, counters, timers, gauges, delcounters, deltimers, delgauges, health, config, quit\n\n");
            break;

          case "config":
            stream.write("\n");
            for (var prop in config) {
              if (!config.hasOwnProperty(prop)) {
                continue;
              }
              if (typeof config[prop] !== 'object') {
                stream.write(prop + ": " + config[prop] + "\n");
                continue;
              }
              subconfig = config[prop];
              for (var subprop in subconfig) {
                if (!subconfig.hasOwnProperty(subprop)) {
                  continue;
                }
                stream.write(prop + " > " + subprop + ": " + subconfig[subprop] + "\n");
              }
            }
            break;

          case "health":
            if (cmdline.length > 0) {
              var cmdaction = cmdline[0].toLowerCase();
              if (cmdaction === 'up') {
                healthStatus = 'up';
              } else if (cmdaction === 'down') {
                healthStatus = 'down';
              }
            }
            stream.write("health: " + healthStatus + "\n");
            break;

          case "stats":
            var now    = Math.round(new Date().getTime() / 1000);
            var uptime = now - startup_time;

            stream.write("uptime: " + uptime + "\n");

            var stat_writer = function(group, metric, val) {
              var delta;

              if (metric.match("^last_")) {
                delta = now - val;
              }
              else {
                delta = val;
              }

              stream.write(group + "." + metric + ": " + delta + "\n");
            };

            // Loop through the base stats
            for (var group in stats) {
              for (var metric in stats[group]) {
                stat_writer(group, metric, stats[group][metric]);
              }
            }

            backendEvents.once('status', function(writeCb) {
              stream.write("END\n\n");
            });

            // Let each backend contribute its status
            backendEvents.emit('status', function(err, name, stat, val) {
              if (err) {
                l.log("Failed to read stats for backend " +
                        name + ": " + err);
              } else {
                stat_writer(name, stat, val);
              }
            });

            break;

          case "counters":
            stream.write(util.inspect(counters) + "\n");
            stream.write("END\n\n");
            break;

          case "timers":
            stream.write(util.inspect(timers) + "\n");
            stream.write("END\n\n");
            break;

          case "gauges":
            stream.write(util.inspect(gauges) + "\n");
            stream.write("END\n\n");
            break;

          case "delcounters":
            mgmt.delete_stats(counters, cmdline, stream);
            break;

          case "deltimers":
            mgmt.delete_stats(timers, cmdline, stream);
            break;

          case "delgauges":
            mgmt.delete_stats(gauges, cmdline, stream);
            break;

          case "quit":
            stream.end();
            break;

          default:
            stream.write("ERROR\n");
            break;
        }

      });
    });

    mgmtServer.listen(config.mgmt_port || 8126, config.mgmt_address || undefined);

    util.log("server is up");

    pctThreshold = config.percentThreshold || 90;
    if (!Array.isArray(pctThreshold)) {
      pctThreshold = [ pctThreshold ]; // listify percentiles so single values work the same
    }

    flushInterval = Number(config.flushInterval || 10000);
    config.flushInterval = flushInterval;

    if (config.backends) {
      for (var i = 0; i < config.backends.length; i++) {
        loadBackend(config, config.backends[i]);
      }
    } else {
      // The default backend is graphite
      loadBackend(config, './backends/graphite');
    }

    // Setup the flush timer
    var flushInt = setInterval(flushMetrics, flushInterval);

    if (keyFlushInterval > 0) {
      var keyFlushPercent = Number((config.keyFlush && config.keyFlush.percent) || 100);
      var keyFlushLog = config.keyFlush && config.keyFlush.log;

      keyFlushInt = setInterval(function () {
        var sortedKeys = [];

        for (var key in keyCounter) {
          sortedKeys.push([key, keyCounter[key]]);
        }

        sortedKeys.sort(function(a, b) { return b[1] - a[1]; });

        var logMessage = "";
        var timeString = (new Date()) + "";

        // only show the top "keyFlushPercent" keys
        for (var i = 0, e = sortedKeys.length * (keyFlushPercent / 100); i < e; i++) {
          logMessage += timeString + " count=" + sortedKeys[i][1] + " key=" + sortedKeys[i][0] + "\n";
        }

        if (keyFlushLog) {
          var logFile = fs.createWriteStream(keyFlushLog, {flags: 'a+'});
          logFile.write(logMessage);
          logFile.end();
        } else {
          process.stdout.write(logMessage);
        }

        // clear the counter
        keyCounter = {};
      }, keyFlushInterval);
    }
  }
});

process.on('exit', function () {
  flushMetrics();
});
<|endoftext|>


<commit_before>view = Backbone.View.extend();

view.prototype.initialize = function() {
    _(this).bindAll(
        'render',
        'attach',
        'mapZoom',
        'fullscreen'
    );
    this.model.bind('saved', this.attach);
    this.model.bind('poll', this.attach);
    this.render().attach();
};

view.prototype.render = function(init) {
    if (!MM) throw new Error('ModestMaps not found.');

    $(this.el).html(templates.Map());

    this.map = new MM.Map('map',
        new wax.mm.connector(this.model.attributes));

    // Adapted location interaction - opens in new tab
    function locationOn(o) {
        if ((o.e.type === 'mousemove' || !o.e.type)) {
            return;
        } else {
            var loc = o.formatter({ format: 'location' }, o.data);
            if (loc) {
                window.open(loc);
            }
        }
    }

    // Add references to all controls onto the map object.
    // Allows controls to be removed later on.
    this.map.controls = {
        interaction: wax.mm.interaction()
            .map(this.map)
            .tilejson(this.model.attributes)
            .on(wax.tooltip()
                .parent(this.map.parent).events())
            .on({on: locationOn}),
        legend: wax.mm.legend(this.map, this.model.attributes),
        zoombox: wax.mm.zoombox(this.map),
        zoomer: wax.mm.zoomer(this.map).appendTo(this.map.parent),
        fullscreen: wax.mm.fullscreen(this.map).appendTo(this.map.parent)
    };

    // Add image error request handler. "Dedupes" image errors by
    // checking against last received image error so as to not spam
    // the user with the same errors message for every image request.
    this.map.getLayerAt(0).requestManager.addCallback('requesterror', _(function(manager, msg) {
        $.ajax(msg.url, { error: _(function(resp) {
            if (resp.responseText === this._error) return;
            this._error = resp.responseText;
            new views.Modal(resp);
        }).bind(this) });
    }).bind(this));

    var center = this.model.get('center');
    this.map.setCenterZoom(new MM.Location(
        center[1],
        center[0]),
        center[2]);
    this.map.setZoomRange(
        this.model.get('minzoom'),
        this.model.get('maxzoom'));
    this.map.addCallback('zoomed', this.mapZoom);
    this.map.addCallback('panned', this.mapZoom);
    this.map.addCallback('extentset', this.mapZoom);
    this.map.addCallback('resized', this.fullscreen);
    this.mapZoom({element: this.map.div});
    return this;
};

// Catch resize events and add a fullscreen class to the
// project element to handle visibility of components.
// Note that the wax fullscreen control sets a body class that
// we cannot use here as it can be stale (e.g. user routes away
// from a fullscreen'd map, leaving a stale class on the body).
view.prototype.fullscreen = function(e) {
    if (this.$('#map').hasClass('wax-fullscreen-map')) {
        $('div.project').addClass('fullscreen');
    } else {
        $('div.project').removeClass('fullscreen');
    }
};

// Set zoom display.
view.prototype.mapZoom = function(e) {
    this.$('.zoom-display .zoom').text(this.map.getZoom());
};

view.prototype.attach = function() {
    this._error = '';

    var layer = this.map.getLayerAt(0);
    layer.provider.options.tiles = this.model.get('tiles');
    layer.provider.options.minzoom = this.model.get('minzoom');
    layer.provider.options.maxzoom = this.model.get('maxzoom');
    layer.setProvider(layer.provider);

    layer.provider.setZoomRange(layer.provider.options.minzoom,
                          layer.provider.options.maxzoom)

    this.map.setZoomRange(layer.provider.options.minzoom,
                          layer.provider.options.maxzoom)

    this.map.controls.interaction.tilejson(this.model.attributes);

    if (this.model.get('legend')) {
        this.map.controls.legend.content(this.model.attributes);
        this.map.controls.legend.appendTo(this.map.parent);
    } else {
        $(this.map.controls.legend.element()).remove();
    }

    this.map.draw();
    this.mapZoom();
};
<commit_msg>Fix map jump when using fullscreen control<commit_after>view = Backbone.View.extend();

view.prototype.initialize = function() {
    _(this).bindAll(
        'render',
        'attach',
        'mapZoom',
        'fullscreen'
    );
    this.model.bind('saved', this.attach);
    this.model.bind('poll', this.attach);
    this.render().attach();
};

view.prototype.render = function(init) {
    if (!MM) throw new Error('ModestMaps not found.');

    $(this.el).html(templates.Map());

    this.map = new MM.Map('map',
        new wax.mm.connector(this.model.attributes));

    // Adapted location interaction - opens in new tab
    function locationOn(o) {
        if ((o.e.type === 'mousemove' || !o.e.type)) {
            return;
        } else {
            var loc = o.formatter({ format: 'location' }, o.data);
            if (loc) {
                window.open(loc);
            }
        }
    }

    // Add references to all controls onto the map object.
    // Allows controls to be removed later on.
    this.map.controls = {
        interaction: wax.mm.interaction()
            .map(this.map)
            .tilejson(this.model.attributes)
            .on(wax.tooltip()
                .parent(this.map.parent).events())
            .on({on: locationOn}),
        legend: wax.mm.legend(this.map, this.model.attributes),
        zoombox: wax.mm.zoombox(this.map),
        zoomer: wax.mm.zoomer(this.map).appendTo(this.map.parent),
        fullscreen: wax.mm.fullscreen(this.map).appendTo(this.map.parent)
    };

    // Add image error request handler. "Dedupes" image errors by
    // checking against last received image error so as to not spam
    // the user with the same errors message for every image request.
    this.map.getLayerAt(0).requestManager.addCallback('requesterror', _(function(manager, msg) {
        $.ajax(msg.url, { error: _(function(resp) {
            if (resp.responseText === this._error) return;
            this._error = resp.responseText;
            new views.Modal(resp);
        }).bind(this) });
    }).bind(this));

    var center = this.model.get('center');
    this.map.setCenterZoom(new MM.Location(
        center[1],
        center[0]),
        center[2]);
    this.map.setZoomRange(
        this.model.get('minzoom'),
        this.model.get('maxzoom'));
    this.map.addCallback('zoomed', this.mapZoom);
    this.map.addCallback('panned', this.mapZoom);
    this.map.addCallback('extentset', this.mapZoom);
    this.map.addCallback('resized', this.fullscreen);
    this.mapZoom({element: this.map.div});
    return this;
};

// Catch resize events and add a fullscreen class to the
// project element to handle visibility of components.
// Note that the wax fullscreen control sets a body class that
// we cannot use here as it can be stale (e.g. user routes away
// from a fullscreen'd map, leaving a stale class on the body).
view.prototype.fullscreen = function(e) {
    if (this.$('#map').hasClass('wax-fullscreen-map')) {
        $('div.project').addClass('fullscreen');
    } else {
        $('div.project').removeClass('fullscreen');
    }
    this.map.draw();
};

// Set zoom display.
view.prototype.mapZoom = function(e) {
    this.$('.zoom-display .zoom').text(this.map.getZoom());
};

view.prototype.attach = function() {
    this._error = '';

    var layer = this.map.getLayerAt(0);
    layer.provider.options.tiles = this.model.get('tiles');
    layer.provider.options.minzoom = this.model.get('minzoom');
    layer.provider.options.maxzoom = this.model.get('maxzoom');
    layer.setProvider(layer.provider);

    layer.provider.setZoomRange(layer.provider.options.minzoom,
                          layer.provider.options.maxzoom)

    this.map.setZoomRange(layer.provider.options.minzoom,
                          layer.provider.options.maxzoom)

    this.map.controls.interaction.tilejson(this.model.attributes);

    if (this.model.get('legend')) {
        this.map.controls.legend.content(this.model.attributes);
        this.map.controls.legend.appendTo(this.map.parent);
    } else {
        $(this.map.controls.legend.element()).remove();
    }

    this.map.draw();
    this.mapZoom();
};
<|endoftext|>


<commit_before>//////////////////////////////////////////////
// Author: Marcelle Bonterre
// Created On: 5/20/2014
// Purpose: This allows for the creation
//          of HTML lists where multiple
//          items in the list are selectable.
//////////////////////////////////////////////
function multiSelectHandler(){
	return {
		set_click_events: function(config){
			var elems = config.HTMLelements,
				callback = config.callback;

			if( ! window.multiselect ) window.multiselect = {};
			if( ! window.multiselect.columns ) window.multiselect.columns = {};

			var give_focus = function(e){ this.focus(); };

			var add_remove_selected = function(event){
				var parentID = this.parentNode.parentNode.id,
				val = this.value;

				if( ! multiselect.columns[parentID] ){
					multiselect.columns[parentID] = { selected : {}, contents: {} };
				}

				var selections = multiselect.columns[parentID].selected;
				if( this.checked ) selections[val] = this.id;
				else delete selections[val];

				if( callback ) callback( selections );
			};

			if( 'object' === typeof elems ){
				var numElems = elems.length;
				for( var k = 0; k < numElems; ++k ){
					elems[k].onclick = add_remove_selected;
					elems[k].onmouseover = give_focus;
				}
			} else {
				elems.onclick = add_remove_selected;
				elems.onmouseover = give_focus;
			}
		},
		get_selections_from: function(column){
			var rv = multiselect.columns[column];
			if( rv ) return rv.selected;
			return rv;
		},
		make_option: function(name,value,labelText,classNames,callback){
			var input = document.createElement('input');
			input.type = 'checkbox';
			input.name = name;
			input.value = value;
			input.id = value+'option';
			input.style.float = 'left';

            var container = document.createElement('div');
            // FIXME: feature detect classList.
            // if not present, use:
            // if(classNames) container.className += ' ' + classNames;
            if(classNames) container.classList.add(classNames);
            container.appendChild(input);
            container.appendChild(document.createTextNode(labelText));

            var optionObj = {
            	name: name,
            	value: value,
            	label: labelText,
            	id: value+'option',
            	HTML: container
            };

            if( callback ) callback(optionObj);
			return optionObj.HTML;
			// return container;
		},
		append: function(option,column){
			var key = option.value || option;
			if( ! 'object' === typeof column ) column = document.getElementById(column);
			if( ! multiselect.columns[column.id] ) {
				multiselect.columns[column.id] = { selected : {}, contents: {} };
			}

			if( ! multiselect.columns[column.id].contents[key] ){
				multiselect.columns[column.id].contents[key] = option;
				column.appendChild(option.HTML);
			}
		},
		empty: function(column){
			var col = multiselect.columns[column];
			if( col ) delete multiselect.columns[column];

			var elem = document.getElementById(column);
			while (elem.firstChild) {
				elem.removeChild(elem.firstChild);
			}
		},
		select: function(amt,column){
			var col = multiselect.columns[column];
			var selections, id;
			if('none' === amt){
				if( col ){
					selections = col.selected;
					for( var key in selections ){
						id = selections[key];
						document.getElementById(id).checked = false;
						delete selections[key];
					}
				}
			} else if( 'all' === amt ){

			} else {
				if( ! col ) col = multiselect.columns[column] = { selected : {}, contents: {} };
				selections = col.selected;
				var item = amt;
				id = item+'option';
				selections[item] = id;
				document.getElementById(id).checked = true;
			}
		},
		convert_select_to_checkbox: function(elem,callback){
			var div = document.createElement('div');
			div.id = 'tmp'+elem.id;
			div.style.overflow = 'scroll';

			var optStrings_from_optElems = function(optElemList){
				var optStrings = {},
				numOpts = optElemList.length;
				for(var i = 0; i < numOpts; ++i){
					var value = optElemList[i].value;
					var text = optElemList[i].innerHTML;

					optStrings[value] = text;
				}
				return optStrings;
			};

			var opts = optStrings_from_optElems(elem.options);
			for(var key in opts){
				var opt = this.make_option(elem.id+'opt',key,opts[key],'stripe');
				div.appendChild(opt);
			}

			var parent = elem.parentNode;
			parent.appendChild(div);
			parent.removeChild(elem);
			var replacement = document.getElementById(div.id);
			replacement.id = replacement.id.replace(/tmp/,'');

			if( callback ) callback( document.getElementById(div.id) );
			return document.getElementById(div.id);
		}

	}; // end return
} // end multiSelectHandler()
<commit_msg>fixed indenting<commit_after>//////////////////////////////////////////////
// Author: Marcelle Bonterre
// Created On: 5/20/2014
// Purpose: This allows for the creation
//          of HTML lists where multiple
//          items in the list are selectable.
//////////////////////////////////////////////
function multiSelectHandler(){
	return {
		set_click_events: function(config){
			var elems = config.HTMLelements,
			callback = config.callback;

			if( ! window.multiselect ) window.multiselect = {};
			if( ! window.multiselect.columns ) window.multiselect.columns = {};

			var give_focus = function(e){ this.focus(); };

			var add_remove_selected = function(event){
				var parentID = this.parentNode.parentNode.id,
				val = this.value;

				if( ! multiselect.columns[parentID] ){
					multiselect.columns[parentID] = { selected : {}, contents: {} };
				}

				var selections = multiselect.columns[parentID].selected;
				if( this.checked ) selections[val] = this.id;
				else delete selections[val];

				if( callback ) callback( selections );
			};

			if( 'object' === typeof elems ){
				var numElems = elems.length;
				for( var k = 0; k < numElems; ++k ){
					elems[k].onclick = add_remove_selected;
					elems[k].onmouseover = give_focus;
				}
			} else {
				elems.onclick = add_remove_selected;
				elems.onmouseover = give_focus;
			}
		},
		get_selections_from: function(column){
			var rv = multiselect.columns[column];
			if( rv ) return rv.selected;
			return rv;
		},
		make_option: function(name,value,labelText,classNames,callback){
			var input = document.createElement('input');
			input.type = 'checkbox';
			input.name = name;
			input.value = value;
			input.id = value+'option';
			input.style.float = 'left';

			var container = document.createElement('div');
            // FIXME: feature detect classList.
            // if not present, use:
            // if(classNames) container.className += ' ' + classNames;
            if(classNames) container.classList.add(classNames);
            container.appendChild(input);
            container.appendChild(document.createTextNode(labelText));

            var optionObj = {
            	name: name,
            	value: value,
            	label: labelText,
            	id: value+'option',
            	HTML: container
            };

            if( callback ) callback(optionObj);
            return optionObj.HTML;
			// return container;
		},
		append: function(option,column){
			var key = option.value || option;
			if( ! 'object' === typeof column ) column = document.getElementById(column);
			if( ! multiselect.columns[column.id] ) {
				multiselect.columns[column.id] = { selected : {}, contents: {} };
			}

			if( ! multiselect.columns[column.id].contents[key] ){
				multiselect.columns[column.id].contents[key] = option;
				column.appendChild(option.HTML);
			}
		},
		empty: function(column){
			var col = multiselect.columns[column];
			if( col ) delete multiselect.columns[column];

			var elem = document.getElementById(column);
			while (elem.firstChild) {
				elem.removeChild(elem.firstChild);
			}
		},
		select: function(amt,column){
			var col = multiselect.columns[column];
			var selections, id;
			if('none' === amt){
				if( col ){
					selections = col.selected;
					for( var key in selections ){
						id = selections[key];
						document.getElementById(id).checked = false;
						delete selections[key];
					}
				}
			} else if( 'all' === amt ){

			} else {
				if( ! col ) col = multiselect.columns[column] = { selected : {}, contents: {} };
				selections = col.selected;
				var item = amt;
				id = item+'option';
				selections[item] = id;
				document.getElementById(id).checked = true;
			}
		},
		convert_select_to_checkbox: function(elem,callback){
			var div = document.createElement('div');
			div.id = 'tmp'+elem.id;
			div.style.overflow = 'scroll';

			var optStrings_from_optElems = function(optElemList){
				var optStrings = {},
				numOpts = optElemList.length;
				for(var i = 0; i < numOpts; ++i){
					var value = optElemList[i].value;
					var text = optElemList[i].innerHTML;

					optStrings[value] = text;
				}
				return optStrings;
			};

			var opts = optStrings_from_optElems(elem.options);
			for(var key in opts){
				var opt = this.make_option(elem.id+'opt',key,opts[key],'stripe');
				div.appendChild(opt);
			}

			var parent = elem.parentNode;
			parent.appendChild(div);
			parent.removeChild(elem);
			var replacement = document.getElementById(div.id);
			replacement.id = replacement.id.replace(/tmp/,'');

			if( callback ) callback( document.getElementById(div.id) );
			return document.getElementById(div.id);
		}

	}; // end return
} // end multiSelectHandler()
<|endoftext|>


<commit_before>var test = require('ava');

// Fake plugin-structure for wintersmith
var env = {
  helpers: {}
};
require('../../plugins/helpers')(env, function() {});

/**
 * creates a page-mock
 *
 * @param  {string}  path  relative filepath
 * @result {object}        page-mock
 */
function createPageMock(path) {
  return {
    filepath: {
      relative: path
    },
    parent: {
      parent: {
        alerts: {},
        progress: {}
      }
    }
  };
}

test('createPatternTitle', function(t) {
  var pageMock = createPageMock('/patterns/components/alerts/default.md')

  var title = env.helpers.createPatternTitle(pageMock);
  var expected = 'Alerts';

  t.is(title, expected);
});

test('createSubcategoryUrl', function(t) {
  var pagesMock = {
    'default.md': createPageMock('/patterns/components/alerts/default.md'),
    'link-color.md': createPageMock('patterns/components/alerts/link-color.md')
  };

  var url = env.helpers.createSubcategoryUrl(pagesMock);
  var expected = '/patterns/components/alerts/default.html';

  t.is(url, expected);
});<commit_msg>Fix ESLint issues<commit_after>var test = require('ava');

// Fake plugin-structure for wintersmith
var env = {
  helpers: {}
};
require('../../plugins/helpers')(env, function helpers() {});

/**
 * Creates a page-mock
 *
 * @param {string} path - relative filepath
 * @result {object} page-mock
 */
function createPageMock(path) {
  return {
    filepath: {
      relative: path
    },
    parent: {
      parent: {
        alerts: {},
        progress: {}
      }
    }
  };
}

test('createPatternTitle', function createPatternTitle(t) {
  var pageMock = createPageMock('/patterns/components/alerts/default.md');

  var title = env.helpers.createPatternTitle(pageMock);
  var expected = 'Alerts';

  t.is(title, expected);
});

test('createSubcategoryUrl', function createSubcategoryUrl(t) {
  var pagesMock = {
    'default.md': createPageMock('/patterns/components/alerts/default.md'),
    'link-color.md': createPageMock('patterns/components/alerts/link-color.md')
  };

  var url = env.helpers.createSubcategoryUrl(pagesMock);
  var expected = '/patterns/components/alerts/default.html';

  t.is(url, expected);
});
<|endoftext|>


<commit_before>exports.config = {

	//Running a standalone Selenium Server !
	seleniumServerJar: '../node_modules/protractor/selenium/selenium-server-standalone-2.42.2.jar',
	seleniumPort: null,

	chromeDriver: '../node_modules/protractor/selenium/chromedriver',

	// If true, only chromedriver will be started.
	// Tests for browsers other than chrome will not run.
	chromeOnly: false,

	//Deploying to SauceLabs
	sauceUser: process.env.SAUCE_USERNAME,
	sauceKey: process.env.SAUCE_ACCESS_KEY,

	//If Server already there
	//seleniumAddress: null,

	allScriptsTimeout: 11000,

	specs: [
		'e2e/*.js',
	],

	// For a list of available capabilities, see
	// https://code.google.com/p/selenium/wiki/DesiredCapabilities
	// and
	// https://code.google.com/p/selenium/source/browse/javascript/webdriver/capabilities.js
	// Additionally, you may specify count, shardTestFiles, and maxInstances.
	capabilities: {
		browserName: 'chrome',
		tunnel-identifier: process.env.TRAVIS_JOB_NUMBER,
		build: process.env.TRAVIS_BUILD_NUMBER
	},

	framework: 'jasmine',

	jasmineNodeOpts: {
		isVerbose: true,
		showColors: true,
		includeStackTrace: true,
		defaultTimeoutInterval: 30000
	}

};
<commit_msg>chore(core): prevent unexepected token on build<commit_after>exports.config = {

	//Running a standalone Selenium Server !
	seleniumServerJar: '../node_modules/protractor/selenium/selenium-server-standalone-2.42.2.jar',
	seleniumPort: null,

	chromeDriver: '../node_modules/protractor/selenium/chromedriver',

	// If true, only chromedriver will be started.
	// Tests for browsers other than chrome will not run.
	chromeOnly: false,

	//Deploying to SauceLabs
	sauceUser: process.env.SAUCE_USERNAME,
	sauceKey: process.env.SAUCE_ACCESS_KEY,

	//If Server already there
	//seleniumAddress: null,

	allScriptsTimeout: 11000,

	specs: [
		'e2e/*.js',
	],

	// For a list of available capabilities, see
	// https://code.google.com/p/selenium/wiki/DesiredCapabilities
	// and
	// https://code.google.com/p/selenium/source/browse/javascript/webdriver/capabilities.js
	// Additionally, you may specify count, shardTestFiles, and maxInstances.
	capabilities: {
		browserName: 'chrome',
		'tunnel-identifier': process.env.TRAVIS_JOB_NUMBER,
		build: process.env.TRAVIS_BUILD_NUMBER
	},

	framework: 'jasmine',

	jasmineNodeOpts: {
		isVerbose: true,
		showColors: true,
		includeStackTrace: true,
		defaultTimeoutInterval: 30000
	}

};
<|endoftext|>


<commit_before>// tutorial13.js
import { browsers, rows } from './model';
import React, { Component } from 'react';
import ReactFireMixin from 'reactfire';
import { database } from './database';

var Browsers = React.createClass({
  getInitialState: function() {
    return {browsers: this.props.data};
  },
  componentDidMount: function() {
  },
  render: function() {
    var browsers = [];

    for(var key in this.state.browsers){
      browsers.push(

          {this.state.browsers[key].name}

      );
    }

    return (

          {browsers}

    );
  }
});

var Case = React.createClass({
  getInitialState: function() {
    return {data: this.props.data};
  },
  componentDidMount: function() {
  },
  render: function() {
    return (

        {this.state.data.probability}

    );
  }
});

var Row = React.createClass({
  getInitialState: function() {
    return {
      browsers: this.props.browsers,
      device: this.props.device,
      name: this.props.data.name,
      cases: this.props.data.cases
    };
  },
  componentDidMount: function() {

  },
  render: function() {
    var cases = [];

    for(var key in this.state.browsers){
      cases.push(
        <Case key={this.state.device + "-" + key} data={this.state.cases[key]} />
      );
    }

    return (

        {this.state.name}

          {cases}

    );
  }
});

var Rows = React.createClass({
  getInitialState: function() {
    return {
      rows: this.props.rows,
      browsers: this.props.browsers
    };
  },
  componentDidMount: function() {
  },
  render: function() {
    var rows = [];

    for(var key in this.state.rows){
      rows.push(
        <Row key={key} device={key} browsers={this.state.browsers} data={this.state.rows[key]}/>
      );
    }

    return (

{rows}

    );
  }
});

var prepareData = function(ref, defaultData, validator){
  var promise = new Promise(function(resolve, reject){
      ref.on('value', function(snapshot) {
        if((validator && validator(snapshot.val())) || (!validator && snapshot.val())){
          console.log("Have Data");
          resolve(snapshot.val());
        }else{
          // console.log("No Data");
          // console.log("Start set default");
          ref.set(defaultData).then(function(){
            console.log("Default setted");
          });
        }
      });
  });

  return promise;
};

var Chart = React.createClass({
  mixins: [ReactFireMixin],
  getInitialState: function() {
    return {
      browsers: browsers,
      rows: rows
    };
  },
  componentWillMount: function() {
    // database.ref('charts/test1/rows').set(this.state.rows);
    // this.bindAsObject(ref, 'rows');
    var ref = database.ref('charts/test5/rows');

    var validateRows = function(data){
      return !!(data && data.xiaomi);
    };

    this.bindAsObject(ref, 'rows');

    ref.on('value', function(snapshot) {
      console.log(snapshot.val())
    });

    // prepareData(ref, this.state.rows, validateRows).then((data) => {
    //   console.log(data);
    //
    // });
  },
  componentDidMount: function() {
    database.ref('users/zx').set({
      username: "zx",
      time: new Date() + ""
    });
  },
  render: function() {
    return (

        <Browsers data={this.state.browsers} />
        <Rows browsers={this.state.browsers} rows={this.state.rows}/>

    );
  }
});

export { Chart };
<commit_msg>Resolv data init issue.<commit_after>// tutorial13.js
import { browsers, rows } from './model';
import React, { Component } from 'react';
import ReactFireMixin from 'reactfire';
import { database } from './database';

var Browsers = React.createClass({
  getInitialState: function() {
    return {browsers: this.props.data};
  },
  componentDidMount: function() {
  },
  render: function() {
    var browsers = [];

    for(var key in this.props.data){
      browsers.push(

          {this.props.data[key].name}

      );
    }

    return (

          {browsers}

    );
  }
});

var Case = React.createClass({
  getInitialState: function() {
    return {data: this.props.data};
  },
  componentDidMount: function() {
  },
  render: function() {
    return (

        {this.props.data.probability}

    );
  }
});

var Row = React.createClass({
  getInitialState: function() {
    return {
      browsers: this.props.browsers,
      device: this.props.device,
      name: this.props.data.name,
      cases: this.props.data.cases
    };
  },
  componentDidMount: function() {

  },
  render: function() {
    var cases = [];

    console.log("rendering row:", this.props.data);
    for(var key in this.props.browsers){
      cases.push(
        <Case key={this.props.device + "-" + key} data={this.props.data.cases[key]} />
      );
    }

    return (

        {this.props.data.name}

          {cases}

    );
  }
});

var Rows = React.createClass({
  getInitialState: function() {
    return {
      rows: this.props.rows,
      browsers: this.props.browsers
    };
  },
  componentDidMount: function() {
  },
  render: function() {
    var rows = [];

    for(var key in this.props.rows){
      rows.push(
        <Row key={key} device={key} browsers={this.props.browsers} data={this.props.rows[key]}/>
      );
    }

    return (

{rows}

    );
  }
});

var prepareData = function(ref, defaultData, validator){
  var promise = new Promise(function(resolve, reject){
      console.log("Checking remote");
      ref.on('value', function(snapshot) {
        if((validator && validator(snapshot.val())) || (!validator && snapshot.val())){
          console.log("Received Data");
          resolve(snapshot.val());
        }else{
          console.log("No Data");
          console.log("Start set default");
          ref.set(defaultData).then(function(){
            console.log("Default setted");
            // value event is triggerd before this callback
          });
        }
      });
  });

  return promise;
};

var Chart = React.createClass({
  mixins: [ReactFireMixin],
  getInitialState: function() {
    return {
      browsers: browsers,
      rows: rows
    };
  },
  componentWillMount: function() {
    var ref = database.ref('charts/test6/rows');

    // this.bindAsObject(ref, 'rows');

    // ref.on('value', (snapshot) => {
    //   // console.log("received", snapshot.val());
    //   this.setState({
    //     rows: snapshot.val()
    //   });
    // });

    var validateRows = function(data){
      return !!(data && data.xiaomi);
    };
    prepareData(ref, this.state.rows, validateRows).then((data) => {
      console.log(data);
        this.setState({
          rows: data
        });
    });
  },
  componentDidMount: function() {
    database.ref('users/zx').set({
      username: "zx",
      time: new Date() + ""
    });
  },
  render: function() {
    return (

        <Browsers data={this.state.browsers} />
        <Rows browsers={this.state.browsers} rows={this.state.rows}/>

    );
  }
});

export { Chart };
<|endoftext|>


<commit_before>// @flow

import Hooks from './hooks'
import {buildConfig} from 'cli-engine-config'

let init = (options = {}) => {
  process.env.RAN_HOOK = '0'
  let config = buildConfig(options)
  return new Hooks({config})
}

test('does not error when no hooks', async () => {
  let hooks = init()
  await hooks.run('prerun')
})

test('fires a hook', async () => {
  let hooks = init({
    root: process.cwd(),
    hooks: {
      prerun: 'test/fixtures/hooks/prerun.js'
    }
  })
  await hooks.run('prerun')
  expect(process.env.RAN_HOOK).toEqual('1')
})
<commit_msg>multiple hooks<commit_after>// @flow

import Hooks from './hooks'
import {buildConfig} from 'cli-engine-config'

let init = (options = {}) => {
  process.env.RAN_HOOK = '0'
  let config = buildConfig(options)
  return new Hooks({config})
}

test('does not error when no hooks', async () => {
  let hooks = init()
  await hooks.run('prerun')
})

test('fires a hook', async () => {
  let hooks = init({
    root: process.cwd(),
    hooks: {
      prerun: [
        'test/fixtures/hooks/prerun.js'
      ]
    }
  })
  await hooks.run('prerun')
  expect(process.env.RAN_HOOK).toEqual('1')
})
<|endoftext|>


<commit_before>import React, { useCallback, useContext, useEffect, useState } from "react";

import Baskerville from "../components/Baskerville";
import Emoji from "../components/Emoji";
import Link from "../components/Link";

import Fraktio from "../components/Fraktio";
import {
  Cv,
  Email,
  GitHub,
  Linkedin,
  Npm,
  Portfolio,
  Telegram,
  Twitter
} from "../components/icons";

const staticMessages = [

    Hello there! <Emoji label="Smiling Face With Sunglasses">😎</Emoji>

,

My name is Iiro Jäppinen
,

    I’m a UX <Baskerville>&</Baskerville> UI Designer

,

But I also code ECMAscript and React!
,

    I work at <Fraktio />

,

    There I help people realise their ideas, design useful experiences and
    create beautiful interfaces and interactions.

,

    You should email me at{" "}
    <Link href="mailto:hello@iiro.fi">
      <Emoji label="Email">
        <Email />
      </Emoji>{" "}
      hello@iiro.fi
    </Link>{" "}
    or send a tweet to{" "}
    <Link href="https://twitter.com/iirojappinen">
      <Emoji label="Twitter">
        <Twitter />
      </Emoji>{" "}
      @iirojappinen
    </Link>

,

    I also have a{" "}
    <Link href="/cv/">
      <Emoji label="CV">
        <Cv />
      </Emoji>{" "}
      CV
    </Link>
    ,{" "}
    <Link href="/portfolio/">
      <Emoji label="Portfolio">
        <Portfolio />
      </Emoji>{" "}
      Portfolio
    </Link>{" "}
    and a{" "}
    <Link href="https://fi.linkedin.com/in/iiroj">
      <Emoji label="Linkedin">
        <Linkedin />
      </Emoji>{" "}
      LinkedIn
    </Link>{" "}
    profile.

,

    Check out my{" "}
    <Link href="https://github.com/iiroj">
      <Emoji label="GitHub">
        <GitHub />
      </Emoji>{" "}
      GitHub
    </Link>{" "}
    and{" "}
    <Link href="https://www.npmjs.com/~iiroj">
      <Emoji label="npmn">
        <Npm />
      </Emoji>{" "}
      npm
    </Link>{" "}
    for my open source work.

,

    Finally, feel free to send me anonymous{" "}
    <Emoji label="Telegram">
      <Telegram />
    </Emoji>{" "}
    feedback from below. Have a nice day!

];

const sentFeedbackMessage = (

    <Emoji label="Check Mark">✅</Emoji> Thanks for the feedback!

);

const noScriptMessage = (

    <Emoji label="Warning">⚠</Emoji> Uh-oh! It seems you don’t have Javascript
    enabled.

);

const randomIntFromInterval = (min, max) =>
  Math.floor(Math.random() * (max - min + 1) + min);

const waitFor = ms => new Promise(resolve => setTimeout(resolve, ms));

function* messageGenerator(i = 0) {
  while (true) yield staticMessages[i++];
}

const generateMessage = messageGenerator();

const useChatService = () => {
  const [initialized, setInitialized] = useState(false);
  const [typing, setTyping] = useState(false);
  const [messages, setMessages] = useState([
    // Replace the last message on SSR, since it's about sending Feedback
    ...staticMessages.slice(0, staticMessages.length - 1),
    noScriptMessage
  ]);

  const getMessages = async () => {
    if (initialized) {
      await waitFor(randomIntFromInterval(20, 40) * 100);
      setTyping(messages.length < staticMessages.length);
    } else {
      setTyping(true);
      setInitialized(true);
    }

    await waitFor(randomIntFromInterval(20, 40) * 100);
    const message = generateMessage.next().value;
    setMessages(messages =>
      messages.length >= staticMessages.length
        ? messages
        : [...messages, message]
    );
    setTyping(false);
  };

  useEffect(() => {
    setMessages([]);
  }, []);

  useEffect(() => {
    getMessages();
  }, [messages.length]);

  const handleSkip = useCallback(() => {
    setMessages(staticMessages);
    setTyping(false);
  }, []);

  const handleSentFeedback = () => {
    setMessages(messages => [...messages, sentFeedbackMessage]);
  };

  return {
    handleSentFeedback,
    handleSkip,
    messages,
    ready: messages.length >= staticMessages.length,
    typing
  };
};

const ChatContext = React.createContext();

export const ChatProvider = ({ children }) => {
  const value = useChatService();
  return <ChatContext.Provider value={value}>{children}</ChatContext.Provider>;
};

export default () => {
  const context = useContext(ChatContext);
  return context;
};
<commit_msg>refactor: always wait for 1 sec<commit_after>import React, { useCallback, useContext, useEffect, useState } from "react";

import Baskerville from "../components/Baskerville";
import Emoji from "../components/Emoji";
import Link from "../components/Link";

import Fraktio from "../components/Fraktio";
import {
  Cv,
  Email,
  GitHub,
  Linkedin,
  Npm,
  Portfolio,
  Telegram,
  Twitter
} from "../components/icons";

const staticMessages = [

    Hello there! <Emoji label="Smiling Face With Sunglasses">😎</Emoji>

,

My name is Iiro Jäppinen
,

    I’m a UX <Baskerville>&</Baskerville> UI Designer

,

But I also code ECMAscript and React!
,

    I work at <Fraktio />

,

    There I help people realise their ideas, design useful experiences and
    create beautiful interfaces and interactions.

,

    You should email me at{" "}
    <Link href="mailto:hello@iiro.fi">
      <Emoji label="Email">
        <Email />
      </Emoji>{" "}
      hello@iiro.fi
    </Link>{" "}
    or send a tweet to{" "}
    <Link href="https://twitter.com/iirojappinen">
      <Emoji label="Twitter">
        <Twitter />
      </Emoji>{" "}
      @iirojappinen
    </Link>

,

    I also have a{" "}
    <Link href="/cv/">
      <Emoji label="CV">
        <Cv />
      </Emoji>{" "}
      CV
    </Link>
    ,{" "}
    <Link href="/portfolio/">
      <Emoji label="Portfolio">
        <Portfolio />
      </Emoji>{" "}
      Portfolio
    </Link>{" "}
    and a{" "}
    <Link href="https://fi.linkedin.com/in/iiroj">
      <Emoji label="Linkedin">
        <Linkedin />
      </Emoji>{" "}
      LinkedIn
    </Link>{" "}
    profile.

,

    Check out my{" "}
    <Link href="https://github.com/iiroj">
      <Emoji label="GitHub">
        <GitHub />
      </Emoji>{" "}
      GitHub
    </Link>{" "}
    and{" "}
    <Link href="https://www.npmjs.com/~iiroj">
      <Emoji label="npmn">
        <Npm />
      </Emoji>{" "}
      npm
    </Link>{" "}
    for my open source work.

,

    Finally, feel free to send me anonymous{" "}
    <Emoji label="Telegram">
      <Telegram />
    </Emoji>{" "}
    feedback from below. Have a nice day!

];

const sentFeedbackMessage = (

    <Emoji label="Check Mark">✅</Emoji> Thanks for the feedback!

);

const noScriptMessage = (

    <Emoji label="Warning">⚠</Emoji> Uh-oh! It seems you don’t have Javascript
    enabled.

);

const randomIntFromInterval = (min, max) =>
  Math.floor(Math.random() * (max - min + 1) + min);

const waitFor = ms => new Promise(resolve => setTimeout(resolve, ms));

function* messageGenerator(i = 0) {
  while (true) yield staticMessages[i++];
}

const generateMessage = messageGenerator();

const useChatService = () => {
  const [initialized, setInitialized] = useState(false);
  const [typing, setTyping] = useState(false);
  const [messages, setMessages] = useState([
    // Replace the last message on SSR, since it's about sending Feedback
    ...staticMessages.slice(0, staticMessages.length - 1),
    noScriptMessage
  ]);

  const getMessages = async () => {
    if (initialized) {
      await waitFor(1000);
      setTyping(messages.length < staticMessages.length);
    } else {
      setTyping(true);
      setInitialized(true);
    }

    await waitFor(randomIntFromInterval(20, 40) * 100);
    const message = generateMessage.next().value;
    setMessages(messages =>
      messages.length >= staticMessages.length
        ? messages
        : [...messages, message]
    );
    setTyping(false);
  };

  useEffect(() => {
    setMessages([]);
  }, []);

  useEffect(() => {
    getMessages();
  }, [messages.length]);

  const handleSkip = useCallback(() => {
    setMessages(staticMessages);
    setTyping(false);
  }, []);

  const handleSentFeedback = () => {
    setMessages(messages => [...messages, sentFeedbackMessage]);
  };

  return {
    handleSentFeedback,
    handleSkip,
    messages,
    ready: messages.length >= staticMessages.length,
    typing
  };
};

const ChatContext = React.createContext();

export const ChatProvider = ({ children }) => {
  const value = useChatService();
  return <ChatContext.Provider value={value}>{children}</ChatContext.Provider>;
};

export default () => {
  const context = useContext(ChatContext);
  return context;
};
<|endoftext|>