<commit_before>// Measurements from ErgoDox design.
var SWITCH_PLATE_THICKNESS = 3;
var SWITCH_HOLE_SIZE = 13.97;
var SWITCH_NOTCH_WIDTH = 3.5001;
var SWITCH_NOTCH_DEPTH = 0.8128;

var SWITCH_CENTER_Y_SPACING = 19;
var SWITCH_CENTER_X_SPACING = 19;

// Returns the filled solid of a switch hole.
function switchHole(opts={thickness: SWITCH_PLATE_THICKNESS}) {
  var thickness = opts.thickness;
  var holeRadius = SWITCH_HOLE_SIZE / 2;
  var plateRadius = thickness / 2;
  var square = CSG.cube({
    radius: [holeRadius, holeRadius, plateRadius],
  });
  var notch = CSG.cube({
    radius: [SWITCH_NOTCH_DEPTH / 2, SWITCH_NOTCH_WIDTH / 2, plateRadius],
  });
  var notchCenterOffset = holeRadius - SWITCH_NOTCH_DEPTH / 2;

  var hole = square.subtract(
    notch.translate([notchCenterOffset, 0])
  ).subtract(
    notch.translate([-notchCenterOffset, 0])
  );

  // Point, axis, perpendicular axis
  hole.properties.center = new CSG.Connector([0, 0, 0], [0, 0, 1], [0, 1, 0]);

  return hole;
}

// Builds a matrix of key switch descriptors that are unconnected
// but contain the information to be connected.
// The first switch (at coordinates[0, 0]) will not have connecting
// information.
function buildUnconnectedSwitchDescriptorMatrix(opts={placementMatrix: [[]], columnOffsets: [], rowOffsets: []}) {
  var placementMatrix = opts.placementMatrix;
  var columnOffsets = opts.columnOffsets;
  var rowOffsets = opts.rowOffsets;
  var resultMatrix = [];

  for (var row = 0; row < placementMatrix.length; ++row) {
    var baseY = row * SWITCH_CENTER_Y_SPACING;

    resultMatrix.push([]);
    for (var col = 0; col < placementMatrix[row].length; ++col) {
      var result = {
        keySwitch: switchHole(),
        parentSwitchLocation: null,
        parentConnector: null,
        ownLocation: [row, col],
      };

      var baseX = col * SWITCH_CENTER_X_SPACING;
      if (col > 0) {
        // Connect switch to previous switch in row.
        result.parentSwitchLocation = [row, col - 1];
        var point = [-SWITCH_CENTER_X_SPACING, -columnOffsets[col] || 0, 0];
        result.parentConnector = new CSG.Connector(point, [0, 0, 1], [0, 1, 0]);
      } else if (row > 0) {
        // Connect switch to first switch in previous row.
        result.parentSwitchLocation = [row - 1, col];
        var point = [baseX + (rowOffsets[row] || 0), SWITCH_CENTER_Y_SPACING, 0];
        result.parentConnector = new CSG.Connector(point, [0, 0, 1], [0, 1, 0]);
      } else {
        // Switch at [0, 0] will be connected later.
      }

      result.present = placementMatrix[row][col] == 1;

      resultMatrix[row].push(result);
    }
  }

  return resultMatrix;
}

// Add connections between the switches in an unconnected
// descriptor matrix.
// We have to delay adding these connections until after the
// connection information (if any) is added to the switch in
// this matrix that links it to another object since connections
// don't cause cascading changes.
function connectSwitchesInDescriptorMatrix(matrix, opts={center: false}) {
  for (var row = 0; row < matrix.length; ++row) {
    for (var col = 0; col < matrix[row].length; ++col) {
      var descriptor = matrix[row][col];
      var parentObject = null;
      if (descriptor.parentObject) {
        parentObject = descriptor.parentObject;
      } else if (descriptor.parentSwitchLocation) {
        var parentDescriptor = matrix;
        for (var i = 0; i < descriptor.parentSwitchLocation.length; ++i) {
          parentDescriptor = parentDescriptor[descriptor.parentSwitchLocation[i]];
        }
        parentObject = parentDescriptor.keySwitch;
      }
      if (parentObject) {
        if (!descriptor.keySwitch.properties.parentSwitchCenter && descriptor.parentConnector) {
          descriptor.keySwitch.properties.parentSwitchCenter = descriptor.parentConnector;
        }
        var updatedKeySwitch = descriptor.keySwitch
        if (opts.center) {
          updatedKeySwitch = updatedKeySwitch.center();
        }
        updatedKeySwitch = updatedKeySwitch.connectTo(
          descriptor.parentConnector,
          parentObject.properties[descriptor.parentObjectConnectorName || "center"],
          false,
          0
        );
        descriptor.keySwitch = updatedKeySwitch;
      }
    }
  }
}

function hullForMatrix(matrix, opts={radius: 0, offset: {}}) {
  var radius = opts.radius || 0;
  var offset = opts.offset || {};

  var topRow = [];
  for (var col = 0; col < matrix[0].length; ++col) {
    for (var row = 0; row < matrix.length; ++row) {
      if (matrix[row][col].present) {
        topRow.push(matrix[row][col].keySwitch.translate([0, offset.top || 0, 0]));
        break;
      }
    }
  }

  var rightColumn = [];
  for (var row = 0; row < matrix.length; ++row) {
    for (var col = matrix[row].length - 1; col >= 0; --col) {
      if (matrix[row][col].present) {
        rightColumn.push(matrix[row][col].keySwitch.translate([offset.right || 0, 0, 0]));
        break;
      }
    }
  }

  var bottomRow = [];
  for (var col = matrix[0].length - 1; col >= 0; --col) {
    for (var row = matrix.length - 1; row >= 0; --row) {
      if (matrix[row][col].present) {
        bottomRow.push(matrix[row][col].keySwitch.translate([0, offset.bottom || 0, 0]));
        break;
      }
    }
  }

  var leftColumn = [];
  for (var row = matrix.length - 1; row >= 0; --row) {
    for (var col = 0; col < matrix[row].length; ++col) {
      if (matrix[row][col].present) {
        leftColumn.push(matrix[row][col].keySwitch.translate([offset.left || 0, 0, 0]));
        break;
      }
    }
  }

  // Generate bounding squares for each switch.
  var borderSquares = [];
  var borderSegments = [topRow, rightColumn, bottomRow, leftColumn];
  for (var segment = 0; segment < borderSegments.length; ++segment) {
    for (var i = 0; i < borderSegments[segment].length; ++i) {
      var bounds = borderSegments[segment][i].getBounds();
      var center = [(bounds[0].x + bounds[1].x) / 2, (bounds[0].y + bounds[1].y) / 2];
      var square = CAG.rectangle({center: center, radius: (SWITCH_CENTER_Y_SPACING / 2) + radius});
      borderSquares.push(square);
    }
  }

  return hull(borderSquares);
}

function switchPlateLeftHand() {
  var primaryMatrix = buildUnconnectedSwitchDescriptorMatrix({
    placementMatrix: [
      [1, 1, 1, 1, 1, 1],
      [1, 1, 1, 1, 1, 1],
      [1, 1, 1, 1, 1, 1],
      [1, 1, 1, 1, 1, 1],
      [0, 0, 1, 1, 1, 0],
    ],
    columnOffsets: [0, -4, 14, 5, -6, -5],
    rowOffsets: [],
  });

  var thumbMatrix = buildUnconnectedSwitchDescriptorMatrix({
    placementMatrix: [
      [1, 1],
      [1, 1],
    ],
    columnOffsets: [0, -2],
    rowOffsets: [],
  });

  // Layout initial relative switch positions for primary matrix (required for hull calculation).
  connectSwitchesInDescriptorMatrix(primaryMatrix, {center: true});

  // Set up connection from thumb matrix to primary matrix.
  var thumbMatrixParentRow = primaryMatrix[primaryMatrix.length - 2];
  var thumbMatrixParent = thumbMatrixParentRow[thumbMatrixParentRow.length - 1];
  thumbMatrix[0][0].parentObject = thumbMatrixParent.keySwitch;
  thumbMatrix[0][0].parentConnector = new CSG.Connector([0, SWITCH_CENTER_Y_SPACING, 0], [0, 0, 1], [0, 1, 0]);

  // Layout initial relative switch positions for thumb matrix (required for hull calculation).
  connectSwitchesInDescriptorMatrix(thumbMatrix, {center: true});

  var primaryExteriorHull = hullForMatrix(primaryMatrix, {radius: 10, offset: {bottom: -25}});
  var primaryInteriorHull = hullForMatrix(primaryMatrix, {radius: 3});
  var primaryPlate = linear_extrude({height: SWITCH_PLATE_THICKNESS}, primaryExteriorHull);
  var primaryInteriorCutout = linear_extrude({height: SWITCH_PLATE_THICKNESS}, primaryInteriorHull);

  var thumbExteriorHull = hullForMatrix(thumbMatrix, {radius: 10});
  var thumbInteriorHull = hullForMatrix(thumbMatrix, {radius: 3});
  var thumbPlate = linear_extrude({height: SWITCH_PLATE_THICKNESS}, thumbExteriorHull);
  var thumbInteriorCutout = linear_extrude({height: SWITCH_PLATE_THICKNESS}, thumbInteriorHull);

  // Connect primary matrix to primary switch plate.
  primaryMatrix[0][0].parentObject = primaryPlate;
  primaryMatrix[0][0].parentObjectConnectorName = "primarySwitchPlateConnector";
  primaryPlate.properties.primarySwitchPlateConnector = new CSG.Connector(
    primaryMatrix[0][0].keySwitch.properties.center.point,
    [0, 0, 1],
    [0, 1, 0]
  );
  // These two points are intentionally identical.
  primaryMatrix[0][0].parentConnector = primaryPlate.properties.primarySwitchPlateConnector;
  connectSwitchesInDescriptorMatrix(primaryMatrix, {center: true});

  // Connect thumb switch plate to thumb matrix.
  thumbPlate.properties.thumbMatrixConnector = new CSG.Connector(
    thumbMatrix[0][0].keySwitch.properties.center.point,
    [0, 0, 1],
    [0, 1, 0]
  );
  // Adjust the spacer first so that we don't use the updated proerty.
  // While the space is at a different Z coordinate, the two connectors
  // used have identical Z coordinates, so the transformation is sound.
  thumbInteriorCutout = thumbInteriorCutout.connectTo(
    thumbPlate.properties.thumbMatrixConnector,
    thumbMatrix[0][0].keySwitch.properties.center,
    false,
    0
  );
  thumbPlate = thumbPlate.connectTo(
    thumbPlate.properties.thumbMatrixConnector,
    thumbMatrix[0][0].keySwitch.properties.center,
    false,
    0
  );

  var switches = [];
  var matrices = [primaryMatrix, thumbMatrix];
  for (var h = 0; h < matrices.length; ++h) {
    var matrix = matrices[h];
    for (var i = 0; i < matrix.length; ++i) {
      var row = matrix[i];
      for (var j = 0; j < row.length; ++j) {
        if (row[j].present) {
          switches.push(row[j].keySwitch);
        }
      }
    }
  }

  var fullPlate = primaryPlate.union(thumbPlate);
  var fullInteriorCutout = primaryInteriorCutout.union(thumbInteriorCutout);
  var fullSpacer = fullPlate.subtract(fullInteriorCutout);

  var switchPlate = fullPlate;
  for (var i = 0; i < switches.length; ++i) {
    var keySwitch = switches[i];
    var switchBounds = keySwitch.getBounds();
    keySwitch = keySwitch.translate([0, 0, -switchBounds[0].z]);
    switchPlate = switchPlate.subtract(keySwitch);
  }

  return switchPlate.translate([0, 0, SWITCH_PLATE_THICKNESS]).union(fullSpacer);
}

