<commit_before>/**
 *
 * @since 0.1.0
 */

'use strict';
/*
 * Required dependencies
 */
var _ = require('underscore');

/**
 *
 * @param {Array} array
 * @param {String} type
 * @returns {object} GeoJSON object
 */
var toGeoJSON = function (array, type) {
  var georesult = {};
  if ( !type ) {
    type = "point";
  }
  type = type.toLowerCase();
  switch (type) {
    case 'point':
      var _array = _.flatten(array);
      var _a = JSON.stringify(array) || {};
      if (_array.length !== 2) {
        return new Error("expected a single set of coordinates in [lat, lng] format. \nReceived " + _a);
      }
      var arr = [_array[1], _array[0]];
      georesult = {
        type: "Point",
        coordinates: arr
      };
      return georesult;
    break;
    case 'linestring':
      var arr = [];
      _.each(array, function (a) {
        arr.push([a[1], a[0]]);
      });
      georesult = {
        type: "LineString",
        coordinates: _.uniq(arr, true, function (x) {
          return JSON.stringify(x) ;
        })
      };
      return georesult;
    break;
    case 'polygon':
      var arr = [[[]]];
      if (array.length < 3) {
        return new Error("Expecting 'array' to have at length of at least 3 sets of coordinates.");
      }
      if (array[0].toString() !== _.last(array).toString()) {
        array.push(array[0]);
      }
      _.each(array, function (a) {
        arr[0][0].push([a[1], a[0]]);
      });
      georesult = {
        type: "Polygon",
        coordinates: arr
      };
      return georesult;
    break;
    default:
      return new Error("type not recognised. Should be 'point', 'linestring', or 'polygon'");
  }
};

/**
 *
 * @param {type} geoobj GeoJSON object
 * @returns {Array}
 */
var toArray = function (geoobj) {
  if (!geoobj.type || !geoobj.coordinates) {
    return new Error("The object specified is not a a valid GeoJSON object");
  }
  switch (geoobj.type.toLowerCase()) {
    case 'point':
      var point = [geoobj.coordinates[1],geoobj.coordinates[0]];
      return point;
    break;
    case 'linestring':
      // check if it is a valid line
      var array = geoobj.coordinates;
      var line = [];
      _.each(array, function (ln) {
        if (typeof ln === 'object') {
          line.push([ln[1], ln[0]]);
        }
        else {
          return new Error("the object specified is not a valid GeoJSON LineString");
        }
      });
      return line;
    break;
    case 'polygon':
      var array = geoobj.coordinates;
      while (array.length === 1) {
        array = array[0];
      }
      var poly = [];
      if (array[0].toString() !== _.last(array).toString()) {
        return new Error("The first and last coordinates of a Polygon are not the same");
      }
      _.each(_.initial(array), function (pl) {
        poly.push([pl[1], pl[0]]);
      });
      return poly;
    break;
    default:
      return new Error("unknown GeoJSON type specified");
  }
};

/**
 *
 * @param {Array} array array of coordinates
 * @param {Number} decimals number of decimals to return
 * @returns {Number}
 */
var getDistance = function (array, decimals) {
  if(typeof(Number.prototype.toRad) === "undefined") {
      Number.prototype.toRad = function () {
      return this * Math.PI / 180;
    };
  }

  decimals = decimals || 3;
  var earthRadius = 6378.137, // km
    distance = 0,
    len = array.length;
  for (var i = 0; (i + 1) < len; i++) {
    var x1 = array[i];
    var x2 = array[i + 1];

    var lat1 = parseFloat(x1[0]);
    var lat2 = parseFloat(x2[0]);
    var lon1 = parseFloat(x1[1]);
    var lon2 = parseFloat(x2[1]);

    var dLat = (lat2 - lat1).toRad();
    var dLon = (lon2 - lon1).toRad();
    lat1 = lat1.toRad();
    lat2 = lat2.toRad();

    var a = Math.sin(dLat / 2) * Math.sin(dLat / 2) +
      Math.sin(dLon / 2) * Math.sin(dLon / 2) * Math.cos(lat1) * Math.cos(lat2);
    var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
    var d = earthRadius * c;
    distance += d;
  }
  distance = Math.round(distance * Math.pow(10, decimals)) / Math.pow(10, decimals);
  return distance;
};

/*
 * Export functions
 */
exports.toGeoJSON = toGeoJSON;
exports.toArray = toArray;
exports.getDistance = getDistance;<commit_msg>Fix nesting of `Polygon`<commit_after>/**
 *
 * @since 0.1.0
 */

'use strict';
/*
 * Required dependencies
 */
var _ = require('underscore');

/**
 *
 * @param {Array} array
 * @param {String} type
 * @returns {object} GeoJSON object
 */
var toGeoJSON = function (array, type) {
  var georesult = {};
  if ( !type ) {
    type = "point";
  }
  type = type.toLowerCase();
  switch (type) {
    case 'point':
      var _array = _.flatten(array);
      var _a = JSON.stringify(array) || {};
      if (_array.length !== 2) {
        return new Error("expected a single set of coordinates in [lat, lng] format. \nReceived " + _a);
      }
      var arr = [_array[1], _array[0]];
      georesult = {
        type: "Point",
        coordinates: arr
      };
      return georesult;
    break;
    case 'linestring':
      var arr = [];
      _.each(array, function (a) {
        arr.push([a[1], a[0]]);
      });
      georesult = {
        type: "LineString",
        coordinates: _.uniq(arr, true, function (x) {
          return JSON.stringify(x) ;
        })
      };
      return georesult;
    break;
    case 'polygon':
      var arr = [[]];
      if (array.length < 3) {
        return new Error("Expecting 'array' to have at length of at least 3 sets of coordinates.");
      }
      if (array[0].toString() !== _.last(array).toString()) {
        array.push(array[0]);
      }
      _.each(array, function (a) {
        arr[0].push([a[1], a[0]]);
      });
      georesult = {
        type: "Polygon",
        coordinates: arr
      };
      return georesult;
    break;
    default:
      return new Error("type not recognised. Should be 'point', 'linestring', or 'polygon'");
  }
};

/**
 *
 * @param {type} geoobj GeoJSON object
 * @returns {Array}
 */
var toArray = function (geoobj) {
  if (!geoobj.type || !geoobj.coordinates) {
    return new Error("The object specified is not a a valid GeoJSON object");
  }
  switch (geoobj.type.toLowerCase()) {
    case 'point':
      var point = [geoobj.coordinates[1],geoobj.coordinates[0]];
      return point;
    break;
    case 'linestring':
      // check if it is a valid line
      var array = geoobj.coordinates;
      var line = [];
      _.each(array, function (ln) {
        if (typeof ln === 'object') {
          line.push([ln[1], ln[0]]);
        }
        else {
          return new Error("the object specified is not a valid GeoJSON LineString");
        }
      });
      return line;
    break;
    case 'polygon':
      var array = geoobj.coordinates[0];
      if (!array.length) {
        return new Error("the object specified is not a valid GeoJSON Polygon");
      }
      var poly = [];
      _.each(array, function (a) {
        if (a[0].toString() !== _.last(a).toString()) {
          return new Error("The first and last coordinates of a Polygon are not the same");
        }
        if (a.length < 4) {
          return new Error("A valid Polygon should have a minimum of 4 coordinates");
        }
        _.each(_.initial(a), function (pl) {
          poly.push([pl[1], pl[0]]);
        });
      });
      return poly;
    break;
    default:
      return new Error("unknown GeoJSON type specified");
  }
};

/**
 *
 * @param {Array} array array of coordinates
 * @param {Number} decimals number of decimals to return
 * @returns {Number}
 */
var getDistance = function (array, decimals) {
  if(typeof(Number.prototype.toRad) === "undefined") {
      Number.prototype.toRad = function () {
      return this * Math.PI / 180;
    };
  }

  decimals = decimals || 3;
  var earthRadius = 6378.137, // km
    distance = 0,
    len = array.length;
  for (var i = 0; (i + 1) < len; i++) {
    var x1 = array[i];
    var x2 = array[i + 1];

    var lat1 = parseFloat(x1[0]);
    var lat2 = parseFloat(x2[0]);
    var lon1 = parseFloat(x1[1]);
    var lon2 = parseFloat(x2[1]);

    var dLat = (lat2 - lat1).toRad();
    var dLon = (lon2 - lon1).toRad();
    lat1 = lat1.toRad();
    lat2 = lat2.toRad();

    var a = Math.sin(dLat / 2) * Math.sin(dLat / 2) +
      Math.sin(dLon / 2) * Math.sin(dLon / 2) * Math.cos(lat1) * Math.cos(lat2);
    var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
    var d = earthRadius * c;
    distance += d;
  }
  distance = Math.round(distance * Math.pow(10, decimals)) / Math.pow(10, decimals);
  return distance;
};

/*
 * Export functions
 */
exports.toGeoJSON = toGeoJSON;
exports.toArray = toArray;
exports.getDistance = getDistance;<|endoftext|>


<commit_before>import wpi from 'wiring-pi';

export default blinkLED = () => {
    wpi.setup("gpio");

    const pin = 12;
    const blinks = 5;

    wpi.pinMode(pin, wpi.OUTPUT);

    let value = 1;

    for(let i = 0; i < blinks; i++) {
      wpi.digitalWrite(pin, value);
      value = +!value;
      setTimeout(500);
    }

    wpi.digitalWrite(pin, 0);
};
<commit_msg>fixed blinkLED<commit_after>import wpi from 'wiring-pi';

 const blinkLED = () => {
    wpi.setup("gpio");

    const pin = 12;
    const blinks = 5;

    wpi.pinMode(pin, wpi.OUTPUT);

    let value = 1;

    for(let i = 0; i < blinks; i++) {
      wpi.digitalWrite(pin, value);
      value = +!value;
      setTimeout(500);
    }

    wpi.digitalWrite(pin, 0);
};

export default blinkLED;
<|endoftext|>


<commit_before>const Discord = require('discord.js')
const Feed = require('../structs/db/Feed.js')
const createLogger = require('../util/logger/create.js')
const maintenance = require('../maintenance/index.js')

module.exports = async (oldChannel, newChannel) => {
  if (!(newChannel instanceof Discord.GuildChannel) || !(oldChannel instanceof Discord.GuildChannel)) {
    return
  }
  const log = createLogger(oldChannel.guild.shard.id)
  const deleted = newChannel.guild.deleted || newChannel.deleted
  try {
    const feeds = await Feed.getManyBy('channel', newChannel.id)
    for (const feed of feeds) {
      if (deleted) {
        feed.delete()
          .catch(err => log.error(err, 'Failed to delete due to deleted channel'))
      } else {
        maintenance.checkPermissions.feed(feed, newChannel.client)
          .catch(err => log.error(err, `Failed to check permissions of feed ${feed._id} after channel update`))
      }
    }
  } catch (err) {
    log.error(err, 'Failed to check feeds in channelUpdate')
  }
}
<commit_msg>Add additional check for channel update<commit_after>const Discord = require('discord.js')
const Feed = require('../structs/db/Feed.js')
const createLogger = require('../util/logger/create.js')
const maintenance = require('../maintenance/index.js')