function main() {
  return switchPlateLeftHand();
}

<commit_msg>Fix inverted row offsetting logic.<commit_after>// Measurements from ErgoDox design.
var SWITCH_PLATE_THICKNESS = 3;
var SWITCH_HOLE_SIZE = 13.97;
var SWITCH_NOTCH_WIDTH = 3.5001;
var SWITCH_NOTCH_DEPTH = 0.8128;

var SWITCH_CENTER_Y_SPACING = 19;
var SWITCH_CENTER_X_SPACING = 19;

// Returns the filled solid of a switch hole.
function switchHole(opts={thickness: SWITCH_PLATE_THICKNESS}) {
  var thickness = opts.thickness;
  var holeRadius = SWITCH_HOLE_SIZE / 2;
  var plateRadius = thickness / 2;
  var square = CSG.cube({
    radius: [holeRadius, holeRadius, plateRadius],
  });
  var notch = CSG.cube({
    radius: [SWITCH_NOTCH_DEPTH / 2, SWITCH_NOTCH_WIDTH / 2, plateRadius],
  });
  var notchCenterOffset = holeRadius - SWITCH_NOTCH_DEPTH / 2;

  var hole = square.subtract(
    notch.translate([notchCenterOffset, 0])
  ).subtract(
    notch.translate([-notchCenterOffset, 0])
  );

  // Point, axis, perpendicular axis
  hole.properties.center = new CSG.Connector([0, 0, 0], [0, 0, 1], [0, 1, 0]);

  return hole;
}

// Builds a matrix of key switch descriptors that are unconnected
// but contain the information to be connected.
// The first switch (at coordinates[0, 0]) will not have connecting
// information.
function buildUnconnectedSwitchDescriptorMatrix(opts={placementMatrix: [[]], columnOffsets: [], rowOffsets: []}) {
  var placementMatrix = opts.placementMatrix;
  var columnOffsets = opts.columnOffsets;
  var rowOffsets = opts.rowOffsets;
  var resultMatrix = [];

  for (var row = 0; row < placementMatrix.length; ++row) {
    var baseY = row * SWITCH_CENTER_Y_SPACING;

    resultMatrix.push([]);
    for (var col = 0; col < placementMatrix[row].length; ++col) {
      var result = {
        keySwitch: switchHole(),
        parentSwitchLocation: null,
        parentConnector: null,
        ownLocation: [row, col],
      };

      var baseX = col * SWITCH_CENTER_X_SPACING;
      if (col > 0) {
        // Connect switch to previous switch in row.
        result.parentSwitchLocation = [row, col - 1];
        var point = [-SWITCH_CENTER_X_SPACING, -columnOffsets[col] || 0, 0];
        result.parentConnector = new CSG.Connector(point, [0, 0, 1], [0, 1, 0]);
      } else if (row > 0) {
        // Connect switch to first switch in previous row.
        result.parentSwitchLocation = [row - 1, col];
        var point = [baseX - (rowOffsets[row] || 0), SWITCH_CENTER_Y_SPACING, 0];
        result.parentConnector = new CSG.Connector(point, [0, 0, 1], [0, 1, 0]);
      } else {
        // Switch at [0, 0] will be connected later.
      }

      result.present = placementMatrix[row][col] == 1;

      resultMatrix[row].push(result);
    }
  }

  return resultMatrix;
}

// Add connections between the switches in an unconnected
// descriptor matrix.
// We have to delay adding these connections until after the
// connection information (if any) is added to the switch in
// this matrix that links it to another object since connections
// don't cause cascading changes.
function connectSwitchesInDescriptorMatrix(matrix, opts={center: false}) {
  for (var row = 0; row < matrix.length; ++row) {
    for (var col = 0; col < matrix[row].length; ++col) {
      var descriptor = matrix[row][col];
      var parentObject = null;
      if (descriptor.parentObject) {
        parentObject = descriptor.parentObject;
      } else if (descriptor.parentSwitchLocation) {
        var parentDescriptor = matrix;
        for (var i = 0; i < descriptor.parentSwitchLocation.length; ++i) {
          parentDescriptor = parentDescriptor[descriptor.parentSwitchLocation[i]];
        }
        parentObject = parentDescriptor.keySwitch;
      }
      if (parentObject) {
        if (!descriptor.keySwitch.properties.parentSwitchCenter && descriptor.parentConnector) {
          descriptor.keySwitch.properties.parentSwitchCenter = descriptor.parentConnector;
        }
        var updatedKeySwitch = descriptor.keySwitch
        if (opts.center) {
          updatedKeySwitch = updatedKeySwitch.center();
        }
        updatedKeySwitch = updatedKeySwitch.connectTo(
          descriptor.parentConnector,
          parentObject.properties[descriptor.parentObjectConnectorName || "center"],
          false,
          0
        );
        descriptor.keySwitch = updatedKeySwitch;
      }
    }
  }
}

function hullForMatrix(matrix, opts={radius: 0, offset: {}}) {
  var radius = opts.radius || 0;
  var offset = opts.offset || {};

  var topRow = [];
  for (var col = 0; col < matrix[0].length; ++col) {
    for (var row = 0; row < matrix.length; ++row) {
      if (matrix[row][col].present) {
        topRow.push(matrix[row][col].keySwitch.translate([0, offset.top || 0, 0]));
        break;
      }
    }
  }

  var rightColumn = [];
  for (var row = 0; row < matrix.length; ++row) {
    for (var col = matrix[row].length - 1; col >= 0; --col) {
      if (matrix[row][col].present) {
        rightColumn.push(matrix[row][col].keySwitch.translate([offset.right || 0, 0, 0]));
        break;
      }
    }
  }

  var bottomRow = [];
  for (var col = matrix[0].length - 1; col >= 0; --col) {
    for (var row = matrix.length - 1; row >= 0; --row) {
      if (matrix[row][col].present) {
        bottomRow.push(matrix[row][col].keySwitch.translate([0, offset.bottom || 0, 0]));
        break;
      }
    }
  }

  var leftColumn = [];
  for (var row = matrix.length - 1; row >= 0; --row) {
    for (var col = 0; col < matrix[row].length; ++col) {
      if (matrix[row][col].present) {
        leftColumn.push(matrix[row][col].keySwitch.translate([offset.left || 0, 0, 0]));
        break;
      }
    }
  }

  // Generate bounding squares for each switch.
  var borderSquares = [];
  var borderSegments = [topRow, rightColumn, bottomRow, leftColumn];
  for (var segment = 0; segment < borderSegments.length; ++segment) {
    for (var i = 0; i < borderSegments[segment].length; ++i) {
      var bounds = borderSegments[segment][i].getBounds();
      var center = [(bounds[0].x + bounds[1].x) / 2, (bounds[0].y + bounds[1].y) / 2];
      var square = CAG.rectangle({center: center, radius: (SWITCH_CENTER_Y_SPACING / 2) + radius});
      borderSquares.push(square);
    }
  }

  return hull(borderSquares);
}

function switchPlateLeftHand() {
  var primaryMatrix = buildUnconnectedSwitchDescriptorMatrix({
    placementMatrix: [
      [1, 1, 1, 1, 1, 1],
      [1, 1, 1, 1, 1, 1],
      [1, 1, 1, 1, 1, 1],
      [1, 1, 1, 1, 1, 1],
      [0, 0, 1, 1, 1, 0],
    ],
    columnOffsets: [0, -4, 14, 5, -6, -5],
    rowOffsets: [],
  });

  var thumbMatrix = buildUnconnectedSwitchDescriptorMatrix({
    placementMatrix: [
      [1, 1],
      [1, 1],
    ],
    columnOffsets: [0, -2],
    rowOffsets: [],
  });

  // Layout initial relative switch positions for primary matrix (required for hull calculation).
  connectSwitchesInDescriptorMatrix(primaryMatrix, {center: true});

  // Set up connection from thumb matrix to primary matrix.
  var thumbMatrixParentRow = primaryMatrix[primaryMatrix.length - 2];
  var thumbMatrixParent = thumbMatrixParentRow[thumbMatrixParentRow.length - 1];
  thumbMatrix[0][0].parentObject = thumbMatrixParent.keySwitch;
  thumbMatrix[0][0].parentConnector = new CSG.Connector([0, SWITCH_CENTER_Y_SPACING, 0], [0, 0, 1], [0, 1, 0]);

  // Layout initial relative switch positions for thumb matrix (required for hull calculation).
  connectSwitchesInDescriptorMatrix(thumbMatrix, {center: true});

  var primaryExteriorHull = hullForMatrix(primaryMatrix, {radius: 10, offset: {bottom: -25}});
  var primaryInteriorHull = hullForMatrix(primaryMatrix, {radius: 3});
  var primaryPlate = linear_extrude({height: SWITCH_PLATE_THICKNESS}, primaryExteriorHull);
  var primaryInteriorCutout = linear_extrude({height: SWITCH_PLATE_THICKNESS}, primaryInteriorHull);

  var thumbExteriorHull = hullForMatrix(thumbMatrix, {radius: 10});
  var thumbInteriorHull = hullForMatrix(thumbMatrix, {radius: 3});
  var thumbPlate = linear_extrude({height: SWITCH_PLATE_THICKNESS}, thumbExteriorHull);
  var thumbInteriorCutout = linear_extrude({height: SWITCH_PLATE_THICKNESS}, thumbInteriorHull);

  // Connect primary matrix to primary switch plate.
  primaryMatrix[0][0].parentObject = primaryPlate;
  primaryMatrix[0][0].parentObjectConnectorName = "primarySwitchPlateConnector";
  primaryPlate.properties.primarySwitchPlateConnector = new CSG.Connector(
    primaryMatrix[0][0].keySwitch.properties.center.point,
    [0, 0, 1],
    [0, 1, 0]
  );
  // These two points are intentionally identical.
  primaryMatrix[0][0].parentConnector = primaryPlate.properties.primarySwitchPlateConnector;
  connectSwitchesInDescriptorMatrix(primaryMatrix, {center: true});

  // Connect thumb switch plate to thumb matrix.
  thumbPlate.properties.thumbMatrixConnector = new CSG.Connector(
    thumbMatrix[0][0].keySwitch.properties.center.point,
    [0, 0, 1],
    [0, 1, 0]
  );
  // Adjust the spacer first so that we don't use the updated proerty.
  // While the space is at a different Z coordinate, the two connectors
  // used have identical Z coordinates, so the transformation is sound.
  thumbInteriorCutout = thumbInteriorCutout.connectTo(
    thumbPlate.properties.thumbMatrixConnector,
    thumbMatrix[0][0].keySwitch.properties.center,
    false,
    0
  );
  thumbPlate = thumbPlate.connectTo(
    thumbPlate.properties.thumbMatrixConnector,
    thumbMatrix[0][0].keySwitch.properties.center,
    false,
    0
  );

  var switches = [];
  var matrices = [primaryMatrix, thumbMatrix];
  for (var h = 0; h < matrices.length; ++h) {
    var matrix = matrices[h];
    for (var i = 0; i < matrix.length; ++i) {
      var row = matrix[i];
      for (var j = 0; j < row.length; ++j) {
        if (row[j].present) {
          switches.push(row[j].keySwitch);
        }
      }
    }
  }

  var fullPlate = primaryPlate.union(thumbPlate);
  var fullInteriorCutout = primaryInteriorCutout.union(thumbInteriorCutout);
  var fullSpacer = fullPlate.subtract(fullInteriorCutout);

  var switchPlate = fullPlate;
  for (var i = 0; i < switches.length; ++i) {
    var keySwitch = switches[i];
    var switchBounds = keySwitch.getBounds();
    keySwitch = keySwitch.translate([0, 0, -switchBounds[0].z]);
    switchPlate = switchPlate.subtract(keySwitch);
  }

  return switchPlate.translate([0, 0, SWITCH_PLATE_THICKNESS]).union(fullSpacer);
}

function main() {
  return switchPlateLeftHand();
}

<|endoftext|>


<commit_before>module.exports = {
  '-1' : 'system busy, retry later',
  0    : 'success',
  1    : 'internal error, contact us',

  10001: 'require appKey',
  10002: 'require appSecret',
  10003: 'require deviceId',
  10004: 'invalid appKey',
  10005: 'invalid appSecret',
  10006: 'failed to create/update device, contact us',
  10007: 'invalid token',
  10008: 'token is expired',
  10009: 'failed to generate token, contact us',
  10010: 'require token',
  10011: 'require uploaded data file',
  11001: 'require username',
  11002: 'require password',
  11003: 'user not exist',
  11004: 'password not match',
  11005: 'failed to generate token, contact us',
  11006: 'failed to create user',
  11007: 'failed to hash password',
  11008: 'failed to save user, please check if required field is correct',
  11009: 'failed to save file',
  11010: 'failed to delete file',
  11011: 'file not exist',
  11012: 'error when read file',
  11013: 'failed to create poi import task',
  11014: 'require clientKey',
  11015: 'require clientSecret',
  11016: 'client not exist',
  11017: 'invalid clientKey',
  11018: 'invalid clientSecret',
  40001: 'failed to create device, contact us',
  40002: 'failed to get created device, contact us',
  40003: 'failed to update device, contact us',
  40004: 'failed to get updated device, contact us',
  40005: 'failed to queue poi import job',
  40006: 'failed to find regions',
  40007: 'failed to find pois'
};<commit_msg>remove a unused error code<commit_after>module.exports = {
  '-1' : 'system busy, retry later',
  0    : 'success',
  1    : 'internal error, contact us',

  10001: 'require appKey',
  10002: 'require appSecret',
  10003: 'require deviceId',
  10004: 'invalid appKey',
  10005: 'invalid appSecret',
  10006: 'failed to create/update device, contact us',
  10007: 'invalid token',
  10008: 'token is expired',
  10009: 'failed to generate token, contact us',
  10010: 'require token',
  10011: 'require uploaded data file',
  11001: 'require username',
  11002: 'require password',
  11003: 'user not exist',
  11004: 'password not match',
  11005: 'failed to generate token, contact us',
  11006: 'failed to create user',
  11007: 'failed to hash password',
  11008: 'failed to save user, please check if required field is correct',
  11009: 'failed to save file',
  11010: 'failed to delete file',
  11011: 'file not exist',
  11012: 'error when read file',
  11013: 'failed to create poi import task',
  11014: 'require clientKey',
  11015: 'require clientSecret',
  11016: 'client not exist',
  11017: 'invalid clientKey',
  11018: 'invalid clientSecret',
  40001: 'failed to create device, contact us',
  40002: 'failed to get device, contact us',
  40003: 'failed to update device, contact us',
  //40004: 'failed to get updated device, contact us',
  40005: 'failed to queue poi import job',
  40006: 'failed to find regions',
  40007: 'failed to find pois'
};
<|endoftext|>


<commit_before>var fs             = require('fs');
var path           = require('path');
var callerPath     = require('caller');
var mockRequire    = require('mock-require');
var findModuleDeps = require('find-module-deps');

function isModuleNotFoundError(e){
    return e.code && e.code === 'MODULE_NOT_FOUND';
}

function isExternalModule(path) {
    return /[\/\\]node_modules[\/\\]/.test(path);
}

function isLocalModule(path) {
    return /^\.{1,2}[\/\\]/.test(path);
}

function isSystemModule(path) {
    return /^[^.\/\\]/.test(path);
}

function getFullPath(modulePath, calledFrom) {
    var resolvedPath;
    try {
        resolvedPath = require.resolve(modulePath);
    } catch(e) { }

    var isSystemModule = resolvedPath === modulePath;

    if (isExternalModule(resolvedPath) || isSystemModule) {
        return resolvedPath;
    }

    if (!isLocalModule(modulePath)) {
        return modulePath;
    }

    var localModuleName = path.join(path.dirname(calledFrom), modulePath);

    try {
        return require.resolve(localModuleName);
    } catch (e) {
        if (isModuleNotFoundError(e)) { return localModuleName; }
        else { throw e; }
    }
}

/**
 * @param {String} modulePath
 * @param {Object} [options]
 * @param {Object}   [mocks] - map of mocks of module dependencies as {'module_dependency_path': 'mock_path'}.
 *                           You can use object or function instead of 'mock_path'
 * @param {Boolean}  [pristine] - clean npm cache before loading
 * @param {Boolean}  [deep] - clean npm cache for submodules
 *
 * @returns {*} module
 */
function requireMe(modulePath, options) {
    options = options || {};

    var mocks = options.mocks || {};
    var pristine = options.pristine;
    var deep = options.deep;

    var calledFrom = callerPath();
    var fullModulePath = getFullPath(modulePath, calledFrom);
    var mocksArr = Object.keys(mocks).map(function(path) {
        return {
            path: getFullPath(path, calledFrom),
            value: typeof mocks[path] === 'string' ? getFullPath(mocks[path], calledFrom) : mocks[path]
        };
    });

    if (pristine) {
        if (deep && !(isExternalModule(fullModulePath) || isSystemModule(fullModulePath))) {
            var moduleCode = fs.readFileSync(fullModulePath);
            var deps = findModuleDeps(moduleCode) || [];

            deps.forEach(function(localPath) {
                var childPath = getFullPath(localPath, fullModulePath);

                requireMe(childPath, {pristine: true, deep: true})
            });
        }

        delete require.cache[require.resolve(fullModulePath)];
    }

    mocksArr.forEach(function(mock) {
        mockRequire(mock.path, mock.value);
    });

    return require(fullModulePath);
}

module.exports = requireMe;<commit_msg>stop mocking when module was required<commit_after>var fs             = require('fs');
var path           = require('path');
var callerPath     = require('caller');
var mockRequire    = require('mock-require');
var findModuleDeps = require('find-module-deps');

function isModuleNotFoundError(e){
    return e.code && e.code === 'MODULE_NOT_FOUND';
}

function isExternalModule(path) {
    return /[\/\\]node_modules[\/\\]/.test(path);
}

function isLocalModule(path) {
    return /^\.{1,2}[\/\\]/.test(path);
}

function isSystemModule(path) {
    return /^[^.\/\\]/.test(path);
}

function getFullPath(modulePath, calledFrom) {
    var resolvedPath;
    try {
        resolvedPath = require.resolve(modulePath);
    } catch(e) { }

    var isSystemModule = resolvedPath === modulePath;

    if (isExternalModule(resolvedPath) || isSystemModule) {
        return resolvedPath;
    }

    if (!isLocalModule(modulePath)) {
        return modulePath;
    }

    var localModuleName = path.join(path.dirname(calledFrom), modulePath);

    try {
        return require.resolve(localModuleName);
    } catch (e) {
        if (isModuleNotFoundError(e)) { return localModuleName; }
        else { throw e; }
    }
}

/**
 * @param {String} modulePath
 * @param {Object} [options]
 * @param {Object}   [mocks] - map of mocks of module dependencies as {'module_dependency_path': 'mock_path'}.
 *                           You can use object or function instead of 'mock_path'
 * @param {Boolean}  [pristine] - clean npm cache before loading
 * @param {Boolean}  [deep] - clean npm cache for submodules
 *
 * @returns {*} module
 */