module.exports = async (oldChannel, newChannel) => {
  if (!(newChannel instanceof Discord.GuildChannel) || !(oldChannel instanceof Discord.GuildChannel)) {
    return
  }
  const client = newChannel.client
  const log = createLogger(oldChannel.guild.shard.id)
  const deleted = newChannel.guild.deleted || newChannel.deleted || !client.channels.cache.has(newChannel.id)
  try {
    const feeds = await Feed.getManyBy('channel', newChannel.id)
    for (const feed of feeds) {
      if (deleted) {
        feed.delete()
          .catch(err => log.error(err, 'Failed to delete due to deleted channel'))
      } else {
        maintenance.checkPermissions.feed(feed, client)
          .catch(err => log.error(err, `Failed to check permissions of feed ${feed._id} after channel update`))
      }
    }
  } catch (err) {
    log.error(err, 'Failed to check feeds in channelUpdate')
  }
}
<|endoftext|>


<commit_before>const { Event } = require('klasa');

module.exports = class extends Event {

	run(message) {
		if (message.command && message.command.deletable) for (const msg of message.responses) msg.delete();
	}

};
<commit_msg>[Fix] Klasa tries to delete already deleted messages (#438)<commit_after>const { Event } = require('klasa');

module.exports = class extends Event {

	run(message) {
		if (message.command && message.command.deletable) {
			for (const msg of message.responses) {
				if (!msg.deleted) msg.delete();
			}
		}
	}

};
<|endoftext|>


<commit_before>'use strict';

/**
 * Data Access Object.
 *
 * All functions that return a Promise of data will reject that Promise if no data is found.
 *
 * @module dao
 * @license MIT
 * @author RaceProUK
 */

const db = require('./model/db');

let initialised = false;

module.exports = {
	initialise: initialise,
	teardown: teardown,
	isInitialised: isInitialised,
	//User operations
	getAllUsers: getAllUsers,
	getUser: getUser,
	getUserByName: getUserByName,
	addUser: addUser,
	updateUser: updateUser,
	//Board operations
	getAllBoards: getAllBoards,
	getBoards: getBoards,
	getBoard: getBoard,
	addBoard: addBoard,
	updateBoard: updateBoard,
	//Game operations
	getAllGames: getAllGames,
	getGames: getGames,
	getGame: getGame,
	addGame: addGame,
	updateGame: updateGame
};

/**
 * Initialise the DAO. *Must be called before any other function.*
 *
 * @param {Object} config The necessary information to set up the database
 * @param {String} config.sqlite The location of the SQLite file to use; if it doesn't exist, create it
 * @param {Object} config.postgres The necessary information to connect to a PostgreSQL database
 * @param {String} config.postgres.host The host running the PostGreSQL server
 * @param {String} config.postgres.name The name of the database to connect to
 * @param {String} config.postgres.username The username of the user to connect as
 * @param {String} config.postgres.password The password of the user to connect as
 *
 * @returns {Promise} A Promise that is resolved when the DAO is initialised.
 */
function initialise(config) {
	return initialised
		? Promise.resolve()
		: db.initialise(config).then(() => {
			initialised = true;
		});
}

/**
 * Tears down the DAO. *The DAO must be reinitialised before it can be used again.*
 *
 * @returns {Promise} A Promise that is resolved when the DAO is torn down.
 */
function teardown() {
	return !initialised
		? Promise.resolve()
		: db.close().then(() => {
			initialised = false;
		});
}

/**
 * Reports if the DAO is initialised.
 *
 * @returns {boolean} Flag indicating whether the DAO is initialised.
 */
function isInitialised() {
	return initialised;
}

/**
 * Get all users in the forum.
 *
 * @returns {Promise} A Promise that is resolved with a list of users
 */
function getAllUsers() {
	return db.Users.findAll().then((users) => {
		if (!users || users.length === 0) {
			throw new Error(`No users exist`);
		}
		return users;
	});
}

/**
 * Get a user by ID.
 *
 * @param {Number} id The ID of the user requested
 *
 * @returns {Promise} A Promise that is resolved with the user requested
 */
function getUser(id) {
	return db.Users.findByPrimary(id).then((user) => {
		if (!user) {
			throw new Error(`User with ID ${id} not found`);
		}
		return user;
	});
}

/**
 * Get a user by name.
 *
 * @param {String} name The name of the user requested
 *
 * @returns {Promise} A Promise that is resolved with the user requested
 */
function getUserByName(name) {
	return db.Users.findOne({
		where: {
			Username: name
		}
	}).then((user) => {
		if (!user) {
			throw new Error(`User with ID ${name} not found`);
		}
		return user;
	});
}

/**
 * Add a user.
 *
 * @param {Object} user The user to add
 *
 * @returns {Promise} A Promise that is resolved with the user added
 */
function addUser(user) {
	return db.Users.create(user);
}

/**
 * Update a user.
 *
 * @param {Number} id The ID of the user to update
 * @param {Object} user The details to update the user with
 *
 * @returns {Promise} A Promise that is resolved with the user updated
 */
function updateUser(id, user) {
	return db.Users.update(user, {
		where: {
			ID: id
		}
	}).then(() => {
		return getUser(id);
	});
}

/**
 * Get all vanilla boards in the forum.
 *
 * @returns {Promise} A Promise that is resolved with a list of vanilla boards
 */
function getAllBoards() {
	return db.Boards.findAll({
		where: {
			GameID: null
		}
	}).then((boards) => {
		if (!boards || boards.length === 0) {
			throw new Error(`No boards exist`);
		}
		return boards;
	});
}

/**
 * Get all vanilla boards that belong to a parent board, or all root-level vanilla boards if no parent specified.
 *
 * @param {Number} [parentID] The ID of the parent board, or `null` for root-level boards
 *
 * @returns {Promise} A Promise that is resolved with a list of vanilla boards
 */
function getBoards(parentID) {
	if (parentID !== 0) {
		parentID = parentID || null; //Coerce to null to prevent avoidable errors
	}
	return db.Boards.findAll({
		where: {
			BoardID: parentID,
			GameID: null
		}
	}).then((boards) => {
		if (!boards || boards.length === 0) {
			throw new Error(`No boards exist with a parent of ${parentID}`);
		}
		return boards;
	});
}

/**
 * Get a vanilla board by ID.
 *
 * @param {Number} id The ID of the board requested
 *
 * @returns {Promise} A Promise that is resolved with the board requested
 */
function getBoard(id) {
	return db.Boards.findByPrimary(id, {
		where: {
			GameID: null
		}
	}).then((board) => {
		if (!board) {
			throw new Error(`Board with ID ${id} not found`);
		}
		return board;
	});
}

/**
 * Add a vanilla board.
 *
 * @param {Object} board The board to add
 *
 * @returns {Promise} A Promise that is resolved with the board added
 */
function addBoard(board) {
	return new Promise((resolve, reject) => {
		if (board.GameID || board.Game) {
			reject(new Error('Games cannot be added using this method; please use addGame() instead'));
		} else {
			resolve();
		}
	}).then(() => {
		return db.Boards.create(board);
	});
}

/**
 * Update a vanilla board.
 *
 * @param {Number} id The ID of the board to update
 * @param {Object} board The details to update the board with
 *
 * @returns {Promise} A Promise that is resolved with the board updated
 */
function updateBoard(id, board) {
	return new Promise((resolve, reject) => {
		if (board.GameID || board.Game) {
			reject(new Error('Games cannot be updated using this method; please use updateGame() instead'));
		} else {
			resolve();
		}
	}).then(() => {
		return db.Boards.update(board, {
			where: {
				ID: id,
				GameID: null
			}
		});
	}).then(() => {
		return getBoard(id);
	});
}

/**
 * Get all games in the forum.
 *
 * @returns {Promise} A Promise that is resolved with a list of games
 */
function getAllGames() {
	return db.Boards.findAll({
		where: {
			GameID: {
				not: null
			}
		},
		include: [db.Games]
	}).then((games) => {
		if (!games || games.length === 0) {
			throw new Error(`No games exist`);
		}
		return games;
	});
}

/**
 * Get all games that belong to a parent game, or all root-level games if no parent specified.
 *
 * @param {Number} [parentID] The ID of the parent game, or `null` for root-level games
 *
 * @returns {Promise} A Promise that is resolved with a list of games
 */
function getGames(parentID) {
	if (parentID !== 0) {
		parentID = parentID || null; //Coerce to null to prevent avoidable errors
	}
	return db.Boards.findAll({
		where: {
			BoardID: parentID,
			GameID: {
				not: null
			}
		},
		include: [db.Games]
	}).then((games) => {
		if (!games || games.length === 0) {
			throw new Error(`No games exist with a parent of ${parentID}`);
		}
		return games;
	});
}

/**
 * Get a game by ID.
 *
 * @param {Number} id The ID of the game requested
 *
 * @returns {Promise} A Promise that is resolved with the game requested
 */
function getGame(id) {
	return db.Boards.findByPrimary(id, {
		where: {
			GameID: {
				not: null
			}
		},
		include: [db.Games]
	}).then((game) => {
		if (!game) {
			throw new Error(`Game with ID ${id} not found`);
		}
		return game;
	});
}

/**
 * Add a game.
 *
 * @param {Object} game The game to add
 *
 * @returns {Promise} A Promise that is resolved with the game added
 */
function addGame(game) {
	return new Promise((resolve, reject) => {
		if (!game.GameID && !game.Game) {
			reject(new Error('Vanilla boards cannot be added using this method; please use addBoard() instead'));
		} else {
			resolve();
		}
	}).then(() => {
		return db.Boards.create(game, {
			include: [db.Games]
		});
	});
}

/**
 * Update a game.
 *
 * @param {Number} id The ID of the game to update
 * @param {Object} game The details to update the game with
 *
 * @returns {Promise} A Promise that is resolved with the game updated
 */
function updateGame(id, game) {
	return new Promise((resolve, reject) => {
		if (!game.GameID && !game.Game) {
			reject(new Error('Games cannot be updated using this method; please use updateBoard() instead'));
		} else {
			resolve();
		}
	}).then(() => {
		return db.Boards.update(game, {
			where: {
				ID: id,
				GameID: {
					not: null
				}
			}
		});
	}).then(() => {
		return getGame(id);
	});
}
<commit_msg>Fixing error message<commit_after>'use strict';

/**
 * Data Access Object.
 *
 * All functions that return a Promise of data will reject that Promise if no data is found.
 *
 * @module dao
 * @license MIT
 * @author RaceProUK
 */

const db = require('./model/db');

let initialised = false;

module.exports = {
	initialise: initialise,
	teardown: teardown,
	isInitialised: isInitialised,
	//User operations
	getAllUsers: getAllUsers,
	getUser: getUser,
	getUserByName: getUserByName,
	addUser: addUser,
	updateUser: updateUser,
	//Board operations
	getAllBoards: getAllBoards,
	getBoards: getBoards,
	getBoard: getBoard,
	addBoard: addBoard,
	updateBoard: updateBoard,
	//Game operations
	getAllGames: getAllGames,
	getGames: getGames,
	getGame: getGame,
	addGame: addGame,
	updateGame: updateGame
};

/**
 * Initialise the DAO. *Must be called before any other function.*
 *
 * @param {Object} config The necessary information to set up the database
 * @param {String} config.sqlite The location of the SQLite file to use; if it doesn't exist, create it
 * @param {Object} config.postgres The necessary information to connect to a PostgreSQL database
 * @param {String} config.postgres.host The host running the PostGreSQL server
 * @param {String} config.postgres.name The name of the database to connect to
 * @param {String} config.postgres.username The username of the user to connect as
 * @param {String} config.postgres.password The password of the user to connect as
 *
 * @returns {Promise} A Promise that is resolved when the DAO is initialised.
 */
function initialise(config) {
	return initialised
		? Promise.resolve()
		: db.initialise(config).then(() => {
			initialised = true;
		});
}

/**
 * Tears down the DAO. *The DAO must be reinitialised before it can be used again.*
 *
 * @returns {Promise} A Promise that is resolved when the DAO is torn down.
 */
function teardown() {
	return !initialised
		? Promise.resolve()
		: db.close().then(() => {
			initialised = false;
		});
}

/**
 * Reports if the DAO is initialised.
 *
 * @returns {boolean} Flag indicating whether the DAO is initialised.
 */
function isInitialised() {
	return initialised;
}

/**
 * Get all users in the forum.
 *
 * @returns {Promise} A Promise that is resolved with a list of users
 */
function getAllUsers() {
	return db.Users.findAll().then((users) => {
		if (!users || users.length === 0) {
			throw new Error(`No users exist`);
		}
		return users;
	});
}

/**
 * Get a user by ID.
 *
 * @param {Number} id The ID of the user requested
 *
 * @returns {Promise} A Promise that is resolved with the user requested
 */
function getUser(id) {
	return db.Users.findByPrimary(id).then((user) => {
		if (!user) {
			throw new Error(`User with ID ${id} not found`);
		}
		return user;
	});
}

/**
 * Get a user by name.
 *
 * @param {String} name The name of the user requested
 *
 * @returns {Promise} A Promise that is resolved with the user requested
 */
function getUserByName(name) {
	return db.Users.findOne({
		where: {
			Username: name
		}
	}).then((user) => {
		if (!user) {
			throw new Error(`User with name ${name} not found`);
		}
		return user;
	});
}

/**
 * Add a user.
 *
 * @param {Object} user The user to add
 *
 * @returns {Promise} A Promise that is resolved with the user added
 */
function addUser(user) {
	return db.Users.create(user);
}

/**
 * Update a user.
 *
 * @param {Number} id The ID of the user to update
 * @param {Object} user The details to update the user with
 *
 * @returns {Promise} A Promise that is resolved with the user updated
 */
function updateUser(id, user) {
	return db.Users.update(user, {
		where: {
			ID: id
		}
	}).then(() => {
		return getUser(id);
	});
}

/**
 * Get all vanilla boards in the forum.
 *
 * @returns {Promise} A Promise that is resolved with a list of vanilla boards
 */
function getAllBoards() {
	return db.Boards.findAll({
		where: {
			GameID: null
		}
	}).then((boards) => {
		if (!boards || boards.length === 0) {
			throw new Error(`No boards exist`);
		}
		return boards;
	});
}

/**
 * Get all vanilla boards that belong to a parent board, or all root-level vanilla boards if no parent specified.
 *
 * @param {Number} [parentID] The ID of the parent board, or `null` for root-level boards
 *
 * @returns {Promise} A Promise that is resolved with a list of vanilla boards
 */
function getBoards(parentID) {
	if (parentID !== 0) {
		parentID = parentID || null; //Coerce to null to prevent avoidable errors
	}
	return db.Boards.findAll({
		where: {
			BoardID: parentID,
			GameID: null
		}
	}).then((boards) => {
		if (!boards || boards.length === 0) {
			throw new Error(`No boards exist with a parent of ${parentID}`);
		}
		return boards;
	});
}

/**
 * Get a vanilla board by ID.
 *
 * @param {Number} id The ID of the board requested
 *
 * @returns {Promise} A Promise that is resolved with the board requested
 */
function getBoard(id) {
	return db.Boards.findByPrimary(id, {
		where: {
			GameID: null
		}
	}).then((board) => {
		if (!board) {
			throw new Error(`Board with ID ${id} not found`);
		}
		return board;
	});
}

/**
 * Add a vanilla board.
 *
 * @param {Object} board The board to add
 *
 * @returns {Promise} A Promise that is resolved with the board added
 */
function addBoard(board) {
	return new Promise((resolve, reject) => {
		if (board.GameID || board.Game) {
			reject(new Error('Games cannot be added using this method; please use addGame() instead'));
		} else {
			resolve();
		}
	}).then(() => {
		return db.Boards.create(board);
	});
}

/**
 * Update a vanilla board.
 *
 * @param {Number} id The ID of the board to update
 * @param {Object} board The details to update the board with
 *
 * @returns {Promise} A Promise that is resolved with the board updated
 */
function updateBoard(id, board) {
	return new Promise((resolve, reject) => {
		if (board.GameID || board.Game) {
			reject(new Error('Games cannot be updated using this method; please use updateGame() instead'));
		} else {
			resolve();
		}
	}).then(() => {
		return db.Boards.update(board, {
			where: {
				ID: id,
				GameID: null
			}
		});
	}).then(() => {
		return getBoard(id);
	});
}

/**
 * Get all games in the forum.
 *
 * @returns {Promise} A Promise that is resolved with a list of games
 */
function getAllGames() {
	return db.Boards.findAll({
		where: {
			GameID: {
				not: null
			}
		},
		include: [db.Games]
	}).then((games) => {
		if (!games || games.length === 0) {
			throw new Error(`No games exist`);
		}
		return games;
	});
}

/**
 * Get all games that belong to a parent game, or all root-level games if no parent specified.
 *
 * @param {Number} [parentID] The ID of the parent game, or `null` for root-level games
 *
 * @returns {Promise} A Promise that is resolved with a list of games
 */
function getGames(parentID) {
	if (parentID !== 0) {
		parentID = parentID || null; //Coerce to null to prevent avoidable errors
	}
	return db.Boards.findAll({
		where: {
			BoardID: parentID,
			GameID: {
				not: null
			}
		},
		include: [db.Games]
	}).then((games) => {
		if (!games || games.length === 0) {
			throw new Error(`No games exist with a parent of ${parentID}`);
		}
		return games;
	});
}

/**
 * Get a game by ID.
 *
 * @param {Number} id The ID of the game requested
 *
 * @returns {Promise} A Promise that is resolved with the game requested
 */
function getGame(id) {
	return db.Boards.findByPrimary(id, {
		where: {
			GameID: {
				not: null
			}
		},
		include: [db.Games]
	}).then((game) => {
		if (!game) {
			throw new Error(`Game with ID ${id} not found`);
		}
		return game;
	});
}

/**
 * Add a game.
 *
 * @param {Object} game The game to add
 *
 * @returns {Promise} A Promise that is resolved with the game added
 */
function addGame(game) {
	return new Promise((resolve, reject) => {
		if (!game.GameID && !game.Game) {
			reject(new Error('Vanilla boards cannot be added using this method; please use addBoard() instead'));
		} else {
			resolve();
		}
	}).then(() => {
		return db.Boards.create(game, {
			include: [db.Games]
		});
	});
}

/**
 * Update a game.
 *
 * @param {Number} id The ID of the game to update
 * @param {Object} game The details to update the game with
 *
 * @returns {Promise} A Promise that is resolved with the game updated
 */
function updateGame(id, game) {
	return new Promise((resolve, reject) => {
		if (!game.GameID && !game.Game) {
			reject(new Error('Games cannot be updated using this method; please use updateBoard() instead'));
		} else {
			resolve();
		}
	}).then(() => {
		return db.Boards.update(game, {
			where: {
				ID: id,
				GameID: {
					not: null
				}
			}
		});
	}).then(() => {
		return getGame(id);
	});
}
<|endoftext|>


<commit_before>'use strict';

var sizzle = require('sizzle');
var Dominus = require('./Dominus.ctor');
var api = module.exports = {};

api.qsa = function (elem, selector) {
  var results = new Dominus();
  return sizzle(selector, elem, results);
};

api.qs = function (elem, selector) {
  return api.qsa(elem, selector)[0];
};

api.on = function (elem, type, fn) {
  elem.addEventListener(type, fn);
};

function getSet (key, elem, value) {
  if (value === void 0) {
    return elem[key];
  } else {
    elem[key] = value;
  }
}

function getSetProperty (prop) {
  api[prop] = getSet.bind(null, prop);
}

['html', 'text', 'value'].forEach(getSetProperty);
<commit_msg>dom mapping<commit_after>'use strict';

var sizzle = require('sizzle');
var Dominus = require('./Dominus.ctor');
var api = module.exports = {};

api.qsa = function (elem, selector) {
  var results = new Dominus();
  return sizzle(selector, elem, results);
};

api.qs = function (elem, selector) {
  return api.qsa(elem, selector)[0];
};

api.on = function (elem, type, fn) {
  elem.addEventListener(type, fn);
};

function getSet (key, elem, value) {
  if (value === void 0) {
    return elem[key];
  } else {
    elem[key] = value;
  }
}

function getSetProperty (kvp) {
  api[kvp[0]] = getSet.bind(null, kvp[1]);
}

[['html', 'innerHTML'], ['text', 'innerText'], ['value', 'value']].forEach(getSetProperty);
<|endoftext|>


<commit_before>import { version } from '../package.json';
import './polyfills';

const toPrefetch = new Set();

/**
 * Barba prefetch
 *
 * @namespace @barba/prefetch
 * @type {object}
 */
export const prefetch = {
  /**
   * Version
   *
   * @memberof @barba/prefetch
   * @type {string}
   */
  version,

  /**
   * Plugin installation
   *
   * @memberof @barba/prefetch
   * @param {barba} barba barba instance
   * @param {HTMLElement} [root = document.body] routes
   * @returns {undefined}
   */
  install(barba, { root = document.body, timeout = 2e3 } = {}) {
    this.barba = barba;
    this._root = root;
    this._timeout = timeout;
    /* istanbul ignore next */
    this._observer = new IntersectionObserver(entries => {
      entries.forEach(entry => {
        if (entry.isIntersecting) {
          const el = entry.target;
          const url = this.barba.utils.getHref(el);

          if (toPrefetch.has(url)) {
            this._observer.unobserve(el);
            // Prefetch and cache
            if (!this.barba.cache.has(url)) {
              this.barba.cache.set(url, this.barba.request(url));
            }
          }
        }
      });
    });
  },

  /**
   * Plugin initialisation
   *
   * @memberof @barba/prefetch
   * @returns {undefined}
   */
  init() {
    this._observe(this._timeout);
    // Register hooks
    this.barba.hooks.after(this._observe, this);
  },

  /**
   * Plugin reset
   *
   * @memberof @barba/prefetch
   * @returns {undefined}
   */
  // DEV
  // destroy() {},

  _observe(timeout) {
    /* istanbul ignore next */
    window.requestIdleCallback(
      () => {
        // If not, find all links and use IntersectionObserver.
        this._root.querySelectorAll('a').forEach(el => {
          const url = this.barba.utils.getHref(el);

          // Add some [data-barba="preload"] or
          // Add some [data-barba-preload="true/false"] ?
          if (
            !this.barba.cache.has(url) &&
            !this.prevent.check(el, {}, el.href)
          ) {
            this._observer.observe(el);
            toPrefetch.add(url);
          }
        });
      },
      { timeout }
    );
  },
};

export default prefetch;
<commit_msg>fix(prefetch): :bug: fix check error<commit_after>import { version } from '../package.json';
import './polyfills';

const toPrefetch = new Set();

/**
 * Barba prefetch
 *
 * @namespace @barba/prefetch
 * @type {object}
 */
export const prefetch = {
  /**
   * Version
   *
   * @memberof @barba/prefetch
   * @type {string}
   */
  version,

  /**
   * Plugin installation
   *
   * @memberof @barba/prefetch
   * @param {barba} barba barba instance
   * @param {HTMLElement} [root = document.body] routes
   * @returns {undefined}
   */
  install(barba, { root = document.body, timeout = 2e3 } = {}) {
    this.barba = barba;
    this._root = root;
    this._timeout = timeout;
    /* istanbul ignore next */
    this._observer = new IntersectionObserver(entries => {
      entries.forEach(entry => {
        if (entry.isIntersecting) {
          const el = entry.target;
          const url = this.barba.utils.getHref(el);

          if (toPrefetch.has(url)) {
            this._observer.unobserve(el);
            // Prefetch and cache
            if (!this.barba.cache.has(url)) {
              this.barba.cache.set(url, this.barba.request(url));
            }
          }
        }
      });
    });
  },

  /**
   * Plugin initialisation
   *
   * @memberof @barba/prefetch
   * @returns {undefined}
   */
  init() {
    this._observe(this._timeout);
    // Register hooks
    this.barba.hooks.after(this._observe, this);
  },

  /**
   * Plugin reset
   *
   * @memberof @barba/prefetch
   * @returns {undefined}
   */
  // DEV
  // destroy() {},

  _observe(timeout) {
    /* istanbul ignore next */
    window.requestIdleCallback(
      () => {
        // If not, find all links and use IntersectionObserver.
        this._root.querySelectorAll('a').forEach(el => {
          const url = this.barba.utils.getHref(el);

          // Add some [data-barba="preload"] or
          // Add some [data-barba-preload="true/false"] ?
          if (
            !this.barba.cache.has(url) &&
            !this.barba.prevent.check(el, {}, el.href)
          ) {
            this._observer.observe(el);
            toPrefetch.add(url);
          }
        });
      },
      { timeout }
    );
  },
};

export default prefetch;
<|endoftext|>


<commit_before>'use strict';

/**
 * ScreenDirectiveCtrl
 *
 * extends LayoutBlockBase & LayoutDisplayBase
 *
 */
function ScreenDirectiveCtrl($scope, $element, $attrs, augmentController){
  var self = this,
      screen = this.layoutScope,
      trans = this.transition,
      locals,
      extCtrl = $attrs["withController"];
  //
  this.addReflowWatcher("displaying()");
  this.addReflowWatcher("calculateHeight()");
  this.addReflowWatcher("calculateWidth()");
  //
  $element.css("width","100%");
  $element.css("display","block");
  $element.css("position","absolute");
  ////////////////
  // setup the screen api
  //
  screen.calculateHeight = function(args){
    return screen.displaying() ? screen.height : 0;
  }
  //
  screen.calculateWidth = function(args){
    return screen.displaying() ? screen.width : 0;
  }
  //
  screen.show = function(name){
    var name = name || screen.name;
    $scope._block.currentScreen = name;
  }
  //
  screen.hide = function(){
    if(screen.displaying()){
      $scope._block.currentScreen = null;
    }
  }
  //
  screen.displaying = function(){
    return ($scope._block.currentScreen == screen.name);
  }
  //
  // init function get called during linking phase
  this.init = function(_block, _layout){
    // augment controller
    if(angular.isString(extCtrl) && extCtrl.length > 0) {
      locals = { $scope: $scope,
                 $element: $element,
                 $attrs: $attrs,
                 _trans: trans,
                 _screen: screen,
                 _block: _block,
                 _layout: _layout };
      augmentController(extCtrl, this, locals);
    }
    screen.$broadcast("init");
  }
  //
  // make it easier to override these functions
  var __super = this._super || {};
  this._super = angular.extend({}, __super, {
    // add any instance methods as properties of this hash
  });
}
ScreenDirectiveCtrl.$inject = ["$scope", "$element", "$attrs", "augmentController"]
ScreenDirectiveCtrl = extendLayoutCtrl(LayoutBlockBase, LayoutDisplayBase, ScreenDirectiveCtrl);

/**
 * aScreen Directive
 *
 */

 var aScreenDirective = [ "$compile", "$jQuery", function($compile, $jQuery) {
   return {
     restrict:"EA",
     scope:true,
     require:["^aLayout", "^aBlock", "aScreen"],
     controller: ScreenDirectiveCtrl,
     //////////////////
     // COMPILE
     compile:function(element, attr){
       var template = '
'+element.html()+"
";
       // var template = element.html();
       element.html("");
       //////////////
       // LINK
       return function(scope, iElement, iAttrs, controllers){
        // properties
        var screen  = controllers[2],
            block   = controllers[1],
            layout  = controllers[0],
            screenScope = scope._screen = screen.layoutScope,
            blockScope  = scope._block  = block.layoutScope,
            layoutScope = scope._layout  = layout.layoutScope,
            name = screenScope.name = block.addChild(screenScope, iAttrs.withName),
            childScope;
        //
        // Watchers and Listeners
        // add/remove template
        screenScope.$watch("displaying()", function(newval, oldval){
                          if(newval && !(/In$/).test(screenScope.transState)) {
                            toggleContent(true);
                          } else if(!newval && !(/Out$/).test(screenScope.transState)){
                            toggleContent(false);
                          }
                        });
        // watch the height of the element
        screenScope.$watch( function(){ return $jQuery(iElement).children(".a-screen-content").height(); },
                      function(newval){
                        screenScope.height = newval;
                        screenScope.contentHeight = newval;
                      } );
        // watch the width of the element
        screenScope.$watch( function(){ return $jQuery(iElement).children(".a-screen-content").width(); },
                      function(newval){
                        screenScope.width = newval;
                        screenScope.contentWidth = newval;
                      } );
        // listeners
        screenScope.$watch("transState", function(val){
          switch(val){
            case "transitionedOut":
              clearContent();
              break;
          }
        });
        //
        // Init
        // if this is first screen registered, show it
        screen.init( blockScope, layoutScope);

        var dereg = blockScope.$on("init",function(){
          if(!blockScope.currentScreen) {
            screenScope.show();
          }
          toggleContent(screenScope.displaying());
        })

        // dispose
        scope.$on("$destroy", function(){
          screen = block = layout = null;
          screenScope = blockScope = layoutScope = null;
          scope._layout = scope._block = scope._screen = null;
          dereg();
        });
        //
        // private
        function toggleContent (show) {
          if(show) {
            if(childScope){
              childScope.$destroy();
            }
            childScope = scope.$new();
            iElement.html(template);
            $compile(iElement.contents())(childScope);
            screen.transitionIn();
          } else {
            screen.transitionOut();
          }
        }
        function clearContent(){
          if (childScope) {
            childScope.$destroy();
            childScope = null;
          }
          iElement.html('');
        };
       }
     }
   }
 }]

 <commit_msg>Changed how transitions get called in screens<commit_after>'use strict';

/**
 * ScreenDirectiveCtrl
 *
 * extends LayoutBlockBase & LayoutDisplayBase
 *
 */
function ScreenDirectiveCtrl($scope, $element, $attrs, augmentController){
  var self = this,
      screen = this.layoutScope,
      trans = this.transition,
      locals,
      extCtrl = $attrs["withController"];
  //
  this.addReflowWatcher("displaying()");
  this.addReflowWatcher("calculateHeight()");
  this.addReflowWatcher("calculateWidth()");
  //
  $element.css("width","100%");
  $element.css("display","block");
  $element.css("position","absolute");
  ////////////////
  // setup the screen api
  //
  screen.calculateHeight = function(args){
    return screen.displaying() ? screen.height : 0;
  }
  //
  screen.calculateWidth = function(args){
    return screen.displaying() ? screen.width : 0;
  }
  //
  screen.show = function(name){
    var name = name || screen.name;
    $scope._block.currentScreen = name;
  }
  //
  screen.hide = function(){
    if(screen.displaying()){
      $scope._block.currentScreen = null;
    }
  }
  //
  screen.displaying = function(){
    return ($scope._block.currentScreen == screen.name);
  }
  //
  // init function get called during linking phase
  this.init = function(_block, _layout){
    // augment controller
    if(angular.isString(extCtrl) && extCtrl.length > 0) {
      locals = { $scope: $scope,
                 $element: $element,
                 $attrs: $attrs,
                 _trans: trans,
                 _screen: screen,
                 _block: _block,
                 _layout: _layout };
      augmentController(extCtrl, this, locals);
    }
    screen.$broadcast("init");
  }
  //
  // make it easier to override these functions
  var __super = this._super || {};
  this._super = angular.extend({}, __super, {
    // add any instance methods as properties of this hash
  });
}
ScreenDirectiveCtrl.$inject = ["$scope", "$element", "$attrs", "augmentController"]
ScreenDirectiveCtrl = extendLayoutCtrl(LayoutBlockBase, LayoutDisplayBase, ScreenDirectiveCtrl);

/**
 * aScreen Directive
 *
 */

 var aScreenDirective = [ "$compile", "$jQuery", function($compile, $jQuery) {
   return {
     restrict:"EA",
     scope:true,
     require:["^aLayout", "^aBlock", "aScreen"],
     controller: ScreenDirectiveCtrl,
     //////////////////
     // COMPILE
     compile:function(element, attr){
       var template = '
'+element.html()+"
";
       // var template = element.html();
       element.html("");
       //////////////
       // LINK
       return function(scope, iElement, iAttrs, controllers){
        // properties
        var screen  = controllers[2],
            block   = controllers[1],
            layout  = controllers[0],
            screenScope = scope._screen = screen.layoutScope,
            blockScope  = scope._block  = block.layoutScope,
            layoutScope = scope._layout  = layout.layoutScope,
            name = screenScope.name = block.addChild(screenScope, iAttrs.withName),
            childScope;
        //
        // Watchers and Listeners
        // add/remove template
        screenScope.$watch("displaying()", function(newval, oldval){
                          if(newval && !(/In$/).test(screenScope.transState)) {
                            toggleContent(true);
                            screen.transitionIn();
                          } else if(!newval && !(/Out$/).test(screenScope.transState)){
                            toggleContent(false);
                            screen.transitionOut();
                          }
                        });
        // watch the height of the element
        screenScope.$watch( function(){ return $jQuery(iElement).children(".a-screen-content").height(); },
                      function(newval){
                        screenScope.height = newval;
                        screenScope.contentHeight = newval;
                      } );
        // watch the width of the element
        screenScope.$watch( function(){ return $jQuery(iElement).children(".a-screen-content").width(); },
                      function(newval){
                        screenScope.width = newval;
                        screenScope.contentWidth = newval;
                      } );
        // listeners
        screenScope.$watch("transState", function(val){
          switch(val){
            case "transitionedOut":
              clearContent();
              break;
          }
        });
        //
        // Init
        // if this is first screen registered, show it
        screen.init( blockScope, layoutScope);

        var dereg = blockScope.$on("init",function(){
          if(!blockScope.currentScreen) {
            screenScope.show();
          }
          toggleContent(screenScope.displaying());
          if(screenScope.displaying()) screen.transitionIn();
        })

        // dispose
        scope.$on("$destroy", function(){
          screen = block = layout = null;
          screenScope = blockScope = layoutScope = null;
          scope._layout = scope._block = scope._screen = null;
          dereg();
        });
        //
        // private
        function toggleContent (show) {
          if(show) {
            if(childScope){
              childScope.$destroy();
            }
            childScope = scope.$new();
            iElement.html(template);
            $compile(iElement.contents())(childScope);
            // screen.transitionIn();
          } else {
            // screen.transitionOut();
          }
        }
        function clearContent(){
          if (childScope) {
            childScope.$destroy();
            childScope = null;
          }
          iElement.html('');
        };
       }
     }
   }
 }]

 <|endoftext|>


<commit_before>
var   fs = require('graceful-fs')
    , path = require('path')
    , wrench = require('wrench')
    , fse = require('fs-extra')
    , bars = require('handlebars')
    , util = require('../../util/util')

var internal = {};

exports.run = function run(flow, files) {

        //copy local project + build files

        var ignore_files = (flow.flags.files === false);

        if(!ignore_files) {
            wrench.mkdirSyncRecursive(flow.project.paths.files, 0755);
            flow.log(3, 'files - copying project files to %s', flow.project.paths.files);
            flow.log(3,'');
        }

        var project_file_path = path.resolve(flow.project.root, flow.project.paths.files);
        var projectfiles = internal.copy_files(flow, files.project_files, project_file_path, ignore_files);

        var ignore_build_files = (flow.flags['build-files'] === false);

        if(!ignore_build_files) {
            wrench.mkdirSyncRecursive(flow.project.paths.build, 0755);
            flow.log(3,'');
            flow.log(3, 'files - copying build files to %s', flow.project.paths.build);
            flow.log(3,'');
        }

        var project_build_file_path = path.resolve(flow.project.root, flow.project.paths.build);
        var buildfiles = internal.copy_files(flow, files.build_files, project_build_file_path, ignore_build_files);

        //clean up the list of files by their destination
    projectfiles.map(function(_path, i){
        _path = util.normalize(_path);
        var _root = path.resolve(flow.project.root, flow.project.paths.files);
            _root = util.normalize(_root, true);
        projectfiles[i] = _path.replace(_root,'');
    });

        //clean up the list of files by their destination
    buildfiles.map(function(_path, i){
        _path = util.normalize(_path);
        var _root = path.resolve(flow.project.root, flow.project.paths.build);
            _root = util.normalize(_root, true);
        buildfiles[i] = _path.replace(_root,'');
    });

        //store the lists
    flow.project.prepared.files.project_files_output = projectfiles;
    flow.project.prepared.files.build_files_output = buildfiles;

        //write out the asset list
        if(flow.timing) console.time('files - write files list');

    internal.write_files_list(flow);

        if(flow.timing) console.timeEnd('files - write files list');

    flow.log(3,'');
    flow.log(3,'files - done');
    flow.log(3,'');

} //run

    //in this case, verify will return a list of files
    //as a flat array of { source : dest } from prepared
exports.verify = function verify(flow, done) {

    flow.log(3, 'files - verifying ... ');

    flow.project.do_prepare(flow);

    var final_project_files = [];
    var final_build_files = [];

    var warning = '';
    var err = null;

        //check if each source exists, otherwise
        //we throw an error because this is likely
        //unexpected. this can be configured from the
        //flow : { } object in the project
    for(index in flow.project.prepared.files.project_files) {

        var file = flow.project.prepared.files.project_files[index];

        flow.log(4, 'files - checking for project file `' + file.source +'`');
        if(!fs.existsSync(file.source)) {
            warning += '       > missing files source path ' + file.source + '\n';
        } else {
            final_project_files.push(file);
        }

    } //index in prepared files

    for(index in flow.project.prepared.files.build_files) {

        var file = flow.project.prepared.files.build_files[index];

        flow.log(4, 'files - checking for build file `' + file.source +'`');
        if(!fs.existsSync(file.source)) {
            warning += '       > missing files source path ' + file.source + '\n';
        } else {
            final_build_files.push(file);
        }

    } //index in prepared build files

    var err_on_missing = flow.flags['error-on-missing'] || flow.config.build.files_error_on_missing;

    if(err_on_missing) {
        if(warning) {
            err = warning;
            flow.project.failed = true;
        }
    } else {
        if(warning) {
            internal._missing_warning(flow, warning, 'Warning');
        }
    }

    done(err, { project_files:final_project_files, build_files:final_build_files });

} //verify

internal.write_files_list = function(flow) {

    if(flow.flags.list !== false) {

        var out_name = flow.flags['list-name'] || flow.config.build.files_output_list_name;

        if(flow.config.build.files_output_list) {

            var output_path = path.join(flow.project.paths.files, out_name);
                output_path = util.normalize(output_path);

            var output = JSON.stringify(flow.project.prepared.files.project_files_output);

            if(flow.project.prepared.files.project_files_output.length > 0) {

                flow.log(3, 'files - writing file list to ' + output_path);

                fse.ensureFileSync(output_path);
                fs.writeFileSync(output_path, output, 'utf8');

            }

        } //if config

    } //no list

} //write_files_list

internal.copy_files = function(flow, files, output, no_copy) {

    var copied_list = [];

    if(files.length > 0) {

                //first deal with the files in the project itself
            for(index in files) {

                var node = files[index];
                var dest = util.normalize(path.join(output, node.dest));

                if(!no_copy) {

                    if(node.template) {

                        flow.log(3, '   copying with template %s from %s to %s%s', node.template, node.source, output, node.dest);

                        var res = internal.template_path(flow, node, dest);

                        if(!node.not_listed) {
                            copied_list = copied_list.concat( res );
                        }

                    } else {

                        flow.log(3, '   copying %s to %s%s', node.source, output, node.dest);

                        var res = util.copy_path(flow, node.source, dest);

                        if(!node.not_listed) {
                            copied_list = copied_list.concat( res );
                        }
                    }

                } else {//no_copy

                    copied_list.push( dest );

                }

            } //each project file

    } //files.length > 0

    return copied_list;

} //copy_project_files

internal.template_path = function(flow, node, dest) {

    if(fs.statSync(node.source).isDirectory()) {
        return internal.template_folder_recursively(flow, node, dest);
    } else {
        internal.template_file(flow, node.template, node.source, dest);
        return [ dest ];
    }

} //template_path

internal.template_folder_recursively = function(flow, node, _dest, _overwrite) {

    var copied_list = [];

    if(_overwrite == undefined) _overwrite = true;

        //make sure the destination exists
        //before copying any files to the location
    wrench.mkdirSyncRecursive(_dest, 0755);

        //obtain a list of items from the source
    var _source_path = node.source;
        //if a relative path from our project, make it absolute
    if(!node.source_name) {
        _source_path = util.normalize(path.resolve(flow.project.root, node.source), true);
    }

    var _source_list = wrench.readdirSyncRecursive(_source_path);

        //for each source item, check if it's a directory
    var _source_file_list = [];

    for(var i = 0; i < _source_list.length; ++i) {
        var _is_dir = fs.statSync( path.join(node.source, _source_list[i]) ).isDirectory();
        if(!_is_dir) {
            var allow = _source_list[i].charAt(0) != '.' || !flow.config.build.files_ignore_dotfiles;
            if(allow) {
              _source_file_list.push(_source_list[i]);
            }
        }
    }

        //for each file only, copy it across
    for(var i = 0; i < _source_file_list.length; ++i) {

        var _dest_file = path.join( _dest, _source_file_list[i] );
        var source_path = path.join(node.source, _source_file_list[i]);

        flow.log(3,'        - copying with template %s %s to %s', node.template, source_path, _dest_file );

        // fse.copySync( source_path, _dest_file );
        internal.template_file(flow, node.template, source_path, _dest_file);
        copied_list.push(_dest_file);

    } //each source file

    return copied_list;

} //template_folder_recursively

internal.template_file = function(flow, _template, _source, _dest) {

    var templates = [];

    var fname = path.basename(_source);
    if(fname.charAt(0) == '.') {
        flow.log(3, '        -      skip hidden file ' + _source);
        return;
    }

        //we allow multiple context nodes via ['one','two']
    if(_template.constructor == Array) {
        templates = _template;
    } else if(_template.constructor == String) {
        templates.push(_template);
    } else {
        flow.log(1, '    Warning - template value on `files` currently supports Array or String only', _source, _template );
    }

        //we wrap the context against a root for clarity in the template files
        //as well as allowing multiple contexts side by side
    var real_context = {
        debug : flow.flags.debug || false,
        arch : flow.target_arch,
        archtag : '',
        debugtag : '',
        flow : { config : flow.config }
    };

    if(flow.flags.debug) {
        real_context.debugtag = '-debug';
    }

    if(flow.target_arch == 'armv7') {
        real_context.archtag = '-v7';
    }

    for(index in templates) {
        var templ = templates[index];
        var context = flow.project.prepared.source[templ];
        if(!context) {
            flow.log(1, '    Warning - template value missing! %s was not found in the project root', templ);
        } else {
            real_context[templ] = context;
        }
    } //each templates

    var raw_file = fs.readFileSync(_source, 'utf8');

    flow.log(6, 'context for file node : ', _source, real_context);

    var template = bars.compile(raw_file);
    var templated = template( real_context );

    fse.ensureFileSync(_dest);
    fs.writeFileSync(_dest, templated, 'utf8');

} //template_file

internal._missing_warning = function(flow, msg, type) {

    var level = 3;

    if(type == 'Error') {
        level = 1;
    }

    console.log('');
    flow.log(level, '%s', type);
    flow.log(level, 'failed to find some files list in project tree!\n');
    flow.log(level, '%s', msg);

} //_missing_warning

exports.error = function(flow, err) {

    internal._missing_warning(flow, err, 'Error');

} //error

<commit_msg>flow; moving missing root template warnings to log 3<commit_after>
var   fs = require('graceful-fs')
    , path = require('path')
    , wrench = require('wrench')
    , fse = require('fs-extra')
    , bars = require('handlebars')
    , util = require('../../util/util')

var internal = {};

exports.run = function run(flow, files) {

        //copy local project + build files

        var ignore_files = (flow.flags.files === false);

        if(!ignore_files) {
            wrench.mkdirSyncRecursive(flow.project.paths.files, 0755);
            flow.log(3, 'files - copying project files to %s', flow.project.paths.files);
            flow.log(3,'');
        }

        var project_file_path = path.resolve(flow.project.root, flow.project.paths.files);
        var projectfiles = internal.copy_files(flow, files.project_files, project_file_path, ignore_files);

        var ignore_build_files = (flow.flags['build-files'] === false);

        if(!ignore_build_files) {
            wrench.mkdirSyncRecursive(flow.project.paths.build, 0755);
            flow.log(3,'');
            flow.log(3, 'files - copying build files to %s', flow.project.paths.build);
            flow.log(3,'');
        }

        var project_build_file_path = path.resolve(flow.project.root, flow.project.paths.build);
        var buildfiles = internal.copy_files(flow, files.build_files, project_build_file_path, ignore_build_files);

        //clean up the list of files by their destination
    projectfiles.map(function(_path, i){
        _path = util.normalize(_path);
        var _root = path.resolve(flow.project.root, flow.project.paths.files);
            _root = util.normalize(_root, true);
        projectfiles[i] = _path.replace(_root,'');
    });

        //clean up the list of files by their destination
    buildfiles.map(function(_path, i){
        _path = util.normalize(_path);
        var _root = path.resolve(flow.project.root, flow.project.paths.build);
            _root = util.normalize(_root, true);
        buildfiles[i] = _path.replace(_root,'');
    });

        //store the lists
    flow.project.prepared.files.project_files_output = projectfiles;
    flow.project.prepared.files.build_files_output = buildfiles;

        //write out the asset list
        if(flow.timing) console.time('files - write files list');

    internal.write_files_list(flow);

        if(flow.timing) console.timeEnd('files - write files list');

    flow.log(3,'');
    flow.log(3,'files - done');
    flow.log(3,'');

} //run

    //in this case, verify will return a list of files
    //as a flat array of { source : dest } from prepared
exports.verify = function verify(flow, done) {

    flow.log(3, 'files - verifying ... ');

    flow.project.do_prepare(flow);

    var final_project_files = [];
    var final_build_files = [];

    var warning = '';
    var err = null;

        //check if each source exists, otherwise
        //we throw an error because this is likely
        //unexpected. this can be configured from the
        //flow : { } object in the project
    for(index in flow.project.prepared.files.project_files) {

        var file = flow.project.prepared.files.project_files[index];

        flow.log(4, 'files - checking for project file `' + file.source +'`');
        if(!fs.existsSync(file.source)) {
            warning += '       > missing files source path ' + file.source + '\n';
        } else {
            final_project_files.push(file);
        }

    } //index in prepared files

    for(index in flow.project.prepared.files.build_files) {

        var file = flow.project.prepared.files.build_files[index];

        flow.log(4, 'files - checking for build file `' + file.source +'`');
        if(!fs.existsSync(file.source)) {
            warning += '       > missing files source path ' + file.source + '\n';
        } else {
            final_build_files.push(file);
        }

    } //index in prepared build files

    var err_on_missing = flow.flags['error-on-missing'] || flow.config.build.files_error_on_missing;

    if(err_on_missing) {
        if(warning) {
            err = warning;
            flow.project.failed = true;
        }
    } else {
        if(warning) {
            internal._missing_warning(flow, warning, 'Warning');
        }
    }

    done(err, { project_files:final_project_files, build_files:final_build_files });

} //verify

internal.write_files_list = function(flow) {

    if(flow.flags.list !== false) {

        var out_name = flow.flags['list-name'] || flow.config.build.files_output_list_name;

        if(flow.config.build.files_output_list) {

            var output_path = path.join(flow.project.paths.files, out_name);
                output_path = util.normalize(output_path);

            var output = JSON.stringify(flow.project.prepared.files.project_files_output);

            if(flow.project.prepared.files.project_files_output.length > 0) {

                flow.log(3, 'files - writing file list to ' + output_path);

                fse.ensureFileSync(output_path);
                fs.writeFileSync(output_path, output, 'utf8');

            }

        } //if config

    } //no list

} //write_files_list

internal.copy_files = function(flow, files, output, no_copy) {

    var copied_list = [];

    if(files.length > 0) {

                //first deal with the files in the project itself
            for(index in files) {

                var node = files[index];
                var dest = util.normalize(path.join(output, node.dest));

                if(!no_copy) {

                    if(node.template) {

                        flow.log(3, '   copying with template %s from %s to %s%s', node.template, node.source, output, node.dest);

                        var res = internal.template_path(flow, node, dest);

                        if(!node.not_listed) {
                            copied_list = copied_list.concat( res );
                        }

                    } else {

                        flow.log(3, '   copying %s to %s%s', node.source, output, node.dest);

                        var res = util.copy_path(flow, node.source, dest);

                        if(!node.not_listed) {
                            copied_list = copied_list.concat( res );
                        }
                    }

                } else {//no_copy

                    copied_list.push( dest );

                }

            } //each project file

    } //files.length > 0

    return copied_list;

} //copy_project_files

internal.template_path = function(flow, node, dest) {

    if(fs.statSync(node.source).isDirectory()) {
        return internal.template_folder_recursively(flow, node, dest);
    } else {
        internal.template_file(flow, node.template, node.source, dest);
        return [ dest ];
    }

} //template_path

internal.template_folder_recursively = function(flow, node, _dest, _overwrite) {

    var copied_list = [];

    if(_overwrite == undefined) _overwrite = true;

        //make sure the destination exists
        //before copying any files to the location
    wrench.mkdirSyncRecursive(_dest, 0755);

        //obtain a list of items from the source
    var _source_path = node.source;
        //if a relative path from our project, make it absolute
    if(!node.source_name) {
        _source_path = util.normalize(path.resolve(flow.project.root, node.source), true);
    }

    var _source_list = wrench.readdirSyncRecursive(_source_path);

        //for each source item, check if it's a directory
    var _source_file_list = [];

    for(var i = 0; i < _source_list.length; ++i) {
        var _is_dir = fs.statSync( path.join(node.source, _source_list[i]) ).isDirectory();
        if(!_is_dir) {
            var allow = _source_list[i].charAt(0) != '.' || !flow.config.build.files_ignore_dotfiles;
            if(allow) {
              _source_file_list.push(_source_list[i]);
            }
        }
    }

        //for each file only, copy it across
    for(var i = 0; i < _source_file_list.length; ++i) {

        var _dest_file = path.join( _dest, _source_file_list[i] );
        var source_path = path.join(node.source, _source_file_list[i]);

        flow.log(3,'        - copying with template %s %s to %s', node.template, source_path, _dest_file );

        // fse.copySync( source_path, _dest_file );
        internal.template_file(flow, node.template, source_path, _dest_file);
        copied_list.push(_dest_file);

    } //each source file

    return copied_list;

} //template_folder_recursively

internal.template_file = function(flow, _template, _source, _dest) {

    var templates = [];

    var fname = path.basename(_source);
    if(fname.charAt(0) == '.') {
        flow.log(3, '        -      skip hidden file ' + _source);
        return;
    }

        //we allow multiple context nodes via ['one','two']
    if(_template.constructor == Array) {
        templates = _template;
    } else if(_template.constructor == String) {
        templates.push(_template);
    } else {
        flow.log(1, '    Warning - template value on `files` currently supports Array or String only', _source, _template );
    }

        //we wrap the context against a root for clarity in the template files
        //as well as allowing multiple contexts side by side
    var real_context = {
        debug : flow.flags.debug || false,
        arch : flow.target_arch,
        archtag : '',
        debugtag : '',
        flow : { config : flow.config }
    };

    if(flow.flags.debug) {
        real_context.debugtag = '-debug';
    }

    if(flow.target_arch == 'armv7') {
        real_context.archtag = '-v7';
    }

    for(index in templates) {
        var templ = templates[index];
        var context = flow.project.prepared.source[templ];
        if(!context) {
            flow.log(3, '    Warning - template value missing! %s was not found in the project root', templ);
        } else {
            real_context[templ] = context;
        }
    } //each templates

    var raw_file = fs.readFileSync(_source, 'utf8');

    flow.log(6, 'context for file node : ', _source, real_context);

    var template = bars.compile(raw_file);
    var templated = template( real_context );

    fse.ensureFileSync(_dest);
    fs.writeFileSync(_dest, templated, 'utf8');

} //template_file

internal._missing_warning = function(flow, msg, type) {

    var level = 3;

    if(type == 'Error') {
        level = 1;
    }

    console.log('');
    flow.log(level, '%s', type);
    flow.log(level, 'failed to find some files list in project tree!\n');
    flow.log(level, '%s', msg);

} //_missing_warning

exports.error = function(flow, err) {

    internal._missing_warning(flow, err, 'Error');

} //error

<|endoftext|>


<commit_before>#!/usr/bin/env ./node_modules/.bin/babel-node
require("coffee-script/register");

var web3 = require("web3");
var path = require("path");
var fs = require("fs");
var gaze = require('gaze');
var deasync = require("deasync");
var colors = require('colors/safe');
var Init = require("./lib/init");
var Create = require("./lib/create");
var Config = require("./lib/config");
var Contracts = require("./lib/contracts");
var Build = require("./lib/build");
var Test = require("./lib/test");
var Exec = require("./lib/exec");
var Repl = require("./lib/repl");
var Serve = require("./lib/serve");

var ConfigurationError = require("./lib/errors/configurationerror");
var ExtendableError = require("./lib/errors/extendableerror");

var truffle_dir = process.env.TRUFFLE_NPM_LOCATION;
var working_dir = process.env.TRUFFLE_WORKING_DIRECTORY;

var argv = require('yargs').argv;
var pkg = JSON.parse(fs.readFileSync(path.join(truffle_dir, "package.json"), {encoding: "utf8"}));

var tasks = {};
var registerTask = function(name, description, fn) {
  tasks[name] = {
    name: name,
    description: description,
    fn: fn
  };
}

var printSuccess = function() {
  console.log(colors.green(`Completed without errors on ${new Date().toString()}`));
};

var printFailure = function() {
  console.log(colors.red(`Completed with errors on ${new Date().toString()}`));
};

var runTask = function(name) {
  try {
    var fn = deasync(tasks[name].fn);
    fn();
    return 0;
  } catch (e) {
    if (e instanceof ExtendableError) {
      console.log(e.message);

      if (argv.stack != null) {
        console.log(e.stack);
      }

    } else {
      // Bubble up all other unexpected errors.
      console.log(e.stack || e.toString());
    }
    return 1;
  }
};

registerTask('watch', "Watch filesystem for changes and rebuild the project automatically", function(done) {
  var needs_rebuild = true;
  // var needs_redeploy = false;

  gaze(["app/**/*", "config/**/*", "contracts/**/*"], {cwd: working_dir, interval: 1000, debounceDelay: 500}, function() {
    // On changed/added/deleted
    this.on('all', function(event, filePath) {
      var display_path = path.join("./", filePath.replace(working_dir, ""));
      console.log(colors.cyan(`>> File ${display_path} changed.`));

      needs_rebuild = true;

      // if (display_path.indexOf("contracts/") == 0) {
      //   needs_redeploy = true;
      // } else {
      //   needs_rebuild = true;
      // }
    });
  });

  var check_rebuild = function() {
    // if (needs_redeploy == true) {
    //   needs_redeploy = false;
    //   needs_rebuild = false;
    //   console.log("Redeploying...");
    //   if (runTask("deploy") != 0) {
    //     printFailure();
    //   }
    // }

    if (needs_rebuild == true) {
      needs_rebuild = false;
      console.log("Rebuilding...");
      if (runTask("build") != 0) {
        printFailure();
      }
    }

    setTimeout(check_rebuild, 500);
  };

  setInterval(check_rebuild, 500);
});

registerTask('list', "List all available tasks", function(done) {
  console.log("Truffle v" + pkg.version + " - a development framework for Ethereum");
  console.log("");
  console.log("Usage: truffle [command] [options]");
  console.log("");
  console.log("Commands:");
  console.log("");

  var sorted = Object.keys(tasks).sort();

  var longestTask = sorted.reduce(function(a, b) {
    var first = typeof a == "string" ? a.length : a;
    return Math.max(first, b.length);
  });

  for (var i = 0; i < sorted.length; i++) {
    var task = tasks[sorted[i]];
    var heading = task.name;
    while (heading.length < longestTask) {
      heading += " ";
    }
    console.log("  " + heading + " => " + task.description)
  }

  console.log("");
  done();
});

registerTask('version', "Show version number and exit", function(done) {
  console.log("Truffle v" + pkg.version);
  done();
});

registerTask('init', "Initialize new Ethereum project, including example contracts and tests", function(done) {
  var config = Config.gather(truffle_dir, working_dir, argv);
  Init.all(config, done);
});

registerTask('init:contracts', "Initialize default contracts directory", function(done) {
  var config = Config.gather(truffle_dir, working_dir, argv);
  Init.contracts(config, done);
});

registerTask('init:config', "Initialize default project configuration", function(done) {
  var config = Config.gather(truffle_dir, working_dir, argv);
  Init.config(config, done);
});

registerTask('init:tests', "Initialize tests directory structure and helpers", function(done) {
  var config = Config.gather(truffle_dir, working_dir, argv);
  Init.tests(config, done);
});

registerTask('create:contract', "Create a basic contract", function(done) {
  var config = Config.gather(truffle_dir, working_dir, argv);

  var name = argv.name;

  if (name == null && argv._.length > 1) {
    name = argv._[1];
  }

  if (name == null) {
    throw new ConfigurationError("Please specify a name. Example: truffle create:contract MyContract");
  } else {
    Create.contract(config, name, done);
  }
});

registerTask('create:test', "Create a basic test", function(done) {
  var config = Config.gather(truffle_dir, working_dir, argv);

  var name = argv.name;

  if (name == null && argv._.length > 1) {
    name = argv._[1];
  }

  if (name == null) {
    throw new ConfigurationError("Please specify a name. Example: truffle create:test MyTest");
  } else {
    Create.test(config, name, done);
  }
});

registerTask('resolve', "Resolve dependencies in contract file and print result", function(done) {
  var config = Config.gather(truffle_dir, working_dir, argv, "development");

  var file = argv.file;

  if (file == null && argv._.length > 1) {
    file = argv._[1];
  }

  if (file == null) {
    throw new ConfigurationError("Please specify a contract file. Example: truffle resolve ./contracts/Example.sol");
  } else {
    file = path.resolve(file);

    var code;

    try {
      code = Contracts.resolve(file);
    } catch (e) {
      done(e);
      return;
    }

    console.log(code);
    done();
  }
});

registerTask('compile', "Compile contracts", function(done) {
  var config = Config.gather(truffle_dir, working_dir, argv, "development");
  Contracts.compile(config, done);
});

registerTask('deploy', "Deploy contracts to the network", function(done) {
  var config = Config.gather(truffle_dir, working_dir, argv, "development");

  console.log("Using environment " + config.environment + ".");

  // Compile and deploy.
  Contracts.deploy(config, true, function(err) {
    if (err != null) {
      done(err);
    } else {
      console.log("Rebuilding app with new contracts...");
      runTask("build");
      done();
    }
  });
});

registerTask('build', "Build development version of app; creates ./build directory", function(done) {
  var config = Config.gather(truffle_dir, working_dir, argv, "development");
  Build.build(config, function(err) {
    done(err);
    if (err == null) {
      printSuccess();
    }
  });
});

registerTask('dist', "Create distributable version of app (minified); creates ./dist directory", function(done) {
  var config = Config.gather(truffle_dir, working_dir, argv, "production");
  console.log("Using environment " + config.environment + ".");
  Build.dist(config, function(err) {
    done(err);
    if (err == null) {
      printSuccess();
    }
  });
});

registerTask('exec', "Execute a Coffee/JS file within truffle environment. Script *must* call process.exit() when finished.", function(done) {
  var config = Config.gather(truffle_dir, working_dir, argv, "development");

  var file = argv.file;

  if (file == null && argv._.length > 1) {
    file = argv._[1];
  }

  if (file == null) {
    console.log("Please specify a file, passing the path of the script you'd like the run. Note that all scripts *must* call process.exit() when finished.");
    done();
    return;
  }

  Exec.file(config, file);
});

// Supported options:
// --no-color: Disable color
// More to come.
registerTask('test', "Run tests", function(done) {
  var config = Config.gather(truffle_dir, working_dir, argv, "test");

  console.log("Using environment " + config.environment + ".");

  // Ensure we're quiet about deploys during tests.
  config.argv.quietDeploy = true;

  var file = argv.file;

  if (file == null && argv._.length > 1) {
    file = argv._[1];
  }

  if (file == null) {
    Test.run(config, done);
  } else {
    if (path.isAbsolute(file) == false) {
      file = path.resolve(file);
    }

    Test.run(config, file, done);
  }

});

registerTask('console', "Run a console with deployed contracts instanciated and available (REPL)", function(done) {
  var config = Config.gather(truffle_dir, working_dir, argv, "development");
  Repl.run(config, done);
});

registerTask('serve', "Serve app on http://localhost:8080 and rebuild changes as needed", function(done) {
  var config = Config.gather(truffle_dir, working_dir, argv, "development");
  console.log("Using environment " + config.environment + ".");
  Serve.start(config, function() {
    runTask("watch");
  });
});

// Default to listing available commands.
var current_task = argv._[0];

if (current_task == null) {
  current_task = "list";
}

if (tasks[current_task] == null) {
  console.log(colors.red("Unknown command: " + current_task));
  process.exit(1);
}

// Something is keeping the process open. I'm not sure what.
// Let's explicitly kill it until I can figure it out.
process.exit(runTask(current_task));
//runTask(current_task);
<commit_msg>Recompile and redeploy when contracts are changed using watch/serve. Don't explicitly rebuild after deploy as watch/serve will pick that up automatically now.<commit_after>#!/usr/bin/env ./node_modules/.bin/babel-node
require("coffee-script/register");

var web3 = require("web3");
var path = require("path");
var fs = require("fs");
var gaze = require('gaze');
var deasync = require("deasync");
var colors = require('colors/safe');
var Init = require("./lib/init");
var Create = require("./lib/create");
var Config = require("./lib/config");
var Contracts = require("./lib/contracts");
var Build = require("./lib/build");
var Test = require("./lib/test");
var Exec = require("./lib/exec");
var Repl = require("./lib/repl");
var Serve = require("./lib/serve");

var ConfigurationError = require("./lib/errors/configurationerror");
var ExtendableError = require("./lib/errors/extendableerror");

var truffle_dir = process.env.TRUFFLE_NPM_LOCATION;
var working_dir = process.env.TRUFFLE_WORKING_DIRECTORY;

var argv = require('yargs').argv;
var pkg = JSON.parse(fs.readFileSync(path.join(truffle_dir, "package.json"), {encoding: "utf8"}));

var tasks = {};
var registerTask = function(name, description, fn) {
  tasks[name] = {
    name: name,
    description: description,
    fn: fn
  };
}

var printSuccess = function() {
  console.log(colors.green(`Completed without errors on ${new Date().toString()}`));
};

var printFailure = function() {
  console.log(colors.red(`Completed with errors on ${new Date().toString()}`));
};

var runTask = function(name) {
  try {
    var fn = deasync(tasks[name].fn);
    fn();
    return 0;
  } catch (e) {
    if (e instanceof ExtendableError) {
      console.log(e.message);

      if (argv.stack != null) {
        console.log(e.stack);
      }

    } else {
      // Bubble up all other unexpected errors.
      console.log(e.stack || e.toString());
    }
    return 1;
  }
};

registerTask('watch', "Watch filesystem for changes and rebuild the project automatically", function(done) {
  var needs_rebuild = true;
  var needs_redeploy = false;

  gaze(["app/**/*", "config/**/*", "contracts/**/*"], {cwd: working_dir, interval: 1000, debounceDelay: 500}, function() {
    // On changed/added/deleted
    this.on('all', function(event, filePath) {
      var display_path = path.join("./", filePath.replace(working_dir, ""));
      console.log(colors.cyan(`>> File ${display_path} changed.`));

      needs_rebuild = true;

      if (display_path.indexOf("contracts/") == 0) {
        needs_redeploy = true;
      } else {
        needs_rebuild = true;
      }
    });
  });

  var check_rebuild = function() {
    if (needs_redeploy == true) {
      needs_redeploy = false;
      needs_rebuild = false;
      console.log("Redeploying...");
      if (runTask("deploy") != 0) {
        printFailure();
      }
    }

    if (needs_rebuild == true) {
      needs_rebuild = false;
      console.log("Rebuilding...");
      if (runTask("build") != 0) {
        printFailure();
      }
    }

    setTimeout(check_rebuild, 500);
  };

  setInterval(check_rebuild, 500);
});

registerTask('list', "List all available tasks", function(done) {
  console.log("Truffle v" + pkg.version + " - a development framework for Ethereum");
  console.log("");
  console.log("Usage: truffle [command] [options]");
  console.log("");
  console.log("Commands:");
  console.log("");

  var sorted = Object.keys(tasks).sort();

  var longestTask = sorted.reduce(function(a, b) {
    var first = typeof a == "string" ? a.length : a;
    return Math.max(first, b.length);
  });

  for (var i = 0; i < sorted.length; i++) {
    var task = tasks[sorted[i]];
    var heading = task.name;
    while (heading.length < longestTask) {
      heading += " ";
    }
    console.log("  " + heading + " => " + task.description)
  }

  console.log("");
  done();
});

registerTask('version', "Show version number and exit", function(done) {
  console.log("Truffle v" + pkg.version);
  done();
});

registerTask('init', "Initialize new Ethereum project, including example contracts and tests", function(done) {
  var config = Config.gather(truffle_dir, working_dir, argv);
  Init.all(config, done);
});

registerTask('init:contracts', "Initialize default contracts directory", function(done) {
  var config = Config.gather(truffle_dir, working_dir, argv);
  Init.contracts(config, done);
});

registerTask('init:config', "Initialize default project configuration", function(done) {
  var config = Config.gather(truffle_dir, working_dir, argv);
  Init.config(config, done);
});

registerTask('init:tests', "Initialize tests directory structure and helpers", function(done) {
  var config = Config.gather(truffle_dir, working_dir, argv);
  Init.tests(config, done);
});

registerTask('create:contract', "Create a basic contract", function(done) {
  var config = Config.gather(truffle_dir, working_dir, argv);

  var name = argv.name;

  if (name == null && argv._.length > 1) {
    name = argv._[1];
  }

  if (name == null) {
    throw new ConfigurationError("Please specify a name. Example: truffle create:contract MyContract");
  } else {
    Create.contract(config, name, done);
  }
});

registerTask('create:test', "Create a basic test", function(done) {
  var config = Config.gather(truffle_dir, working_dir, argv);

  var name = argv.name;

  if (name == null && argv._.length > 1) {
    name = argv._[1];
  }

  if (name == null) {
    throw new ConfigurationError("Please specify a name. Example: truffle create:test MyTest");
  } else {
    Create.test(config, name, done);
  }
});

registerTask('resolve', "Resolve dependencies in contract file and print result", function(done) {
  var config = Config.gather(truffle_dir, working_dir, argv, "development");

  var file = argv.file;

  if (file == null && argv._.length > 1) {
    file = argv._[1];
  }

  if (file == null) {
    throw new ConfigurationError("Please specify a contract file. Example: truffle resolve ./contracts/Example.sol");
  } else {
    file = path.resolve(file);

    var code;

    try {
      code = Contracts.resolve(file);
    } catch (e) {
      done(e);
      return;
    }

    console.log(code);
    done();
  }
});

registerTask('compile', "Compile contracts", function(done) {
  var config = Config.gather(truffle_dir, working_dir, argv, "development");
  Contracts.compile(config, done);
});

registerTask('deploy', "Deploy contracts to the network", function(done) {
  var config = Config.gather(truffle_dir, working_dir, argv, "development");

  console.log("Using environment " + config.environment + ".");

  // Compile and deploy.
  Contracts.deploy(config, true, function(err) {
    if (err != null) {
      done(err);
    } else {
      // console.log("Rebuilding app with new contracts...");
      // runTask("build");
      done();
    }
  });
});

registerTask('build', "Build development version of app; creates ./build directory", function(done) {
  var config = Config.gather(truffle_dir, working_dir, argv, "development");
  Build.build(config, function(err) {
    done(err);
    if (err == null) {
      printSuccess();
    }
  });
});

registerTask('dist', "Create distributable version of app (minified); creates ./dist directory", function(done) {
  var config = Config.gather(truffle_dir, working_dir, argv, "production");
  console.log("Using environment " + config.environment + ".");
  Build.dist(config, function(err) {
    done(err);
    if (err == null) {
      printSuccess();
    }
  });
});

registerTask('exec', "Execute a Coffee/JS file within truffle environment. Script *must* call process.exit() when finished.", function(done) {
  var config = Config.gather(truffle_dir, working_dir, argv, "development");

  var file = argv.file;

  if (file == null && argv._.length > 1) {
    file = argv._[1];
  }

  if (file == null) {
    console.log("Please specify a file, passing the path of the script you'd like the run. Note that all scripts *must* call process.exit() when finished.");
    done();
    return;
  }

  Exec.file(config, file);
});

// Supported options:
// --no-color: Disable color
// More to come.
registerTask('test', "Run tests", function(done) {
  var config = Config.gather(truffle_dir, working_dir, argv, "test");

  console.log("Using environment " + config.environment + ".");

  // Ensure we're quiet about deploys during tests.
  config.argv.quietDeploy = true;

  var file = argv.file;

  if (file == null && argv._.length > 1) {
    file = argv._[1];
  }

  if (file == null) {
    Test.run(config, done);
  } else {
    if (path.isAbsolute(file) == false) {
      file = path.resolve(file);
    }

    Test.run(config, file, done);
  }

});

registerTask('console', "Run a console with deployed contracts instanciated and available (REPL)", function(done) {
  var config = Config.gather(truffle_dir, working_dir, argv, "development");
  Repl.run(config, done);
});

registerTask('serve', "Serve app on http://localhost:8080 and rebuild changes as needed", function(done) {
  var config = Config.gather(truffle_dir, working_dir, argv, "development");
  console.log("Using environment " + config.environment + ".");
  Serve.start(config, function() {
    runTask("watch");
  });
});

// Default to listing available commands.
var current_task = argv._[0];

if (current_task == null) {
  current_task = "list";
}

if (tasks[current_task] == null) {
  console.log(colors.red("Unknown command: " + current_task));
  process.exit(1);
}

// Something is keeping the process open. I'm not sure what.
// Let's explicitly kill it until I can figure it out.
process.exit(runTask(current_task));
//runTask(current_task);
<|endoftext|>


<commit_before>/**
 * @license
 * Copyright 2017 The FOAM Authors. All Rights Reserved.
 * http://www.apache.org/licenses/LICENSE-2.0
 */

foam.CLASS({
  package: 'foam.nanos.menu',
  name: 'ViewMenu',

  properties: [
    {
      class: 'foam.u2.ViewSpec',
      name: 'view'
    }
  ],

  methods: [
    function execute(X) {
      X.stack.push(this.view);
    }
  ]
});

foam.CLASS({
  package: 'foam.nanos.menu',
  name: 'DAOMenu',

  properties: [
    {
      class: 'String',
      name: 'daoKey'
    }
  ],

  methods: [
    function execute(X) {
      X.stack.push({class: 'foam.u2.ListCreateController', dao: X[this.daoKey]});
    }
  ]
});

foam.CLASS({
  package: 'foam.nanos.menu',
  name: 'Menu',

  properties: [
    {
      class: 'String',
      name: 'id'
    },
    {
      class: 'String',
      name: 'label'
    },
    {
      class: 'FObjectProperty',
      name: 'handler'
    }
  ],

  actions: [
    {
      name: 'launch',
      code: function(X) {
        console.log('MENU: ', this.id);
        this.handler && this.handler.execute(X);
      }
    }
  ]
});

foam.RELATIONSHIP({
  sourceModel: 'foam.nanos.menu.Menu',
  targetModel: 'foam.nanos.menu.Menu',
  forwardName: 'children',
  inverseName: 'parent',
  sourceProperty: {
    hidden: true
  },
  targetProperty: {
    class: 'String',
    value: ''
  }
});
<commit_msg>More Menu support.<commit_after>/**
 * @license
 * Copyright 2017 The FOAM Authors. All Rights Reserved.
 * http://www.apache.org/licenses/LICENSE-2.0
 */

foam.CLASS({
  package: 'foam.nanos.menu',
  name: 'ViewMenu',

  properties: [
    {
      class: 'foam.u2.ViewSpec',
      name: 'view'
    }
  ],

  methods: [
    function createView(X) { return this.view; }
  ]
});

foam.CLASS({
  package: 'foam.nanos.menu',
  name: 'DAOMenu',

  properties: [
    {
      class: 'String',
      name: 'daoKey'
    }
  ],

  methods: [
    function createView(X) {
      return { class: 'foam.u2.ListCreateController', dao: X[this.daoKey] };
    }
  ]
});

foam.CLASS({
  package: 'foam.nanos.menu',
  name: 'TabsMenu',

  properties: [
    {
      class: 'String',
      name: 'daoKey'
    }
  ],

  methods: [
    function createView(X, menu) {
      var tabs = foam.u2.Tabs.create();

      X.stack.push(tabs);

      menu.children.select({
        put: function(menu) {
          console.log(menu.label);
          if ( menu.handler )
          tabs.start({class: 'foam.u2.Tab', label: menu.label})
            .tag((menu.handler && menu.handler.createView(X, menu)) || 'Coming Soon!')
          .end();
        },
        eof: function() {}
      });

      return tabs;
    }
  ]
});

foam.CLASS({
  package: 'foam.nanos.menu',
  name: 'Menu',

  properties: [
    {
      class: 'String',
      name: 'id'
    },
    {
      class: 'String',
      name: 'label'
    },
    {
      class: 'FObjectProperty',
      name: 'handler'
    }
  ],

  actions: [
    {
      name: 'launch',
      code: function(X) {
        console.log('MENU: ', this.id);
        this.handler && X.stack.push(this.handler.createView(X, this));
      }
    }
  ]
});

foam.RELATIONSHIP({
  sourceModel: 'foam.nanos.menu.Menu',
  targetModel: 'foam.nanos.menu.Menu',
  forwardName: 'children',
  inverseName: 'parent',
  sourceProperty: {
    hidden: true
  },
  targetProperty: {
    class: 'String',
    value: ''
  }
});
<|endoftext|>


<commit_before>/**
 * @license
 * Copyright 2017 The FOAM Authors. All Rights Reserved.
 * http://www.apache.org/licenses/LICENSE-2.0
 */

foam.CLASS({
  package: 'foam.nanos.test',
  name: 'Test',
  extends: 'foam.nanos.script.Script',

  javaImports: [
    'bsh.EvalError',
    'bsh.Interpreter',
    'foam.nanos.pm.PM',
    'java.io.ByteArrayOutputStream',
    'java.io.PrintStream',
    'java.util.Date'
  ],

  tableColumns: [
    'id', 'enabled', 'description', 'passed', 'failed', 'run'
  ],

  searchColumns: [ ],

  properties: [
    'id',
    {
      class: 'Int',
      name: 'passed'
    },
    {
      class: 'Int',
      name: 'failed'
    }
  ],

  methods: [
    {
      name: 'runScript',
      args: [
        {
          name: 'x', javaType: 'foam.core.X'
        }
      ],
      javaReturns: 'void',
      javaCode: `
        ByteArrayOutputStream baos  = new ByteArrayOutputStream();
        PrintStream           ps    = new PrintStream(baos);
        Interpreter           shell = new Interpreter();
        PM                    pm    = new PM(this.getClass(), getId());

System.err.println("************************** Test: " + getCode());
        try {
          shell.set("currentTest", this);
          setPassed(0);
          setFailed(0);
          setOutput("");
          shell.set("x", getX());
          shell.setOut(ps);

          // creates the testing method
          shell.eval("test(boolean exp, String message) { if ( exp ) { currentTest.setPassed(currentTest.getPassed()+1); } else { currentTest.setFailed(currentTest.getFailed()+1); } print((exp ? \\"SUCCESS: \\" : \\"FAILURE: \\")+message);}");
          shell.eval(getCode());
        } catch (EvalError e) {
          e.printStackTrace();
        } finally {
          pm.log(x);
        }

        setLastRun(new Date());
        ps.flush();
        System.err.println("******************** Output: " + this.getPassed() + " " + this.getFailed() + " " + baos.toString());
        setOutput(baos.toString());
    `
    }
  ]
});
<commit_msg>Fixed bug in Test run action was using scriptDAO.<commit_after>/**
 * @license
 * Copyright 2017 The FOAM Authors. All Rights Reserved.
 * http://www.apache.org/licenses/LICENSE-2.0
 */

foam.CLASS({
  package: 'foam.nanos.test',
  name: 'Test',
  extends: 'foam.nanos.script.Script',

  imports: [ 'testDAO as scriptDAO' ],

  javaImports: [
    'bsh.EvalError',
    'bsh.Interpreter',
    'foam.nanos.pm.PM',
    'java.io.ByteArrayOutputStream',
    'java.io.PrintStream',
    'java.util.Date'
  ],

  tableColumns: [
    'id', 'enabled', 'description', 'passed', 'failed', 'run'
  ],

  searchColumns: [ ],

  properties: [
    'id',
    {
      class: 'Int',
      name: 'passed'
    },
    {
      class: 'Int',
      name: 'failed'
    }
  ],

  methods: [
    {
      name: 'runScript',
      args: [
        {
          name: 'x', javaType: 'foam.core.X'
        }
      ],
      javaReturns: 'void',
      javaCode: `
        ByteArrayOutputStream baos  = new ByteArrayOutputStream();
        PrintStream           ps    = new PrintStream(baos);
        Interpreter           shell = new Interpreter();
        PM                    pm    = new PM(this.getClass(), getId());

System.err.println("************************** Test: " + getCode());
        try {
          shell.set("currentTest", this);
          setPassed(0);
          setFailed(0);
          setOutput("");
          shell.set("x", getX());
          shell.setOut(ps);

          // creates the testing method
          shell.eval("test(boolean exp, String message) { if ( exp ) { currentTest.setPassed(currentTest.getPassed()+1); } else { currentTest.setFailed(currentTest.getFailed()+1); } print((exp ? \\"SUCCESS: \\" : \\"FAILURE: \\")+message);}");
          shell.eval(getCode());
        } catch (EvalError e) {
          e.printStackTrace();
        } finally {
          pm.log(x);
        }

        setLastRun(new Date());
        ps.flush();
        System.err.println("******************** Output: " + this.getPassed() + " " + this.getFailed() + " " + baos.toString());
        setOutput(baos.toString());
    `
    }
  ]
});
<|endoftext|>