function requireMe(modulePath, options) {
    options = options || {};

    var mocks = options.mocks || {};
    var pristine = options.pristine;
    var deep = options.deep;

    var calledFrom = callerPath();
    var fullModulePath = getFullPath(modulePath, calledFrom);
    var mocksArr = Object.keys(mocks).map(function(path) {
        return {
            path: getFullPath(path, calledFrom),
            value: typeof mocks[path] === 'string' ? getFullPath(mocks[path], calledFrom) : mocks[path]
        };
    });

    if (pristine) {
        if (deep && !(isExternalModule(fullModulePath) || isSystemModule(fullModulePath))) {
            var moduleCode = fs.readFileSync(fullModulePath);
            var deps = findModuleDeps(moduleCode) || [];

            deps.forEach(function(localPath) {
                var childPath = getFullPath(localPath, fullModulePath);

                requireMe(childPath, {pristine: true, deep: true})
            });
        }

        delete require.cache[require.resolve(fullModulePath)];
    }

    mocksArr.forEach(function(mock) {
        mockRequire(mock.path, mock.value);
    });

    const requiredModule = require(fullModulePath);

    mocksArr.forEach(function(mock) {
        mockRequire.stop(mock.path);
    });

    return requiredModule;
}

module.exports = requireMe;<|endoftext|>


<commit_before>import React from 'react';

import {
  StyleSheet,
  View,
  Text,
  DeviceEventEmitter,
  ActivityIndicator
} from 'react-native';

const styles = StyleSheet.create({
  container: {
    position: 'absolute',
    backgroundColor: 'rgba(0,0,0,0.3)',
    justifyContent: 'center',
    alignItems: 'center',
    top: 0,
    bottom: 0,
    left: 0,
    right: 0,
    flex: 1
  },
  progressBar: {
    margin: 10,
    justifyContent: 'center',
    alignItems: 'center',
    padding: 10
  }
});

const BusyIndicator = React.createClass({
  propTypes: {
    color: React.PropTypes.string,
    overlayColor: React.PropTypes.string,
    overlayHeight: React.PropTypes.number,
    overlayWidth: React.PropTypes.number,
    startVisible: React.PropTypes.bool,
    text: React.PropTypes.string,
    textColor: React.PropTypes.string,
    textFontSize: React.PropTypes.number
  },

  getDefaultProps() {
    return {
      isDismissible: false,
      overlayWidth: 120,
      overlayHeight: 100,
      overlayColor: '#333333',
      color: '#f5f5f5',
      startVisible: false,
      text: 'Please wait...',
      textColor: '#f5f5f5',
      textFontSize: 14
    };
  },

  getInitialState() {
    return {
      isVisible: this.props.startVisible
    };
  },
  componentDidMount () {
    this.emitter = DeviceEventEmitter.addListener('changeLoadingEffect', this.changeLoadingEffect, null);
  },

  componentWillUnmount() {
    this.emitter.remove();
  },

  changeLoadingEffect(state) {
    this.setState({
      isVisible: state.isVisible,
      text: state.title ? state.title : 'Please wait...'
    });
  },

  render() {
    const customStyles = StyleSheet.create({
      overlay: {
        alignItems: 'center',
        justifyContent: 'center',
        borderRadius: 10,
        padding: 10,
        backgroundColor: this.props.overlayColor,
        width: this.props.overlayWidth,
        height: this.props.overlayHeight
      },
      text: {
        color: this.props.textColor,
        fontSize: this.props.textFontSize,
        marginTop: 8
      }
    });

    if (!this.state.isVisible) {
      return (<View />);
    } else {
      return (
        <View style={[styles.container]}>
          <View style={customStyles.overlay}>
            <ActivityIndicator
              color={this.props.color}
              size="small"
              style={styles.progressBar}/>
            <Text numberOfLines={1} style={customStyles.text}>
              {this.state.text}
            </Text>
          </View>
        </View>
      );
    }
  }
});

module.exports = BusyIndicator;
<commit_msg>fixed weird ui bug that tore up ui on hiding of load handler<commit_after>import React from 'react';

import {
  StyleSheet,
  View,
  Text,
  DeviceEventEmitter,
  ActivityIndicator
} from 'react-native';
const styles_bi = StyleSheet.create({
  container: {
    position: 'absolute',
    backgroundColor: 'rgba(0,0,0,0.3)',
    justifyContent: 'center',
    alignItems: 'center',
    top: 0,
    bottom: 0,
    left: 0,
    right: 0,
    flex: 1
  },
  progressBar: {
    margin: 10,
    justifyContent: 'center',
    alignItems: 'center',
    padding: 10
  },
  nocontainer: {
    position: 'absolute',
    //backgroundColor: 'rgba(0,0,0,0.6)',
    //justifyContent: 'center',
    //alignItems: 'center',
    top: 0,
    //bottom: 0,
    left: 0,
    //right: 0,
    //flex: 0,
    width:0.001,
    height:0.001
  },
});

const BusyIndicator = React.createClass({
  propTypes: {
    color: React.PropTypes.string,
    overlayColor: React.PropTypes.string,
    overlayHeight: React.PropTypes.number,
    overlayWidth: React.PropTypes.number,
    startVisible: React.PropTypes.bool,
    text: React.PropTypes.string,
    textColor: React.PropTypes.string,
    textFontSize: React.PropTypes.number
  },

  getDefaultProps() {
    return {
      isDismissible: false,
      overlayWidth: 120,
      overlayHeight: 100,
      overlayColor: '#333333',
      color: '#f5f5f5',
      startVisible: false,
      text: 'Please wait...',
      textColor: '#f5f5f5',
      textFontSize: 14
    };
  },

  getInitialState() {
    return {
      isVisible: this.props.startVisible
    };
  },
  componentDidMount () {
    this.emitter = DeviceEventEmitter.addListener('changeLoadingEffect', this.changeLoadingEffect, null);
  },

  componentWillUnmount() {
    this.emitter.remove();
  },

  changeLoadingEffect(state) {
    this.setState({
      isVisible: state.isVisible,
      text: state.title ? state.title : 'Please wait...'
    });
  },

  render() {
    const customStyles = StyleSheet.create({
      overlay: {
        alignItems: 'center',
        justifyContent: 'center',
        borderRadius: 10,
        padding: 10,
        backgroundColor: this.props.overlayColor,
        width: this.props.overlayWidth,
        height: this.props.overlayHeight
      },
      text: {
        color: this.props.textColor,
        fontSize: this.props.textFontSize,
        marginTop: 8
      }
    });

    if (!this.state.isVisible) {
      return (<View style={[styles_bi.nocontainer]} />);
    } else {
      return (
        <View style={[styles_bi.container]}>
          <View style={customStyles.overlay}>
            <ActivityIndicator
              color={this.props.color}
              size="small"
              style={styles_bi.progressBar}/>
            <Text numberOfLines={1} style={customStyles.text}>
              {this.state.text}
            </Text>
          </View>
        </View>
      );
    }
  }
});
module.exports = BusyIndicator;
<|endoftext|>


<commit_before>var _ = require('lodash')
  , Ribcage
  , extendView;

Ribcage = {
  initialize: function (opts) {

    var tn = this.templateName;

    // if we need to load data before rendering, do it
    if (typeof this.loadData == 'function') {
      this._dataLoaded = false
    }
    // otherwise, assume we have the data already
    else {
      this._dataLoaded = true
    }

    if(this.beforeInit) {
      this.beforeInit(opts);
    }

    this.template = this.template || opts.template;

    if (!this.template) {
      this.template = function () { return ''; };
    }

    if (this.afterInit) {
      this.afterInit(opts);
    }

    this.render();

  }

, context: function () {
    return _.extend({}, this.options, this.model);
  }

, close: function() {

    if (this.beforeClose) {
      this.beforeClose();
    }

    this.closeSubviews();
    this.off();
    this.remove();

  }

, render: function () {
    var self = this
      , model = this.model;

    if (!this._dataLoaded) {
      return this.loadData(this.render)
    }

    if (this.beforeRender) {
      this.beforeRender();
    }

    this.closeSubviews();
    this.$el.empty();

    if (this.beforeTemplating) {
      model = this.beforeTemplating();
    }

    if (this.context) {
      model = this.context();
    }

    this.$el.html(this.template(model));

    // I'm not happy deferring here, but backbone's
    // event system is based on the DOM, so my hands
    // are tied. - Daniel
    _.defer(function () {
      self.trigger('afterRender')
    });

    if (this.afterRender) {
      this.afterRender();
    }

    return this;

  }

, proxy: function (name, view) {
    var self = this;
    view.on(name, function () {
      var args = Array.prototype.slice.call(arguments, 0);
      args.splice(0, 0, name);
      self.trigger.apply(self, args);
    });
  }

, eachSubview: function(iterator) {
    _.each(this.subviews, iterator);
  }

, appendSubview: function(view, el) {
    el || (el = this.$el);

    this.subviews = this.subviews || {};
    this.subviews[view.cid] = view;
    el.append(view.el);

    _.defer(function () {
      view.trigger('afterAppend');
    });

    if (view.afterAppend) {
      view.afterAppend();
    }

  }

, closeSubviews: function() {

    this.eachSubview(function(subview) {
      subview.close();
    });

    this.subviews = {};

  }

, detachSubview: function(view) {

    if (this.subviews) {
      delete this.subviews[view.cid];
    }

    view.$el.detach();

  }
};

extendView = function (view) {
  return view.extend(Ribcage);
};

module.exports = extendView;
<commit_msg>Fix undefined function loadData<commit_after>var _ = require('lodash')
  , Ribcage
  , extendView;

Ribcage = {
  initialize: function (opts) {

    var tn = this.templateName;

    // if we need to load data before rendering, do it
    if (typeof this.loadData == 'function') {
      this._dataLoaded = false
    }
    // otherwise, assume we have the data already
    else {
      this._dataLoaded = true
    }

    if(this.beforeInit) {
      this.beforeInit(opts);
    }

    this.template = this.template || opts.template;

    if (!this.template) {
      this.template = function () { return ''; };
    }

    if (this.afterInit) {
      this.afterInit(opts);
    }

    this.render();

  }

, context: function () {
    return _.extend({}, this.options, this.model);
  }

, close: function() {

    if (this.beforeClose) {
      this.beforeClose();
    }

    this.closeSubviews();
    this.off();
    this.remove();

  }

, render: function () {
    var self = this
      , model = this.model;

    if (!this._dataLoaded && typeof this.loadData == 'function') {
      return this.loadData(this.render)
    }

    if (this.beforeRender) {
      this.beforeRender();
    }

    this.closeSubviews();
    this.$el.empty();

    if (this.beforeTemplating) {
      model = this.beforeTemplating();
    }

    if (this.context) {
      model = this.context();
    }

    this.$el.html(this.template(model));

    // I'm not happy deferring here, but backbone's
    // event system is based on the DOM, so my hands
    // are tied. - Daniel
    _.defer(function () {
      self.trigger('afterRender')
    });

    if (this.afterRender) {
      this.afterRender();
    }

    return this;

  }

, proxy: function (name, view) {
    var self = this;
    view.on(name, function () {
      var args = Array.prototype.slice.call(arguments, 0);
      args.splice(0, 0, name);
      self.trigger.apply(self, args);
    });
  }

, eachSubview: function(iterator) {
    _.each(this.subviews, iterator);
  }

, appendSubview: function(view, el) {
    el || (el = this.$el);

    this.subviews = this.subviews || {};
    this.subviews[view.cid] = view;
    el.append(view.el);

    _.defer(function () {
      view.trigger('afterAppend');
    });

    if (view.afterAppend) {
      view.afterAppend();
    }

  }

, closeSubviews: function() {

    this.eachSubview(function(subview) {
      subview.close();
    });

    this.subviews = {};

  }

, detachSubview: function(view) {

    if (this.subviews) {
      delete this.subviews[view.cid];
    }

    view.$el.detach();

  }
};

extendView = function (view) {
  return view.extend(Ribcage);
};

module.exports = extendView;
<|endoftext|>


<commit_before>var util = require('./lib/util')
	, mkdirp = require('mkdirp')
	, _ = require('underscore')
	, path = require('path');

/** Function: defaultPathBuilder
 * This function builds paths for a screenshot file. It is appended to the
 * constructors base directory and gets prependend with `.png` or `.json` when
 * storing a screenshot or JSON meta data file.
 *
 * Parameters:
 *     (Object) spec - The spec currently reported
 *     (Array) descriptions - The specs and their parent suites descriptions
 *     (Object) result - The result object of the current test spec.
 *     (Object) capabilities - WebDrivers capabilities object containing
 *                             in-depth information about the Selenium node
 *                             which executed the test case.
 *
 * Returns:
 *     (String) containing the built path
 */
function defaultPathBuilder(spec, descriptions, results, capabilities) {
	return util.generateGuid();
}

/** Function: defaultMetaDataBuilder
 * Uses passed information to generate a meta data object which can be saved
 * along with a screenshot.
 * You do not have to add the screenshots file path since this will be appended
 * automatially.
 *
 * Parameters:
 *     (Object) spec - The spec currently reported
 *     (Array) descriptions - The specs and their parent suites descriptions
 *     (Object) result - The result object of the current test spec.
 *     (Object) capabilities - WebDrivers capabilities object containing
 *                             in-depth information about the Selenium node
 *                             which executed the test case.
 *
 * Returns:
 *     (Object) containig meta data to store along with a screenshot
 */
function defaultMetaDataBuilder(spec, descriptions, results, capabilities) {
	var passed = spec.passedExpectations
		, failed = spec.failedExpectations;

	var metaData = {
			description: descriptions.join(' ')
			, passed: _.every(passed.concat(failed), function(it){return it.passed})
			, os: capabilities.caps_.platform
			, browser: {
				name: capabilities.caps_.browserName
				, version: capabilities.caps_.version
			}
		};

	if(passed.length > 0 || failed.length > 0) {
		var result = passed[0];

		if(failed.length > 0) {
			var messages = _.pluck(failed, 'message'),
			      stacks = _.pluck(failed, 'stack');

			//report all failures
			metaData.message = messages.length && messages.join('\n') || 'Failed';
			metaData.trace = stacks.length && stacks.join('\n') || 'No Stack trace information';

		} else {
			metaData.message = result && result.message || 'Passed';
			metaData.trace = result && result.stack;
		}
	}

	return metaData;
}

/** Class: ScreenshotReporter
 * Creates a new screenshot reporter using the given `options` object.
 *
 * For more information, please look at the README.md file.
 *
 * Parameters:
 *     (Object) options - Object with options as described below.
 *
 * Possible options:
 *     (String) baseDirectory - The path to the directory where screenshots are
 *                              stored. If not existing, it gets created.
 *                              Mandatory.
 *     (Function) pathBuilder - A function which returns a path for a screenshot
 *                              to be stored. Optional.
 *     (Function) metaDataBuilder - Function which returns an object literal
 *                                  containing meta data to store along with
 *                                  the screenshot. Optional.
 *     (Boolean) takeScreenShotsForSkippedSpecs - Do you want to capture a
 *                                                screenshot for a skipped spec?
 *                                                Optional (default: false).
 */
function ScreenshotReporter(options) {
	options = options || {};
	if(!options.baseDirectory || options.baseDirectory.length === 0) {
		throw new Error('Please pass a valid base directory to store the ' +
			'screenshots into.');
	} else {
		this.baseDirectory = options.baseDirectory;
	}

	if(typeof (options.cssOverrideFile) !== 'undefined' && _.isString(options.cssOverrideFile) ){
		this.cssOverrideFile = options.cssOverrideFile;
	} else {
		this.cssOverrideFile = null;
	}

	this.pathBuilder = options.pathBuilder || defaultPathBuilder;
	this.docTitle = options.docTitle || 'Generated test report';
	this.docName = options.docName || 'report.html';
	this.metaDataBuilder = options.metaDataBuilder || defaultMetaDataBuilder;
	this.preserveDirectory = options.preserveDirectory || false;
	this.takeScreenShotsForSkippedSpecs =
		options.takeScreenShotsForSkippedSpecs || false;
		this.takeScreenShotsOnlyForFailedSpecs =
 		options.takeScreenShotsOnlyForFailedSpecs || false;
 	this.finalOptions = {
 		takeScreenShotsOnlyForFailedSpecs: this.takeScreenShotsOnlyForFailedSpecs,
 		takeScreenShotsForSkippedSpecs: this.takeScreenShotsForSkippedSpecs,
 		metaDataBuilder: this.metaDataBuilder,
 		pathBuilder: this.pathBuilder,
 		baseDirectory: this.baseDirectory,
 		docTitle: this.docTitle,
 		docName: this.docName,
 		cssOverrideFile: this.cssOverrideFile
 	};

 	if(!this.preserveDirectory){
 		util.removeDirectory(this.finalOptions.baseDirectory);
 	}
}

var currentSuite, currentSpec;
ScreenshotReporter.prototype.jasmineStarted = function () {
    //console.log("##test[progressStart 'Running Jasmine Tests']");
};

ScreenshotReporter.prototype.jasmineDone = function () {
    //console.log("##test[progressFinish 'Running Jasmine Tests']");
};

ScreenshotReporter.prototype.suiteStarted = function (suite) {
	currentSuite = suite;
    //console.log("##START[testSuiteStarted name='" + (suite.fullName) + "']");
};

ScreenshotReporter.prototype.suiteDone = function (suite) {
    //console.log("##test[testSuiteFinished name='" + (suite.fullName) + "']");
};

ScreenshotReporter.prototype.specStarted = function (spec) {
	currentSpec = spec;
    //console.log("##START[testStarted name='" + (spec.description) + "' captureStandardOutput='true']");
};

ScreenshotReporter.prototype.specDone = function (spec) {
    //console.log("##test[testFinished name='" + (spec.description) + "']");

    /** Function: specDone
     * Called by Jasmine when a test spec is done. It triggers the
     * whole screenshot capture process and stores any relevant information.
     *
     * Parameters:
     *     (Object) spec - The test spec to report.
     */

    var self = this, results = spec;
    if(!self.takeScreenShotsForSkippedSpecs && results.skipped) {
    	return;
    }

    browser.takeScreenshot().then(function (png) {
    	browser.getCapabilities().then(function (capabilities) {
    		var descriptions = util.gatherDescriptions(
    				currentSuite
    				, [spec.description]
    			)

    			, baseName = self.pathBuilder(
    				spec
    				, descriptions
    				, results
    				, capabilities
    			)
    			, metaData = self.metaDataBuilder(
    				spec
    				, descriptions
    				, results
    				, capabilities
    			)

    			, screenShotFile = baseName + '.png'
    			, metaFile = baseName + '.json'
    			, screenShotPath = path.join(self.baseDirectory, screenShotFile)
    			, metaDataPath = path.join(self.baseDirectory, metaFile)

    			// pathBuilder can return a subfoldered path too. So extract the
    			// directory path without the baseName
    			, directory = path.dirname(screenShotPath);

    		metaData.screenShotFile = screenShotFile;
    		mkdirp(directory, function(err) {
    			if(err) {
    				throw new Error('Could not create directory ' + directory);
    			} else {
    				util.addMetaData(metaData, metaDataPath, descriptions, self.finalOptions);
    				if(!(self.takeScreenShotsOnlyForFailedSpecs && results.passedExpectations)) {
    					util.storeScreenShot(png, screenShotPath);
    				}
    				util.storeMetaData(metaData, metaDataPath);
    			}
    		});
    	});
    });
};

module.exports = ScreenshotReporter;
<commit_msg>Fixed issues with using takeScreenShotsOnlyForFailedSpecs flag and issues with wrong suite naming<commit_after>var util = require('./lib/util')
	, mkdirp = require('mkdirp')
	, _ = require('underscore')
	, path = require('path');

/** Function: defaultPathBuilder
 * This function builds paths for a screenshot file. It is appended to the
 * constructors base directory and gets prependend with `.png` or `.json` when
 * storing a screenshot or JSON meta data file.
 *
 * Parameters:
 *     (Object) spec - The spec currently reported
 *     (Array) descriptions - The specs and their parent suites descriptions
 *     (Object) result - The result object of the current test spec.
 *     (Object) capabilities - WebDrivers capabilities object containing
 *                             in-depth information about the Selenium node
 *                             which executed the test case.
 *
 * Returns:
 *     (String) containing the built path
 */
function defaultPathBuilder(spec, descriptions, results, capabilities) {
	return util.generateGuid();
}

/** Function: defaultMetaDataBuilder
 * Uses passed information to generate a meta data object which can be saved
 * along with a screenshot.
 * You do not have to add the screenshots file path since this will be appended
 * automatially.
 *
 * Parameters:
 *     (Object) spec - The spec currently reported
 *     (Array) descriptions - The specs and their parent suites descriptions
 *     (Object) result - The result object of the current test spec.
 *     (Object) capabilities - WebDrivers capabilities object containing
 *                             in-depth information about the Selenium node
 *                             which executed the test case.
 *
 * Returns:
 *     (Object) containig meta data to store along with a screenshot
 */
function defaultMetaDataBuilder(spec, descriptions, results, capabilities) {
	var passed = spec.passedExpectations
		, failed = spec.failedExpectations;

	var metaData = {
			description: descriptions.join(' ')
			, passed: _.every(passed.concat(failed), function(it){return it.passed})
			, os: capabilities.caps_.platform
			, browser: {
				name: capabilities.caps_.browserName
				, version: capabilities.caps_.version
			}
		};

	if(passed.length > 0 || failed.length > 0) {
		var result = passed[0];

		if(failed.length > 0) {
			var messages = _.pluck(failed, 'message'),
			      stacks = _.pluck(failed, 'stack');

			//report all failures
			metaData.message = messages.length && messages.join('\n') || 'Failed';
			metaData.trace = stacks.length && stacks.join('\n') || 'No Stack trace information';

		} else {
			metaData.message = result && result.message || 'Passed';
			metaData.trace = result && result.stack;
		}
	}

	return metaData;
}

/** Class: ScreenshotReporter
 * Creates a new screenshot reporter using the given `options` object.
 *
 * For more information, please look at the README.md file.
 *
 * Parameters:
 *     (Object) options - Object with options as described below.
 *
 * Possible options:
 *     (String) baseDirectory - The path to the directory where screenshots are
 *                              stored. If not existing, it gets created.
 *                              Mandatory.
 *     (Function) pathBuilder - A function which returns a path for a screenshot
 *                              to be stored. Optional.
 *     (Function) metaDataBuilder - Function which returns an object literal
 *                                  containing meta data to store along with
 *                                  the screenshot. Optional.
 *     (Boolean) takeScreenShotsForSkippedSpecs - Do you want to capture a
 *                                                screenshot for a skipped spec?
 *                                                Optional (default: false).
 */
function ScreenshotReporter(options) {
	options = options || {};
	if(!options.baseDirectory || options.baseDirectory.length === 0) {
		throw new Error('Please pass a valid base directory to store the ' +
			'screenshots into.');
	} else {
		this.baseDirectory = options.baseDirectory;
	}

	if(typeof (options.cssOverrideFile) !== 'undefined' && _.isString(options.cssOverrideFile) ){
		this.cssOverrideFile = options.cssOverrideFile;
	} else {
		this.cssOverrideFile = null;
	}

	this.pathBuilder = options.pathBuilder || defaultPathBuilder;
	this.docTitle = options.docTitle || 'Generated test report';
	this.docName = options.docName || 'report.html';
	this.metaDataBuilder = options.metaDataBuilder || defaultMetaDataBuilder;
	this.preserveDirectory = options.preserveDirectory || false;
	this.takeScreenShotsForSkippedSpecs =
		options.takeScreenShotsForSkippedSpecs || false;
		this.takeScreenShotsOnlyForFailedSpecs =
 		options.takeScreenShotsOnlyForFailedSpecs || false;
 	this.finalOptions = {
 		takeScreenShotsOnlyForFailedSpecs: this.takeScreenShotsOnlyForFailedSpecs,
 		takeScreenShotsForSkippedSpecs: this.takeScreenShotsForSkippedSpecs,
 		metaDataBuilder: this.metaDataBuilder,
 		pathBuilder: this.pathBuilder,
 		baseDirectory: this.baseDirectory,
 		docTitle: this.docTitle,
 		docName: this.docName,
 		cssOverrideFile: this.cssOverrideFile
 	};

 	if(!this.preserveDirectory){
 		util.removeDirectory(this.finalOptions.baseDirectory);
 	}
}

var currentSuite, currentSpec;
ScreenshotReporter.prototype.jasmineStarted = function () {
    //console.log("##test[progressStart 'Running Jasmine Tests']");
};

ScreenshotReporter.prototype.jasmineDone = function () {
    //console.log("##test[progressFinish 'Running Jasmine Tests']");
};

ScreenshotReporter.prototype.suiteStarted = function (suite) {
	currentSuite = suite;
    //console.log("##START[testSuiteStarted name='" + (suite.fullName) + "']");
};

ScreenshotReporter.prototype.suiteDone = function (suite) {
    //console.log("##test[testSuiteFinished name='" + (suite.fullName) + "']");
};

ScreenshotReporter.prototype.specStarted = function (spec) {
	currentSpec = spec;
    //console.log("##START[testStarted name='" + (spec.description) + "' captureStandardOutput='true']");
};

ScreenshotReporter.prototype.specDone = function (spec) {
    //console.log("##test[testFinished name='" + (spec.description) + "']");

    /** Function: specDone
     * Called by Jasmine when a test spec is done. It triggers the
     * whole screenshot capture process and stores any relevant information.
     *
     * Parameters:
     *     (Object) spec - The test spec to report.
     */

    var self = this, results = spec, suite = currentSuite;
    if(!self.takeScreenShotsForSkippedSpecs && results.skipped) {
    	return;
    }

    browser.takeScreenshot().then(function (png) {
    	browser.getCapabilities().then(function (capabilities) {
    		var descriptions = util.gatherDescriptions(
    				suite
    				, [results.description]
    			)

    			, baseName = self.pathBuilder(
    				spec
    				, descriptions
    				, results
    				, capabilities
    			)
    			, metaData = self.metaDataBuilder(
    				spec
    				, descriptions
    				, results
    				, capabilities
    			)

    			, screenShotFile = baseName + '.png'
    			, metaFile = baseName + '.json'
    			, screenShotPath = path.join(self.baseDirectory, screenShotFile)
    			, metaDataPath = path.join(self.baseDirectory, metaFile)

    			// pathBuilder can return a subfoldered path too. So extract the
    			// directory path without the baseName
    			, directory = path.dirname(screenShotPath);

    		metaData.screenShotFile = screenShotFile;
    		mkdirp(directory, function(err) {
    			if(err) {
    				throw new Error('Could not create directory ' + directory);
    			} else {
    				util.addMetaData(metaData, metaDataPath, descriptions, self.finalOptions);
    				if(!(self.takeScreenShotsOnlyForFailedSpecs && results.failedExpectations.length === 0)) {
    					util.storeScreenShot(png, screenShotPath);
    				}
    				util.storeMetaData(metaData, metaDataPath);
    			}
    		});
    	});
    });
};

module.exports = ScreenshotReporter;
<|endoftext|>


<commit_before>//Global vars for Everyone
//Init Display
var w = 70;
var h = 25;
var display = new ROT.Display({spacing:1.4, width: w, height: h});
var map = {};

var socket = io.connect(window.location.origin);

var actors = {};
var freeCells;
var master;

var name;
var color;
//Things only used by Session 0
var scheduler;
var engine;

var currentTurn;

var init = function (){
	name = document.forms[0].name.value;
	color = document.forms[0].color.value;
	master = (document.forms[0].master.value == "yes")? true : false;

	document.forms[0].style.display = "none";
	document.getElementById("GameArea").appendChild(display.getContainer());
    document.getElementById("Selected").innerHTML = "Selected: ";
    document.getElementById("GameData").style.display = "inline-block";

	if(master){
		masterSockets();
		createMap();

	    socket.emit('updateMap&Actors',{map : map, actors : actors, freeCells: freeCells});

        scheduler = new ROT.Scheduler.Simple();
        scheduler.add(actors["player"],true);
        scheduler.add(actors["cat"],true);
        engine = new ROT.Engine(scheduler);
        engine.start();

	}else{
		clientSockets();
		socket.emit('player2init',"hi");
	}
};

var drawMap = function(){
	for (var key in this.map) {
        var parts = key.split(",");
        var x = parseInt(parts[0]);
        var y = parseInt(parts[1]);
        this.display.draw(x, y, this.map[key]);
    }
};
socket.on('finishedTurn',function(data){
    var x = actors[data.what].x;
    var y = actors[data.what].y;

    display.draw(x, y, map[x+","+y]);
    actors[data.what].update(data.newX, data.newY);

});
socket.on('playerLeft',function (data){
	actors[data].removeMe();
});
socket.on('AMLeft',function (data){
    while (document.body.firstChild) {
        document.body.removeChild(document.body.firstChild);
    };
    confirm("Rocks fall, everyone dies.");
});
var masterSockets = function (){
	socket.on('newPlayer',function (data){

	    actors[data.name] = new RemoteActor(data.x,data.y,data.rune,data.color,data.name);
	    scheduler.add(actors[data.name],true);
	});
	socket.on('yourTurn',function (data){
	    document.getElementById("WhoseTurn").innerHTML = "Current Turn: "+data.whoseTurn;
	    currentTurn = data.whoseTurn;
	});
    socket.on('monotheism',function (data){
        confirm("THERE CAN ONLY BE ONE!");
        document.body.innerHTML="";
        document.head.innerHTML="";
    });
};
var clientSockets = function (){
	socket.on('newPlayer',function (data){

	    if(data.name !== name)
	        actors[data.name] = new Actor(data.x,data.y,data.rune,data.color,data.name);
	});
	socket.on('yourTurn',function(data){
	    document.getElementById("WhoseTurn").innerHTML = "Current Turn: "+data.whoseTurn;
	    currentTurn = data.whoseTurn;
	    if(data.whoseTurn === name)
	        actors[name].act();

	});
	socket.on('initData',function (data){
		map = data.map;
		actors = data.actors;
		freeCells = data.freeCells;

		drawMap();

		for (actor in data.actors){
			actors[actor] = new Actor(data.actors[actor].x,data.actors[actor].y,data.actors[actor].rune,data.actors[actor].color,data.actors[actor].name);
		};

		var index = Math.floor(ROT.RNG.getUniform() * freeCells.length);
	    var key = freeCells.splice(index, 1)[0];
	    var parts = key.split(",");
	    var x = parseInt(parts[0]);
	    var y = parseInt(parts[1]);
		actors[name] = new Player2(x,y,color,name);
		socket.emit('newPlayer',actors[name]);

	});
};
var createMap = function(){
	var mapLayout = new ROT.Map.Digger(w,h,[3,15],0.9);//I don't seem to understand these last 2 arguments
	freeCells = [];

	mapLayout.create(function(x,y,what){

		if (what === 1) {
            display.draw(x,y,null,null,"#777");

            var key = x+","+y;
            //map[key] = "#";
            return;
        };
        var key = x+","+y;
        map[key] = ".";
        freeCells.push(key);
	}.bind(this));
	drawMap();
	actors["player"] = createCreature(Player, freeCells, name, color);
    actors["cat"] = createCreature(Cat, freeCells, "Sam", "tan");
};
var createCreature = function(what, freeCells, thisName, thisColor){
	var index = Math.floor(ROT.RNG.getUniform() * freeCells.length);
    var key = freeCells.splice(index, 1)[0];
    var parts = key.split(",");
    var x = parseInt(parts[0]);
    var y = parseInt(parts[1]);
    return new what(x, y, thisName, thisColor);
};
var Cat = function(xCoord,yCoord, thisName, thisColor){
    this.x = xCoord;
    this.y = yCoord;
    this.rune = "f";
    this.color = thisColor;
    this.name = thisName;

    this.draw = function(){
        display.draw(this.x,this.y,this.rune,this.color);
    };
    this.draw();
    this.act = function(){
        var ownerX = actors["player"].x;
        var ownerY = actors["player"].y;
        var newX;
        var newY;

        var passableCallback = function(x,y){
            return(x+","+y in map);
        };
        var aStar = new ROT.Path.AStar(ownerX,ownerY,passableCallback,{topology:8});

        var path = [];
        var pathCallback = function(x,y){
            path.push([x,y]);
        }
        aStar.compute(this.x,this.y,pathCallback);
        if(path.length <= 5){
            var randomDir = Math.floor(Math.random()*16);
            if(randomDir > 7) {return;}
            var diff = ROT.DIRS[8][randomDir];
            newX = this.x + diff[0];
            newY = this.y + diff[1];
            var newKey = newX + "," + newY;
            if (!(newKey in map)) { return; } // cannot move in this direction
            if(map[newKey] == "#"){ return; }    //Cannot move through walls (#s)
            if(newX === ownerX && newY === ownerY){return;};

        }else{
            path.shift();
            newX = path[0][0];
            newY = path[0][1];
        }
        socket.emit('somethingMoved',{what: "cat", newX : newX, newY : newY});
    };
    this.update = function(newX,newY){
        this.x = newX;
        this.y = newY;
        this.draw();
    };
};
var Player = function(xCoord, yCoord, thisName, thisColor) {
    this.x = xCoord;
    this.y = yCoord;
    this.rune = "@";
    this.color = thisColor;
    this.name = thisName;

    this.act = function(){

        engine.lock();

        socket.emit('yourTurn',{whoseTurn : this.name});
        window.addEventListener("keydown", this);

    };
    this.draw = function(){
        display.draw(this.x,this.y,this.rune,this.color);
    };
    this.draw();
    this.handleEvent = function(e){
        var keyMap = {};
        keyMap[38] = 0;
        keyMap[33] = 1;
        keyMap[39] = 2;
        keyMap[34] = 3;
        keyMap[40] = 4;
        keyMap[35] = 5;
        keyMap[37] = 6;
        keyMap[36] = 7;

        var code = e.keyCode;
        if(code === 12){
            engine.unlock();
            socket.emit('somethingMoved',{what: "player", newX : this.x, newY : this.y});
            return;
        }
        if (!(code in keyMap)) { return; }

        var diff = ROT.DIRS[8][keyMap[code]];
        var newX = this.x + diff[0];
        var newY = this.y + diff[1];

        var newKey = newX + "," + newY;
        if (!(newKey in map)) { return; } // cannot move in this direction
            else if(map[newKey] == "#"){return;}    //Cannot move through walls (#s)

        socket.emit('somethingMoved',{what: "player", newX : newX, newY : newY});

        window.removeEventListener("keydown", this);
/*
        var lightPasses = function(x,y){
            var key = x+","+y;
            if (key in map) {
                if(map[key] !== "#"){
                    return true;
                }
                return false;
            }
            return false;
        };
        var fov = new ROT.FOV.RecursiveShadowcasting(lightPasses);

        display.clear();
        fov.compute180(x, y, 10, keyMap[code], function(x, y, r, visibility) {
            var ch = (r ? map[x+","+y] : "@");
            var color = (map[x+","+y] ? "#aa0": "#660");
            display.draw(x, y, ch);
        });
*/

    };
    this.update = function(newX,newY){
        this.x = newX;
        this.y = newY;
        this.draw();
        if(master){
            engine.unlock();
        };

    };
};
var RemoteActor = function(xCoord,yCoord,rune,color,name){
    this.x = xCoord;
    this.y = yCoord;
    this.rune = rune;
    this.color = color;
    this.name = name;

    this.draw = function(){
        display.draw(this.x,this.y,this.rune,this.color);
    };
    this.draw();
    this.act = function(){

        engine.lock();
        socket.emit('yourTurn',{whoseTurn : this.name});
    };
    this.update = function(newX,newY){
        this.x = newX;
        this.y = newY;
        this.draw();
        engine.unlock();
    };
    this.removeMe = function (){
    	display.draw(this.x, this.y, map[this.x+","+this.y]);
    	console.log("Curr Turn: "+currentTurn+" & this.name: "+this.name);
    	if(currentTurn == this.name)
    		engine.unlock();

    	scheduler.remove(actors[this.name]);
    	delete actors[this.name];
    };
};
var Actor = function(xCoord,yCoord,rune,color,name){
    this.x = xCoord;
    this.y = yCoord;
    this.rune = rune;
    this.color = color;
    this.name = name;

    this.draw = function(){
        display.draw(this.x,this.y,this.rune,this.color);
    };
    this.draw();
    this.act = function(){};
    this.update = function(newX,newY){
        this.x = newX;
        this.y = newY;
        this.draw();
    };
    this.removeMe = function (){
    	display.draw(this.x, this.y, map[this.x+","+this.y]);
    	delete actors[this.name];
    };
};
var Player2 = function(xCoord, yCoord, color, name) {
    this.x = xCoord;
    this.y = yCoord;
    this.rune = "@";
    this.color = color;
    this.name = name;

    this.act = function(){
        //engine.lock();
        window.addEventListener("keydown", this);

    };
    this.draw = function(){
        display.draw(this.x,this.y,this.rune,this.color);
    };
    this.draw();
    this.handleEvent = function(e){
        var keyMap = {};
        keyMap[38] = 0;
        keyMap[33] = 1;
        keyMap[39] = 2;
        keyMap[34] = 3;
        keyMap[40] = 4;
        keyMap[35] = 5;
        keyMap[37] = 6;
        keyMap[36] = 7;

        var code = e.keyCode;
        if(code === 12){
            socket.emit('somethingMoved',{what: name, newX : this.x, newY : this.y});
            window.removeEventListener("keydown", this);
            return;
        }
        if (!(code in keyMap)) { return; }

        var diff = ROT.DIRS[8][keyMap[code]];
        var newX = this.x + diff[0];
        var newY = this.y + diff[1];

        var newKey = newX + "," + newY;
        if (!(newKey in map)) { return; } // cannot move in this direction
            else if(map[newKey] == "#"){return;}    //Cannot move through walls (#s)

        socket.emit('somethingMoved',{what: name, newX : newX, newY : newY});

        window.removeEventListener("keydown", this);
/*
        var lightPasses = function(x,y){
            var key = x+","+y;
            if (key in map) {
                if(map[key] !== "#"){
                    return true;
                }
                return false;
            }
            return false;
        };
        var fov = new ROT.FOV.RecursiveShadowcasting(lightPasses);

        display.clear();
        fov.compute180(x, y, 10, keyMap[code], function(x, y, r, visibility) {
            var ch = (r ? map[x+","+y] : "@");
            var color = (map[x+","+y] ? "#aa0": "#660");
            display.draw(x, y, ch);
        });
*/
        //engine.unlock();
    };
    this.update = function(newX,newY){
        this.x = newX;
        this.y = newY;
        this.draw();
    };
};

window.addEventListener("click",function (e){
    var clickCoOrd = display.eventToPosition(e);

    for(dude in actors){
        //console.log("actors"+actors[dude].x+","+actors[dude].y+" clickCoOrd:"+clickCoOrd);
        if(actors[dude].x === clickCoOrd[0] && actors[dude].y === clickCoOrd[1])
            document.getElementById("Selected").innerHTML = "Selected: "+actors[dude].name;
    };
});
<commit_msg>Free Turns For Everyone!<commit_after>//Global vars for Everyone
//Init Display
var w = 70;
var h = 25;
var display = new ROT.Display({spacing:1.4, width: w, height: h});
var map = {};

var socket = io.connect(window.location.origin);

var actors = {};
var freeCells;
var master;

var name;
var color;
//Things only used by Session 0
var scheduler;
var engine;

var currentTurn;

var init = function (){
	name = document.forms[0].name.value;
	color = document.forms[0].color.value;
	master = (document.forms[0].master.value == "yes")? true : false;

	document.forms[0].style.display = "none";
	document.getElementById("GameArea").appendChild(display.getContainer());
    document.getElementById("Selected").innerHTML = "Selected: ";
    document.getElementById("GameData").style.display = "inline-block";

	if(master){
		masterSockets();
		createMap();

	    socket.emit('updateMap&Actors',{map : map, actors : actors, freeCells: freeCells});
        window.addEventListener("keydown", actors["player"]);
/*
        scheduler = new ROT.Scheduler.Simple();
        scheduler.add(actors["player"],true);
        scheduler.add(actors["cat"],true);
        engine = new ROT.Engine(scheduler);
        engine.start();
*/
	}else{
		clientSockets();
		socket.emit('player2init',"hi");
	}
};

var drawMap = function(){
	for (var key in this.map) {
        var parts = key.split(",");
        var x = parseInt(parts[0]);
        var y = parseInt(parts[1]);
        this.display.draw(x, y, this.map[key]);
    }
};
socket.on('finishedTurn',function(data){
    var x = actors[data.what].x;
    var y = actors[data.what].y;

    display.draw(x, y, map[x+","+y]);
    actors[data.what].update(data.newX, data.newY);

});
socket.on('playerLeft',function (data){
	actors[data].removeMe();
});
socket.on('AMLeft',function (data){
    while (document.body.firstChild) {
        document.body.removeChild(document.body.firstChild);
    };
    confirm("Rocks fall, everyone dies.");
});
var masterSockets = function (){
	socket.on('newPlayer',function (data){

	    actors[data.name] = new RemoteActor(data.x,data.y,data.rune,data.color,data.name);
	    scheduler.add(actors[data.name],true);
	});
	socket.on('yourTurn',function (data){
	    document.getElementById("WhoseTurn").innerHTML = "Current Turn: "+data.whoseTurn;
	    currentTurn = data.whoseTurn;
	});
    socket.on('monotheism',function (data){
        confirm("THERE CAN ONLY BE ONE!");
        document.body.innerHTML="";
        document.head.innerHTML="";
    });
};
var clientSockets = function (){
	socket.on('newPlayer',function (data){

	    if(data.name !== name)
	        actors[data.name] = new Actor(data.x,data.y,data.rune,data.color,data.name);
	});
	socket.on('yourTurn',function(data){
	    document.getElementById("WhoseTurn").innerHTML = "Current Turn: "+data.whoseTurn;
	    currentTurn = data.whoseTurn;
	    if(data.whoseTurn === name)
	        actors[name].act();

	});
	socket.on('initData',function (data){
		map = data.map;
		actors = data.actors;
		freeCells = data.freeCells;

		drawMap();

		for (actor in data.actors){
			actors[actor] = new Actor(data.actors[actor].x,data.actors[actor].y,data.actors[actor].rune,data.actors[actor].color,data.actors[actor].name);
		};

		var index = Math.floor(ROT.RNG.getUniform() * freeCells.length);
	    var key = freeCells.splice(index, 1)[0];
	    var parts = key.split(",");
	    var x = parseInt(parts[0]);
	    var y = parseInt(parts[1]);
		actors[name] = new Player2(x,y,color,name);
		socket.emit('newPlayer',actors[name]);
		window.addEventListener("keydown", actors[name]);
	});
};
var createMap = function(){
	var mapLayout = new ROT.Map.Digger(w,h,[3,15],0.9);//I don't seem to understand these last 2 arguments
	freeCells = [];

	mapLayout.create(function(x,y,what){

		if (what === 1) {
            display.draw(x,y,null,null,"#777");

            var key = x+","+y;
            //map[key] = "#";
            return;
        };
        var key = x+","+y;
        map[key] = ".";
        freeCells.push(key);
	}.bind(this));
	drawMap();
	actors["player"] = createCreature(Player, freeCells, name, color);
    //actors["cat"] = createCreature(Cat, freeCells, "Sam", "tan");
};
var createCreature = function(what, freeCells, thisName, thisColor){
	var index = Math.floor(ROT.RNG.getUniform() * freeCells.length);
    var key = freeCells.splice(index, 1)[0];
    var parts = key.split(",");
    var x = parseInt(parts[0]);
    var y = parseInt(parts[1]);
    return new what(x, y, thisName, thisColor);
};
var Cat = function(xCoord,yCoord, thisName, thisColor){
    this.x = xCoord;
    this.y = yCoord;
    this.rune = "f";
    this.color = thisColor;
    this.name = thisName;

    this.draw = function(){
        display.draw(this.x,this.y,this.rune,this.color);
    };
    this.draw();
    this.act = function(){
        var ownerX = actors["player"].x;
        var ownerY = actors["player"].y;
        var newX;
        var newY;

        var passableCallback = function(x,y){
            return(x+","+y in map);
        };
        var aStar = new ROT.Path.AStar(ownerX,ownerY,passableCallback,{topology:8});

        var path = [];
        var pathCallback = function(x,y){
            path.push([x,y]);
        }
        aStar.compute(this.x,this.y,pathCallback);
        if(path.length <= 5){
            var randomDir = Math.floor(Math.random()*16);
            if(randomDir > 7) {return;}
            var diff = ROT.DIRS[8][randomDir];
            newX = this.x + diff[0];
            newY = this.y + diff[1];
            var newKey = newX + "," + newY;
            if (!(newKey in map)) { return; } // cannot move in this direction
            if(map[newKey] == "#"){ return; }    //Cannot move through walls (#s)
            if(newX === ownerX && newY === ownerY){return;};

        }else{
            path.shift();
            newX = path[0][0];
            newY = path[0][1];
        }
        socket.emit('somethingMoved',{what: "cat", newX : newX, newY : newY});
    };
    this.update = function(newX,newY){
        this.x = newX;
        this.y = newY;
        this.draw();
    };
};
var Player = function(xCoord, yCoord, thisName, thisColor) {
    this.x = xCoord;
    this.y = yCoord;
    this.rune = "@";
    this.color = thisColor;
    this.name = thisName;

    this.act = function(){

        engine.lock();

        socket.emit('yourTurn',{whoseTurn : this.name});
        window.addEventListener("keydown", this);

    };
    this.draw = function(){
        display.draw(this.x,this.y,this.rune,this.color);
    };
    this.draw();
    this.handleEvent = function(e){
        var keyMap = {};
        keyMap[38] = 0;
        keyMap[33] = 1;
        keyMap[39] = 2;
        keyMap[34] = 3;
        keyMap[40] = 4;
        keyMap[35] = 5;
        keyMap[37] = 6;
        keyMap[36] = 7;

        var code = e.keyCode;
        if(code === 12){
            engine.unlock();
            socket.emit('somethingMoved',{what: "player", newX : this.x, newY : this.y});
            return;
        }
        if (!(code in keyMap)) { return; }

        var diff = ROT.DIRS[8][keyMap[code]];
        var newX = this.x + diff[0];
        var newY = this.y + diff[1];

        var newKey = newX + "," + newY;
        if (!(newKey in map)) { return; } // cannot move in this direction
            else if(map[newKey] == "#"){return;}    //Cannot move through walls (#s)

        socket.emit('somethingMoved',{what: "player", newX : newX, newY : newY});

        //window.removeEventListener("keydown", this);
/*
        var lightPasses = function(x,y){
            var key = x+","+y;
            if (key in map) {
                if(map[key] !== "#"){
                    return true;
                }
                return false;
            }
            return false;
        };
        var fov = new ROT.FOV.RecursiveShadowcasting(lightPasses);

        display.clear();
        fov.compute180(x, y, 10, keyMap[code], function(x, y, r, visibility) {
            var ch = (r ? map[x+","+y] : "@");
            var color = (map[x+","+y] ? "#aa0": "#660");
            display.draw(x, y, ch);
        });
*/

    };
    this.update = function(newX,newY){
        this.x = newX;
        this.y = newY;
        this.draw();
        if(master){
            engine.unlock();
        };

    };
};
var RemoteActor = function(xCoord,yCoord,rune,color,name){
    this.x = xCoord;
    this.y = yCoord;
    this.rune = rune;
    this.color = color;
    this.name = name;

    this.draw = function(){
        display.draw(this.x,this.y,this.rune,this.color);
    };
    this.draw();
    this.act = function(){

        engine.lock();
        socket.emit('yourTurn',{whoseTurn : this.name});
    };
    this.update = function(newX,newY){
        this.x = newX;
        this.y = newY;
        this.draw();
        engine.unlock();
    };
    this.removeMe = function (){
    	display.draw(this.x, this.y, map[this.x+","+this.y]);
    	console.log("Curr Turn: "+currentTurn+" & this.name: "+this.name);
    	if(currentTurn == this.name)
    		engine.unlock();

    	scheduler.remove(actors[this.name]);
    	delete actors[this.name];
    };
};
var Actor = function(xCoord,yCoord,rune,color,name){
    this.x = xCoord;
    this.y = yCoord;
    this.rune = rune;
    this.color = color;
    this.name = name;

    this.draw = function(){
        display.draw(this.x,this.y,this.rune,this.color);
    };
    this.draw();
    this.act = function(){};
    this.update = function(newX,newY){
        this.x = newX;
        this.y = newY;
        this.draw();
    };
    this.removeMe = function (){
    	display.draw(this.x, this.y, map[this.x+","+this.y]);
    	delete actors[this.name];
    };
};
var Player2 = function(xCoord, yCoord, color, name) {
    this.x = xCoord;
    this.y = yCoord;
    this.rune = "@";
    this.color = color;
    this.name = name;

    this.act = function(){
        //engine.lock();
        window.addEventListener("keydown", this);

    };
    this.draw = function(){
        display.draw(this.x,this.y,this.rune,this.color);
    };
    this.draw();
    this.handleEvent = function(e){
        var keyMap = {};
        keyMap[38] = 0;
        keyMap[33] = 1;
        keyMap[39] = 2;
        keyMap[34] = 3;
        keyMap[40] = 4;
        keyMap[35] = 5;
        keyMap[37] = 6;
        keyMap[36] = 7;

        var code = e.keyCode;
        if(code === 12){
            socket.emit('somethingMoved',{what: name, newX : this.x, newY : this.y});
            window.removeEventListener("keydown", this);
            return;
        }
        if (!(code in keyMap)) { return; }

        var diff = ROT.DIRS[8][keyMap[code]];
        var newX = this.x + diff[0];
        var newY = this.y + diff[1];

        var newKey = newX + "," + newY;
        if (!(newKey in map)) { return; } // cannot move in this direction
            else if(map[newKey] == "#"){return;}    //Cannot move through walls (#s)

        socket.emit('somethingMoved',{what: name, newX : newX, newY : newY});

        //window.removeEventListener("keydown", this);
/*
        var lightPasses = function(x,y){
            var key = x+","+y;
            if (key in map) {
                if(map[key] !== "#"){
                    return true;
                }
                return false;
            }
            return false;
        };
        var fov = new ROT.FOV.RecursiveShadowcasting(lightPasses);

        display.clear();
        fov.compute180(x, y, 10, keyMap[code], function(x, y, r, visibility) {
            var ch = (r ? map[x+","+y] : "@");
            var color = (map[x+","+y] ? "#aa0": "#660");
            display.draw(x, y, ch);
        });
*/
        //engine.unlock();
    };
    this.update = function(newX,newY){
        this.x = newX;
        this.y = newY;
        this.draw();
    };
};

window.addEventListener("click",function (e){
    var clickCoOrd = display.eventToPosition(e);

    for(dude in actors){
        //console.log("actors"+actors[dude].x+","+actors[dude].y+" clickCoOrd:"+clickCoOrd);
        if(actors[dude].x === clickCoOrd[0] && actors[dude].y === clickCoOrd[1])
            document.getElementById("Selected").innerHTML = "Selected: "+actors[dude].name;
    };
});
<|endoftext|>