<commit_before>var Games = require("./games");
var MatchClock = require("../utilities/timer/match_clock");
var Timers = require("../utilities/timer/timers");
var EventDispatcher = require("../event_dispatcher");

function FailedToJoinMatchError(player, matchup, reason) {
  this.message = "User '" + player.username + "' cannot join matchup '" + matchup.id + "'";
  if (reason) {
    this.message += " because " + reason + ".";
  } else {
    this.message += ".";
  }
  this.stack = (new Error()).stack;
}
FailedToJoinMatchError.prototype = Object.create(Error.prototype);

////////////////////////////////////////

// Possible player messages
const PLAY = "play";
const UPDATE = "update";
const ERROR = "error-message";

// Possible events
const EVENT_UPDATE = "match_event_update"
const EVENT_END = "match_event_end"

function onPlay(match, player) {
  return function(data) {
    if (data.matchID != match.id) {
      return;
    }
    var timestamp = Date.now();
    status = match._getStatus();
    var game = match._game;
    var amP1 = player.isSameUser(match._p1);
    var amP2 = player.isSameUser(match._p2);
    if (status == match.STATUS.NOT_STARTED) {
      player.emit(ERROR, {error: "The game hasn't started yet."});
      return;
    } else if (status == match.STATUS.COMPLETED) {
      player.emit(ERROR, {error: "The game is already over."});
      return;
    } else if (amP1 || amP2) {
      if (data.player == 0 && !amP1) {
        player.emit(ERROR, {error: "You cannot play as P1."});
        return;
      }
      if (data.player == 1 && !amP2) {
        player.emit(ERROR, {error: "You cannot play as P2."});
        return;
      }
      var error = match._makeMove(data.move, data.player, timestamp);
      if (error) {
        player.emit(ERROR, {error: error});
      }
    } else {
      player.emit(ERROR, {error: "You are not playing in this game."});
    }
  };
}

function Matchup(id, matchSettings) {
  var self = this;
  this.id = id;

  this._settings = matchSettings;
  //this._p1Timer = Timers.newTimer(matchSettings.p1Timer);
  //this._p2Timer = Timers.newTimer(matchSettings.p2Timer);
  //this._clock = new MatchClock(this._p1Timer, this._p2Timer);
  this._game = Games.newGame(matchSettings.gameName, matchSettings.gameSettings);
  this._p1 = null;
  this._p2 = null;
  this._spectators = [];
  // List of players that we are currently listening to for moves.
  this._players = [];
  this._dispatcher = new EventDispatcher();
}

module.exports = Matchup;

Matchup.prototype.MESSAGES = {
  PLAY: PLAY,
  UPDATE: UPDATE,
  ERROR: ERROR
};

Matchup.prototype.STATUS = {
  NOT_STARTED: "NOT_STARTED",
  ONGOING: "ONGOING",
  COMPLETED: "COMPLETED"
};

Matchup.prototype.ERRORS = {
  FAILED_TO_JOIN_MATCH : FailedToJoinMatchError
};

Matchup.prototype.onMatchUpdate = function(callback) {
  return this._dispatcher.on(EVENT_UPDATE, callback);
};

Matchup.prototype.onMatchEnd = function(callback) {
  return this._dispatcher.on(EVENT_END, callback);
};

Matchup.prototype.isCurrentlyPlaying = function(player) {
  return player.isSameUser(this._p1) || player.isSameUser(this._p2);
};

Matchup.prototype.hasStarted = function() {
  return this._p1 != null && this._p2 != null;
};

Matchup.prototype.addPlayer = function(player, seat) {
  if (!player) {
    throw new FailedToJoinMatchError(player, this, "player must not be null");
  }
  if (seat != 1 && seat != 2 && seat != 3) {
    throw new Error("'seat' must be 1, 2, or 3.");
  }
  if (seat == 3) {
    this._addPlayerToSpectators(player, true);
  } else {
    var sittingPlayer = seat == 1 ? this._p1 : this._p2;
    if (!sittingPlayer) {
      this._setPlayer(player, seat);
    } else if (player.isSameUser(sittingPlayer)) {
      this._addPlayerToSpectators(player, true)
    } else {
      // The seat is already taken.
      throw new FailedToJoinMatchError(player, this, "seat " + seat + " is already occupied.");
    }
  }
};

Matchup.prototype.matchInfo = function() {
  var info = {};
  info.matchID = this.id;
  info.gameName = this._settings.gameName;
  info.settings = this._settings;
  info.p1 = this._p1 ? {identifier: this._p1.identifier, username: this._p1.username} : null;
  info.p2 = this._p2 ? {identifier: this._p2.identifier, username: this._p2.username} : null;
  return info;
};

////////// Private

Matchup.prototype._makeMove = function(move, playerNumber, timestamp) {
  var didTurnAdvance = false;
  try {
    didTurnAdvance = this._game.playMove(move, playerNumber);
  } catch (error) {
    return "Error while trying to make a move: " + error.message;
  }
  // Ignore timers for now
  // this._clock.toggle(timestamp);
  if (didTurnAdvance) {
    this._broadcastLatestEvents(timestamp);
    this._checkIfOver();
  }
};

Matchup.prototype._dataForUpdate = function() {
  var data = {};
  data.gameName = this._settings.gameName;
  data.status = this._getStatus();
  data.settings = this._settings;
  // Ignor timers for now
  // data.timers = {
  //   p1: this._p1Timer.exportState(),
  //   p2: this._p2Timer.exportState(),
  // }
  data.players = [];
  if (this._p1) {
    data.players.push({
      username: this._p1.username,
      identifier: this._p1.identifier
    });
  } else {
    data.players.push(null);
  }
  if (this._p2) {
    data.players.push({
      username: this._p2.username,
      identifier: this._p2.identifier
    });
  } else {
    data.players.push(null);
  }
  data.matchID = this.id;
  data.toPlay = Array.from(this._game.getPlayersToPlay());
  return data;
};

Matchup.prototype._addPlayerToSpectators = function(player, shouldSendUpdtate) {
  var self = this;
  if (this._spectators.indexOf(player) == -1) {
    this._spectators.push(player);
  }
  if (player.isSameUser(this._p1) || player.isSameUser(this._p2)) {
    if (this._players.indexOf(player) == -1) {
      player.on(PLAY, onPlay(this, player));
      this._players.push(player);
    }
  }
  player.on("disconnect", function() {
    var index = self._spectators.indexOf(player);
    if (index > -1) {
      self._spectators.splice(self._spectators.indexOf(player), 1);
    }
  });
  if (shouldSendUpdtate) {
    var data = this._dataForUpdate();
    var amP1 = player.isSameUser(this._p1)
    var amP2 = player.isSameUser(this._p2)
    data.updates = this._game.getAllUpdates().map((update) => {
      return updateAsSeenBy(update, amP1, amP2);
    });
    player.emit(UPDATE, data);
  }
};

Matchup.prototype._setPlayer = function(player, seat) {
  if (seat != 1 && seat != 2) {
    throw new Error("'seat' should be 1 or 2.");
  }
  var wasPreviouslyStarted = this.hasStarted();
  if (seat == 1) {
    this._p1 = player;
  } else if (seat == 2) {
    this._p2 = player;
  }
  if (this.hasStarted() && !wasPreviouslyStarted) {
    this._game.start();
    //this._clock.start(Date.now());
    //this._startCheckingTime();
  }
  this._addPlayerToSpectators(player, false);
  this._triggerUpdate();
};

// Notify everyone that the status of this match has changed
Matchup.prototype._triggerUpdate = function() {
  this._broadcastCurrentState();
  this._dispatcher.dispatchEvent(EVENT_UPDATE, this._dataForUpdate());
};

Matchup.prototype._broadcastLatestEvents = function(timestamp) {
  var latestUpdate = this._game.getLatestUpdate();
  var data = {
    matchID: this.id,
    status: this._getStatus(timestamp),
    toPlay: Array.from(this._game.getPlayersToPlay()),
    timestamp: timestamp
  }
  for (var i = 0; i < this._spectators.length; ++i) {
    var spectator = this._spectators[i];
    var amP1 = spectator.isSameUser(this._p1)
    var amP2 = spectator.isSameUser(this._p2)
    // Right now only support 2 player games are supported.
    data.update = updateAsSeenBy(latestUpdate, amP1, amP2);
    spectator.emit(PLAY, data);
  }
}

Matchup.prototype._broadcastCurrentState = function() {
  var events = this._game.getAllUpdates();
  var data = this._dataForUpdate();
  for (var i = 0; i < this._spectators.length; ++i) {
    var spectator = this._spectators[i];
    var amP1 = spectator.isSameUser(this._p1)
    var amP2 = spectator.isSameUser(this._p2)
    data.updates = events.map((currentValue) => {
      return updateAsSeenBy(currentValue, amP1, amP2);
    });
    spectator.emit(UPDATE, data);
  }
}

Matchup.prototype._checkIfOver = function() {
  var timestamp = Date.now();
  var status = this._getStatus(timestamp);
  var result = null;
  if (status == this.STATUS.COMPLETED) {
    var winners = this._game.getWinners();
    if (winners.has(0)) {
      result = "P1";
    } else if (winners.has(1)) {
      result = "P2";
    } else {
      result = "DRAW";
    }
  }
  if (result) {
    this._triggerUpdate();
    this._dispatcher.dispatchEvent(EVENT_END, {result: result});
  }
};

Matchup.prototype._getStatus = function() {
  if (!this.hasStarted()) {
    return this.STATUS.NOT_STARTED;
  }
  return this._game.getPlayersToPlay().size ? this.STATUS.ONGOING :this.STATUS.COMPLETED;
};

function updateAsSeenBy(update, amP1, amP2) {
  if (!update) {
    return null;
  }
  var newUpdate = {
    publicInfo: update.publicInfo
  }
  if (update.privateInfo && (amP1 || amP2)) {
    newUpdate.privateInfo = update.privateInfo.map((currentValue, index) => {
      if (index == 0 && amP1 || index == 1 && amP2) {
        currentValue
      }
      return null;
    });
  }
  return newUpdate;
}
<commit_msg>Don't need to specify the player if the user is only playing as one of the players<commit_after>var Games = require("./games");
var MatchClock = require("../utilities/timer/match_clock");
var Timers = require("../utilities/timer/timers");
var EventDispatcher = require("../event_dispatcher");

function FailedToJoinMatchError(player, matchup, reason) {
  this.message = "User '" + player.username + "' cannot join matchup '" + matchup.id + "'";
  if (reason) {
    this.message += " because " + reason + ".";
  } else {
    this.message += ".";
  }
  this.stack = (new Error()).stack;
}
FailedToJoinMatchError.prototype = Object.create(Error.prototype);

////////////////////////////////////////

// Possible player messages
const PLAY = "play";
const UPDATE = "update";
const ERROR = "error-message";

// Possible events
const EVENT_UPDATE = "match_event_update"
const EVENT_END = "match_event_end"

function onPlay(match, player) {
  return function(data) {
    if (data.matchID != match.id) {
      return;
    }
    var timestamp = Date.now();
    status = match._getStatus();
    var game = match._game;
    var amP1 = player.isSameUser(match._p1);
    var amP2 = player.isSameUser(match._p2);
    if (status == match.STATUS.NOT_STARTED) {
      player.emit(ERROR, {error: "The game hasn't started yet."});
      return;
    } else if (status == match.STATUS.COMPLETED) {
      player.emit(ERROR, {error: "The game is already over."});
      return;
    } else if (amP1 || amP2) {
      if (data.player == 0 && !amP1) {
        player.emit(ERROR, {error: "You cannot play as P1."});
        return;
      }
      if (data.player == 1 && !amP2) {
        player.emit(ERROR, {error: "You cannot play as P2."});
        return;
      }
      if (typeof data.player == "undefined") {
        if (amP1) {
          data.player = 0;
        } else if (amP2) {
          data.player = 1;
        }
      }
      var error = match._makeMove(data.move, data.player, timestamp);
      if (error) {
        player.emit(ERROR, {error: error});
      }
    } else {
      player.emit(ERROR, {error: "You are not playing in this game."});
    }
  };
}

function Matchup(id, matchSettings) {
  var self = this;
  this.id = id;

  this._settings = matchSettings;
  //this._p1Timer = Timers.newTimer(matchSettings.p1Timer);
  //this._p2Timer = Timers.newTimer(matchSettings.p2Timer);
  //this._clock = new MatchClock(this._p1Timer, this._p2Timer);
  this._game = Games.newGame(matchSettings.gameName, matchSettings.gameSettings);
  this._p1 = null;
  this._p2 = null;
  this._spectators = [];
  // List of players that we are currently listening to for moves.
  this._players = [];
  this._dispatcher = new EventDispatcher();
}

module.exports = Matchup;

Matchup.prototype.MESSAGES = {
  PLAY: PLAY,
  UPDATE: UPDATE,
  ERROR: ERROR
};

Matchup.prototype.STATUS = {
  NOT_STARTED: "NOT_STARTED",
  ONGOING: "ONGOING",
  COMPLETED: "COMPLETED"
};

Matchup.prototype.ERRORS = {
  FAILED_TO_JOIN_MATCH : FailedToJoinMatchError
};

Matchup.prototype.onMatchUpdate = function(callback) {
  return this._dispatcher.on(EVENT_UPDATE, callback);
};

Matchup.prototype.onMatchEnd = function(callback) {
  return this._dispatcher.on(EVENT_END, callback);
};

Matchup.prototype.isCurrentlyPlaying = function(player) {
  return player.isSameUser(this._p1) || player.isSameUser(this._p2);
};

Matchup.prototype.hasStarted = function() {
  return this._p1 != null && this._p2 != null;
};

Matchup.prototype.addPlayer = function(player, seat) {
  if (!player) {
    throw new FailedToJoinMatchError(player, this, "player must not be null");
  }
  if (seat != 1 && seat != 2 && seat != 3) {
    throw new Error("'seat' must be 1, 2, or 3.");
  }
  if (seat == 3) {
    this._addPlayerToSpectators(player, true);
  } else {
    var sittingPlayer = seat == 1 ? this._p1 : this._p2;
    if (!sittingPlayer) {
      this._setPlayer(player, seat);
    } else if (player.isSameUser(sittingPlayer)) {
      this._addPlayerToSpectators(player, true)
    } else {
      // The seat is already taken.
      throw new FailedToJoinMatchError(player, this, "seat " + seat + " is already occupied.");
    }
  }
};

Matchup.prototype.matchInfo = function() {
  var info = {};
  info.matchID = this.id;
  info.gameName = this._settings.gameName;
  info.settings = this._settings;
  info.p1 = this._p1 ? {identifier: this._p1.identifier, username: this._p1.username} : null;
  info.p2 = this._p2 ? {identifier: this._p2.identifier, username: this._p2.username} : null;
  return info;
};

////////// Private

Matchup.prototype._makeMove = function(move, playerNumber, timestamp) {
  var didTurnAdvance = false;
  try {
    didTurnAdvance = this._game.playMove(move, playerNumber);
  } catch (error) {
    return "Error while trying to make a move: " + error.message;
  }
  // Ignore timers for now
  // this._clock.toggle(timestamp);
  if (didTurnAdvance) {
    this._broadcastLatestEvents(timestamp);
    this._checkIfOver();
  }
};

Matchup.prototype._dataForUpdate = function() {
  var data = {};
  data.gameName = this._settings.gameName;
  data.status = this._getStatus();
  data.settings = this._settings;
  // Ignor timers for now
  // data.timers = {
  //   p1: this._p1Timer.exportState(),
  //   p2: this._p2Timer.exportState(),
  // }
  data.players = [];
  if (this._p1) {
    data.players.push({
      username: this._p1.username,
      identifier: this._p1.identifier
    });
  } else {
    data.players.push(null);
  }
  if (this._p2) {
    data.players.push({
      username: this._p2.username,
      identifier: this._p2.identifier
    });
  } else {
    data.players.push(null);
  }
  data.matchID = this.id;
  data.toPlay = Array.from(this._game.getPlayersToPlay());
  return data;
};

Matchup.prototype._addPlayerToSpectators = function(player, shouldSendUpdtate) {
  var self = this;
  if (this._spectators.indexOf(player) == -1) {
    this._spectators.push(player);
  }
  if (player.isSameUser(this._p1) || player.isSameUser(this._p2)) {
    if (this._players.indexOf(player) == -1) {
      player.on(PLAY, onPlay(this, player));
      this._players.push(player);
    }
  }
  player.on("disconnect", function() {
    var index = self._spectators.indexOf(player);
    if (index > -1) {
      self._spectators.splice(self._spectators.indexOf(player), 1);
    }
  });
  if (shouldSendUpdtate) {
    var data = this._dataForUpdate();
    var amP1 = player.isSameUser(this._p1)
    var amP2 = player.isSameUser(this._p2)
    data.updates = this._game.getAllUpdates().map((update) => {
      return updateAsSeenBy(update, amP1, amP2);
    });
    player.emit(UPDATE, data);
  }
};

Matchup.prototype._setPlayer = function(player, seat) {
  if (seat != 1 && seat != 2) {
    throw new Error("'seat' should be 1 or 2.");
  }
  var wasPreviouslyStarted = this.hasStarted();
  if (seat == 1) {
    this._p1 = player;
  } else if (seat == 2) {
    this._p2 = player;
  }
  if (this.hasStarted() && !wasPreviouslyStarted) {
    this._game.start();
    //this._clock.start(Date.now());
    //this._startCheckingTime();
  }
  this._addPlayerToSpectators(player, false);
  this._triggerUpdate();
};

// Notify everyone that the status of this match has changed
Matchup.prototype._triggerUpdate = function() {
  this._broadcastCurrentState();
  this._dispatcher.dispatchEvent(EVENT_UPDATE, this._dataForUpdate());
};

Matchup.prototype._broadcastLatestEvents = function(timestamp) {
  var latestUpdate = this._game.getLatestUpdate();
  var data = {
    matchID: this.id,
    status: this._getStatus(timestamp),
    toPlay: Array.from(this._game.getPlayersToPlay()),
    timestamp: timestamp
  }
  for (var i = 0; i < this._spectators.length; ++i) {
    var spectator = this._spectators[i];
    var amP1 = spectator.isSameUser(this._p1)
    var amP2 = spectator.isSameUser(this._p2)
    // Right now only support 2 player games are supported.
    data.update = updateAsSeenBy(latestUpdate, amP1, amP2);
    spectator.emit(PLAY, data);
  }
}

Matchup.prototype._broadcastCurrentState = function() {
  var events = this._game.getAllUpdates();
  var data = this._dataForUpdate();
  for (var i = 0; i < this._spectators.length; ++i) {
    var spectator = this._spectators[i];
    var amP1 = spectator.isSameUser(this._p1)
    var amP2 = spectator.isSameUser(this._p2)
    data.updates = events.map((currentValue) => {
      return updateAsSeenBy(currentValue, amP1, amP2);
    });
    spectator.emit(UPDATE, data);
  }
}

Matchup.prototype._checkIfOver = function() {
  var timestamp = Date.now();
  var status = this._getStatus(timestamp);
  var result = null;
  if (status == this.STATUS.COMPLETED) {
    var winners = this._game.getWinners();
    if (winners.has(0)) {
      result = "P1";
    } else if (winners.has(1)) {
      result = "P2";
    } else {
      result = "DRAW";
    }
  }
  if (result) {
    this._triggerUpdate();
    this._dispatcher.dispatchEvent(EVENT_END, {result: result});
  }
};

Matchup.prototype._getStatus = function() {
  if (!this.hasStarted()) {
    return this.STATUS.NOT_STARTED;
  }
  return this._game.getPlayersToPlay().size ? this.STATUS.ONGOING :this.STATUS.COMPLETED;
};

function updateAsSeenBy(update, amP1, amP2) {
  if (!update) {
    return null;
  }
  var newUpdate = {
    publicInfo: update.publicInfo
  }
  if (update.privateInfo && (amP1 || amP2)) {
    newUpdate.privateInfo = update.privateInfo.map((currentValue, index) => {
      if (index == 0 && amP1 || index == 1 && amP2) {
        currentValue
      }
      return null;
    });
  }
  return newUpdate;
}
<|endoftext|>


<commit_before>module.exports = function(grunt) {

  grunt.initConfig({
    pkg: grunt.file.readJSON('package.json'),

    uglify: {
      build: {
        options: {
          banner: '/*! \n * <%= pkg.name %> v<%= pkg.version %> - <%= pkg.description %>\n *\n * <%= pkg.homepage %>\n * \n * Copyright (c) 2014 <%= pkg.author.name %> (<%= pkg.author.url %>)\n * Released under the <%= pkg.license %> license\n */\n\n'
        },
        src: ['src/js/medium-editor-insert-plugin.js', 'src/js/medium-editor-insert-images.js', 'src/js/medium-editor-insert-maps.js'],
        dest: 'dist/js/<%= pkg.name %>.all.min.js'
      },
      f1: {
        options: {
          preserveComments: 'some'
        },
        src: 'src/js/medium-editor-insert-plugin.js',
        dest: 'dist/js/addons/medium-editor-insert-plugin.min.js'
      },
      f2: {
        options: {
          preserveComments: 'some'
        },
        src: 'src/js/medium-editor-insert-images.js',
        dest: 'dist/js/addons/medium-editor-insert-images.min.js'
      },
      f3: {
        options: {
          preserveComments: 'some'
        },
        src: 'src/js/medium-editor-insert-maps.js',
        dest: 'dist/js/addons/medium-editor-insert-maps.min.js'
      }
    },

    copy: {
      main: {
        files: [
          {
            expand: true,
            cwd: 'src/js/',
            src: ['*'],
            dest: 'dist/js/addons/'
          }
        ]
      }
    },

    jshint: {
      files: ['src/js/*.js', 'src/js/**/*.js', 'test/*.js', 'test/**/*.js'],
      options: {
        ignores: ['test/lib/**/*.js']
      }
    },

    qunit: {
      unit: 'test.html'
    },

    blanket_qunit: {
      all: {
        options: {
          urls: ['test.html?coverage=true&gruntReport'],
          threshold: 60
        }
      }
    },

    compass: {
      dist: {
        options: {
          sassDir: 'src/sass',
          cssDir: 'dist/css',
          environment: 'production',
          outputStyle: 'compressed'
        }
      }
    },

    watch: {
      scripts: {
        files: ['src/js/**/*.js'],
        tasks: ['js'],
        options: {
          debounceDelay: 250
        }
      },
      styles: {
        files: 'src/sass/**/*.scss',
        tasks: ['css'],
        options: {
          debounceDelay: 250
        }
      }
    }
  });

  grunt.loadNpmTasks('grunt-contrib-uglify');
  grunt.loadNpmTasks('grunt-contrib-jshint');
  grunt.loadNpmTasks('grunt-contrib-qunit');
  grunt.loadNpmTasks('grunt-contrib-compass');
  grunt.loadNpmTasks('grunt-contrib-watch');
  grunt.loadNpmTasks('grunt-contrib-copy');
  grunt.loadNpmTasks('grunt-blanket-qunit');

  grunt.registerTask('test', ['jshint', 'blanket_qunit']);
  grunt.registerTask('js', ['test', 'uglify', 'copy']);
  grunt.registerTask('css', ['compass']);
  grunt.registerTask('default', ['js', 'css']);

};
<commit_msg>remove blanket<commit_after>module.exports = function(grunt) {

  grunt.initConfig({
    pkg: grunt.file.readJSON('package.json'),

    uglify: {
      build: {
        options: {
          banner: '/*! \n * <%= pkg.name %> v<%= pkg.version %> - <%= pkg.description %>\n *\n * <%= pkg.homepage %>\n * \n * Copyright (c) 2014 <%= pkg.author.name %> (<%= pkg.author.url %>)\n * Released under the <%= pkg.license %> license\n */\n\n'
        },
        src: ['src/js/medium-editor-insert-plugin.js', 'src/js/medium-editor-insert-images.js', 'src/js/medium-editor-insert-maps.js'],
        dest: 'dist/js/<%= pkg.name %>.all.min.js'
      },
      f1: {
        options: {
          preserveComments: 'some'
        },
        src: 'src/js/medium-editor-insert-plugin.js',
        dest: 'dist/js/addons/medium-editor-insert-plugin.min.js'
      },
      f2: {
        options: {
          preserveComments: 'some'
        },
        src: 'src/js/medium-editor-insert-images.js',
        dest: 'dist/js/addons/medium-editor-insert-images.min.js'
      },
      f3: {
        options: {
          preserveComments: 'some'
        },
        src: 'src/js/medium-editor-insert-maps.js',
        dest: 'dist/js/addons/medium-editor-insert-maps.min.js'
      }
    },

    copy: {
      main: {
        files: [
          {
            expand: true,
            cwd: 'src/js/',
            src: ['*'],
            dest: 'dist/js/addons/'
          }
        ]
      }
    },

    jshint: {
      files: ['src/js/*.js', 'src/js/**/*.js', 'test/*.js', 'test/**/*.js'],
      options: {
        ignores: ['test/lib/**/*.js']
      }
    },

    qunit: {
      unit: 'test.html'
    },

    compass: {
      dist: {
        options: {
          sassDir: 'src/sass',
          cssDir: 'dist/css',
          environment: 'production',
          outputStyle: 'compressed'
        }
      }
    },

    watch: {
      scripts: {
        files: ['src/js/**/*.js'],
        tasks: ['js'],
        options: {
          debounceDelay: 250
        }
      },
      styles: {
        files: 'src/sass/**/*.scss',
        tasks: ['css'],
        options: {
          debounceDelay: 250
        }
      }
    }
  });

  grunt.loadNpmTasks('grunt-contrib-uglify');
  grunt.loadNpmTasks('grunt-contrib-jshint');
  grunt.loadNpmTasks('grunt-contrib-qunit');
  grunt.loadNpmTasks('grunt-contrib-compass');
  grunt.loadNpmTasks('grunt-contrib-watch');
  grunt.loadNpmTasks('grunt-contrib-copy');

  grunt.registerTask('test', ['jshint', 'qunit']);
  grunt.registerTask('js', ['test', 'uglify', 'copy']);
  grunt.registerTask('css', ['compass']);
  grunt.registerTask('default', ['js', 'css']);

};
<|endoftext|>


<commit_before>
var fs = require('fs');
var util = require('util');

module.exports = function(grunt) {

    var semverUtils = require('semver-utils');

    var getBuildVersion = function() {
	var package = grunt.file.readJSON('package.json');
	var semver = semverUtils.parse(package.version);

	var release = semver.release ? semver.release.split('.') : 1000;

	if (Array.isArray(release)) {
		release = +release[release.length-1];
	}
	return release;
    }

    var isRelease = function() {
    	var package = grunt.file.readJSON('package.json');
        var semver = semverUtils.parse(package.version);

	return semver.release == null;
    }

    // Do grunt-related things in here
    require('load-grunt-tasks')(grunt);
    grunt.initConfig({
	getPackage: function() { return grunt.file.readJSON('package.json'); },
	package: grunt.file.readJSON('package.json'),
	gitcheckout: {
    	    default: {
      		options: {
		    create: false
		}
   	    }
  	},
	changelog: {
	    'ios-library': {
		options: {
            	    featureRegex: /^(.*)implements (IOSSDK-\d+)(.*)/gim,
            	    fixRegex: /^(.*)fixes (IOSSDK-\d+)(.*)/gim,
            	    dest: 'CHANGELOG.md',
            	    template: '## SDK Version <%= getPackage().version %> / {{date}}\n\n{{> features}}{{> fixes}}',
            	    partials: {
                	features: '{{#each features}}{{> feature}}{{/each}}',
                	feature: '- [NEW] {{this}}\n',
                	fixes: '{{#each fixes}}{{> fix}}{{/each}}',
                	fix: "- [FIX] {{this}}\n"
            	    }
        	}
	    }
	},
	replace: {
	    changelog: {
		options: {
		    patterns: [ {
			match: /(IOSSDK-\d+)/g,
			replacement: '[$1](https://jira.qwasi.com/browse/$1)'
		    }]
		},
		files: [
		    { expand: true, flatten: true, src: ['CHANGELOG.md'] }
		]
	    }
	},
	bump: {
	    options: {
		files: ['package.json'],
		updateConfigs: [],
		commit: true,
		commitMessage: '#bump Release %VERSION%',
		commitFiles: ['package.json', 'Qwasi.podspec', 'Pod/Classes/Version.h'],
		createTag: true,
		tagName: '%VERSION%',
		tagMessage: 'Release %VERSION%',
		push: true,
		pushTo: 'origin',
		prereleaseName: isRelease() ? false : 'dev',
		gitDescribeOptions: '--tags --always --abbrev=1 --dirty=-d',
		globalReplace: false
	    }
	},
	shell: {
	    bump_pod: {
		command: function() {
		    var package = grunt.file.readJSON('package.json');
		    var semver = semverUtils.parse(package.version);

		    return 'podspec-bump -w ' + semver;
		}
	    }
	}
    });

    grunt.registerTask('changeLog', 'Build changelog and add jira links', ['changelog', 'replace']);

    grunt.registerTask('bump-all', [isRelease() ? 'bump-only:patch' : 'bump-only:prerelease', 'shell:bump_pod', 'writeVersionHeader', 'changeLog']);

    grunt.registerTask('writeVersionHeader', function() {
	var package = grunt.file.readJSON('package.json');
	var semver = semverUtils.parse(package.version);

	var header = util.format('\/\/ Version Header\n' +
				 '#define SHORT_VERSION @"%s"\n' +
				 '#define BUILD_VERSION %d\n' +
				 '#define VERSION_STRING @"%s-%s" \n'
				 , semver.version, getBuildVersion(), semver.version, semver.release);

	fs.writeFileSync('Pod/Classes/Version.h', header);

    });

};
<commit_msg>fixing an issue with build #noissue<commit_after>
var fs = require('fs');
var util = require('util');

module.exports = function(grunt) {

    var semverUtils = require('semver-utils');

    var getBuildVersion = function() {
	var package = grunt.file.readJSON('package.json');
	var semver = semverUtils.parse(package.version);

	var release = semver.release ? semver.release.split('.') : 1000;

	if (Array.isArray(release)) {
		release = +release[release.length-1];
	}
	return release;
    }

    var isRelease = function() {
    	var package = grunt.file.readJSON('package.json');
        var semver = semverUtils.parse(package.version);

	return semver.release == null;
    }

    // Do grunt-related things in here
    require('load-grunt-tasks')(grunt);
    grunt.initConfig({
	getPackage: function() { return grunt.file.readJSON('package.json'); },
	package: grunt.file.readJSON('package.json'),
	gitcheckout: {
    	    default: {
      		options: {
		    create: false
		}
   	    }
  	},
	changelog: {
	    'ios-library': {
		options: {
            	    featureRegex: /^(.*)implements (IOSSDK-\d+)(.*)/gim,
            	    fixRegex: /^(.*)fixes (IOSSDK-\d+)(.*)/gim,
            	    dest: 'CHANGELOG.md',
            	    template: '## SDK Version <%= getPackage().version %> / {{date}}\n\n{{> features}}{{> fixes}}',
            	    partials: {
                	features: '{{#each features}}{{> feature}}{{/each}}',
                	feature: '- [NEW] {{this}}\n',
                	fixes: '{{#each fixes}}{{> fix}}{{/each}}',
                	fix: "- [FIX] {{this}}\n"
            	    }
        	}
	    }
	},
	replace: {
	    changelog: {
		options: {
		    patterns: [ {
			match: /(IOSSDK-\d+)/g,
			replacement: '[$1](https://jira.qwasi.com/browse/$1)'
		    }]
		},
		files: [
		    { expand: true, flatten: true, src: ['CHANGELOG.md'] }
		]
	    }
	},
	bump: {
	    options: {
		files: ['package.json'],
		updateConfigs: [],
		commit: true,
		commitMessage: '#bump Release %VERSION%',
		commitFiles: ['package.json', 'Qwasi.podspec', 'Pod/Classes/Version.h'],
		createTag: true,
		tagName: '%VERSION%',
		tagMessage: 'Release %VERSION%',
		push: true,
		pushTo: 'origin',
		prereleaseName: isRelease() ? false : 'dev',
		gitDescribeOptions: '--tags --always --abbrev=1 --dirty=-d',
		globalReplace: false
	    }
	},
	shell: {
	    bump_pod: {
		command: function() {
		    var package = grunt.file.readJSON('package.json');
		    var semver = semverUtils.parse(package.version);

		    return '/usr/local/bin/podspec-bump -w ' + semver;
		}
	    }
	}
    });

    grunt.registerTask('changeLog', 'Build changelog and add jira links', ['changelog', 'replace']);

    grunt.registerTask('bump-all', [isRelease() ? 'bump-only:patch' : 'bump-only:prerelease', 'shell:bump_pod', 'writeVersionHeader', 'changeLog']);

    grunt.registerTask('writeVersionHeader', function() {
	var package = grunt.file.readJSON('package.json');
	var semver = semverUtils.parse(package.version);

	var header = util.format('\/\/ Version Header\n' +
				 '#define SHORT_VERSION @"%s"\n' +
				 '#define BUILD_VERSION %d\n' +
				 '#define VERSION_STRING @"%s-%s" \n'
				 , semver.version, getBuildVersion(), semver.version, semver.release);

	fs.writeFileSync('Pod/Classes/Version.h', header);

    });

};
<|endoftext|>


<commit_before>/*
 * Rules to build the application.
 *
 * (c) 2016 Sanjeev Premi (spremi@ymail.com)
 *
 * SPDX-License-Identifier: BSD-3-Clause
 *                          (http://spdx.org/licenses/BSD-3-Clause.html)
 *
 */

'use strict';

module.exports = function (grunt) {

  //
  // Read project configuration
  //
  var pkgInfo = grunt.file.readJSON('package.json');

  //
  // Profile the tasks
  //
  require('time-grunt')(grunt);

  //
  // Load plugins automatically
  //
  require('jit-grunt')(grunt);

  //
  // Configure the tasks
  //
  grunt.initConfig({
    //
    // Project information
    //
    pkg: pkgInfo,

    //
    // Project structure
    //
    proj: {
      client: 'client',
      server: 'server',
      dist: 'dist'
    },

    //
    // Project environment
    //
    env: {
      dev: {
        NODE_ENV: 'development'
      },
      test: {
        NODE_ENV: 'test'
      },
      prod: {
        NODE_ENV: 'production'
      }
    },

    //
    // Detect errors & potential problems
    //
    jshint: {
      options: {
        reporter: require('jshint-stylish')
      },
      client: {
        options: {
          jshintrc: 'client/.jshintrc'
        },
        src: [
          '<%= proj.client %>/app/**/*.js',
          '!<%= proj.client %>/app/**/*.spec.js',
          '!<%= proj.client %>/app/**/*.mock.js'
        ]
      },
      clientTest: {
        src: [
          '<%= proj.client %>/app/**/*.spec.js',
          '<%= proj.client %>/app/**/*.mock.js'
        ]
      },
      server: {
        options: {
          jshintrc: '<%= proj.server %>/.jshintrc'
        },
        src: [
          '<%= proj.server %>/**/*.js',
          '!<%= proj.server %>/**/*.spec.js'
        ]
      },
      serverTest: {
        options: {
          jshintrc: '<%= proj.server %>/.jshintrc-spec'
        },
        src: ['<%= proj.server %>/**/*.spec.js']
      }
    }
  });

  //
  // Task: Show banner
  //
  grunt.registerTask('banner', 'Show banner',
    function() {

      var str = ':::'['yellow'] + '\n' +
                '::: Building '['yellow'] + pkgInfo.name['magenta'] +
                    ' version '['yellow'] + pkgInfo.version['cyan'] + '\n' +
                ':::'['yellow'];

      grunt.log.writeln(str);
    });

  //
  // Default task
  //
  grunt.registerTask('default', [
    'banner',
    'newer:jshint'
  ]);
};
<commit_msg>build: Add task 'serve'<commit_after>/*
 * Rules to build the application.
 *
 * (c) 2016 Sanjeev Premi (spremi@ymail.com)
 *
 * SPDX-License-Identifier: BSD-3-Clause
 *                          (http://spdx.org/licenses/BSD-3-Clause.html)
 *
 */

'use strict';

module.exports = function (grunt) {

  //
  // Read project configuration
  //
  var pkgInfo = grunt.file.readJSON('package.json');

  //
  // Profile the tasks
  //
  require('time-grunt')(grunt);

  //
  // Load plugins automatically
  //
  require('jit-grunt')(grunt, {
    express: 'grunt-express-server'
  });

  //
  // Configure the tasks
  //
  grunt.initConfig({
    //
    // Project information
    //
    pkg: pkgInfo,

    //
    // Project structure
    //
    proj: {
      client: 'client',
      server: 'server',
      dist: 'dist'
    },

    //
    // Project environment
    //
    env: {
      dev: {
        NODE_ENV: 'development'
      },
      test: {
        NODE_ENV: 'test'
      },
      prod: {
        NODE_ENV: 'production'
      }
    },

    //
    // Detect errors & potential problems
    //
    jshint: {
      options: {
        reporter: require('jshint-stylish')
      },
      client: {
        options: {
          jshintrc: 'client/.jshintrc'
        },
        src: [
          '<%= proj.client %>/app/**/*.js',
          '!<%= proj.client %>/app/**/*.spec.js',
          '!<%= proj.client %>/app/**/*.mock.js'
        ]
      },
      clientTest: {
        src: [
          '<%= proj.client %>/app/**/*.spec.js',
          '<%= proj.client %>/app/**/*.mock.js'
        ]
      },
      server: {
        options: {
          jshintrc: '<%= proj.server %>/.jshintrc'
        },
        src: [
          '<%= proj.server %>/**/*.js',
          '!<%= proj.server %>/**/*.spec.js'
        ]
      },
      serverTest: {
        options: {
          jshintrc: '<%= proj.server %>/.jshintrc-spec'
        },
        src: ['<%= proj.server %>/**/*.spec.js']
      }
    },

    //
    // Express server
    //
    express: {
      options: {
        port: require('./server/config/mode').port
      },
      dev: {
        options: {
          script: '<%= proj.server %>/main.js',
          debug: true
        }
      },
      prod: {
        options: {
          script: '<%= proj.dist %>/<%= proj.server %>/main.js'
        }
      }
    },

    //
    // Watch
    //
    watch: {}
  });

  //
  // Task: Show banner
  //
  grunt.registerTask('banner', 'Show banner',
    function() {

      var str = ':::'['yellow'] + '\n' +
                '::: Building '['yellow'] + pkgInfo.name['magenta'] +
                    ' version '['yellow'] + pkgInfo.version['cyan'] + '\n' +
                ':::'['yellow'];

      grunt.log.writeln(str);
    });

  //
  // Task: serve
  //
  grunt.registerTask('serve', 'Serve the application',
    function() {
      grunt.log.writeln('\n :: Serve '['yellow']);

      grunt.task.run([
        'banner',
        'newer:jshint',
        'express:dev',
        'watch'
      ]);
    });

  //
  // Default task
  //
  grunt.registerTask('default', [
    'banner',
    'newer:jshint'
  ]);
};
<|endoftext|>


<commit_before>'use strict';
var lrSnippet = require('grunt-contrib-livereload/lib/utils').livereloadSnippet;
var mountFolder = function (connect, dir) {
  return connect.static(require('path').resolve(dir));
};

module.exports = function (grunt) {
  // load all grunt tasks
  require('matchdep').filterDev('grunt-*').concat(['gruntacular']).forEach(grunt.loadNpmTasks);

  // configurable paths
  var yeomanConfig = {
    app: 'app',
    dist: 'dist',
    componentName: 'example'
  };

  try {
    yeomanConfig.app = require('./component.json').appPath || yeomanConfig.app;
  } catch (e) {}

  grunt.initConfig({
    yeoman: yeomanConfig,
    watch: {
      compass: {
        files: ['app/styles/{,*/}*.{scss,sass}', 'component/styles/{,*/}*.{scss,sass}'],
        tasks: ['compass']
      },
      templates: {
        files: ['component/templates/*.html', 'app/views/*.html'],
        tasks: 'html2js:directives'
      },
      livereload: {
        files: [
          'app/{,*/}*.html',
          'component/{,*/}*.html',
          '.tmp/styles/{,*/}*.css',
          'app/styles/{,*/}*.scss',
          'app/scripts/{,*/}*.js',
          'component/scripts/{,*/}*.js',
          'app/images/{,*/}*.{png,jpg,jpeg}'
        ],
        tasks: ['livereload']
      }
    },
    connect: {
      livereload: {
        options: {
          port: 9000,
          // Change this to '0.0.0.0' to access the server from outside.
          hostname: '0.0.0.0',
          middleware: function (connect) {
            return [
              lrSnippet,
              mountFolder(connect, '.tmp'),
              mountFolder(connect, ''),
              mountFolder(connect, yeomanConfig.app)
            ];
          }
        }
      },
      test: {
        options: {
          port: 9001,
          middleware: function (connect) {
            return [
              mountFolder(connect, '.tmp'),
              mountFolder(connect, 'test'),
              mountFolder(connect, 'component')
            ];
          }
        }
      }
    },
    open: {
      server: {
        url: 'http://localhost:3501'
      }
    },
    clean: {
      dist: ['.tmp', 'dist/*'],
      server: '.tmp'
    },
    jshint: {
      options: {
        jshintrc: '.jshintrc'
      },
      all: [
        'Gruntfile.js',
        'component/scripts/{,*/}*.js'
      ]
    },
    testacular: {
      unit: {
        configFile: 'testacular.conf.js',
        singleRun: true
      }
    },
    compass: {
      options: {
        sassDir: 'app/styles',
        cssDir: '.tmp/styles',
        imagesDir: 'app/images',
        javascriptsDir: 'app/scripts',
        fontsDir: 'app/styles/fonts',
        importPath: ['app/components', 'component/styles'],
        relativeAssets: true
      },
      dist: {},
      server: {
        options: {
          debugInfo: true
        }
      }
    },
    html2js: {
      directives: ['component/templates/*.html', 'app/views/*.html'],
    },
    concat: {
      dist: {
        files: {
          'dist/example.js': [
            'component/scripts/**/*.js',
            'component/templates/*.js'
          ]
        }
      }
    },
    useminPrepare: {
      html: 'app/index.html',
      options: {
        dest: 'dist'
      }
    },
    usemin: {
      html: ['dist/{,*/}*.html'],
      css: ['dist/styles/{,*/}*.css'],
      options: {
        dirs: ['dist']
      }
    },
    imagemin: {
      dist: {
        files: [{
          expand: true,
          cwd: 'app/images',
          src: '{,*/}*.{png,jpg,jpeg}',
          dest: 'dist/images'
        }]
      }
    },
    cssmin: {
      dist: {
        files: {
          'dist/main.css': [
            '.tmp/styles/{,*/}*.css',
            'app/styles/{,*/}*.css'
          ]
        }
      }
    },
    htmlmin: {
      dist: {
        options: {
          /*removeCommentsFromCDATA: true,
          // https://github.com/yeoman/grunt-usemin/issues/44
          //collapseWhitespace: true,
          collapseBooleanAttributes: true,
          removeAttributeQuotes: true,
          removeRedundantAttributes: true,
          useShortDoctype: true,
          removeEmptyAttributes: true,
          removeOptionalTags: true*/
        },
        files: [{
          expand: true,
          cwd: 'app',
          src: ['*.html', 'views/*.html'],
          dest: 'dist'
        }]
      }
    },
    cdnify: {
      dist: {
        html: ['dist/*.html']
      }
    },
    ngmin: {
      dist: {
        files: [{
          expand: true,
          cwd: 'dist/scripts',
          src: '*.js',
          dest: 'dist/scripts'
        }]
      }
    },
    uglify: {
      dist: {
        files: {
          'dist/scripts/scripts.js': [
            'dist/scripts/scripts.js'
          ],
        }
      }
    },
    copy: {
      dist: {
        files: [{
          expand: true,
          dot: true,
          cwd: 'app',
          dest: 'dist',
          src: [
            '*.{ico,txt}',
          ]
        }]
      }
    }
  });

  var escapeContent = function(content) {
    return content.replace(/"/g, '\\"').replace(/\n/g, '" +\n    "');
  };

  grunt.registerMultiTask('html2js', 'Generate js version of html template.', function() {
    var files = grunt._watch_changed_files || grunt.file.expand(this.data);

    files.forEach(function(file) {
      var content  = escapeContent(grunt.file.read(file)),
          template = '';

      template += 'angular.module("' + file + '", []).run(function($templateCache) {\n';
      template += '  $templateCache.put("' + file + '",\n';
      template += '    "' + content + '");\n';
      template += '});\n';

      grunt.file.write(file + '.js', template);
    });
  });

  grunt.renameTask('regarde', 'watch');
  // remove when mincss task is renamed
  grunt.renameTask('mincss', 'cssmin');

  grunt.registerTask('server', [
    'clean:server',
    'compass:server',
    'html2js',
    'livereload-start',
    'connect:livereload',
    'open',
    'watch'
  ]);

  grunt.registerTask('test', [
    'clean:server',
    'compass',
    'html2js',
    'connect:test',
    'testacular'
  ]);

  grunt.registerTask('build', [
    'clean:dist',
    'jshint',
    'test',
    'compass:dist',
    'html2js',
    //'useminPrepare',
    //'imagemin',
    'cssmin',
    'concat',
    'copy',
    //'cdnify',
    //'usemin',
    //'ngmin',
    //'uglify'
  ]);

  grunt.registerTask('default', ['build']);
};
<commit_msg>Updates to Gruntfile to include SCSS files in dist.<commit_after>'use strict';
var lrSnippet = require('grunt-contrib-livereload/lib/utils').livereloadSnippet;
var mountFolder = function (connect, dir) {
  return connect.static(require('path').resolve(dir));
};

module.exports = function (grunt) {
  // load all grunt tasks
  require('matchdep').filterDev('grunt-*').concat(['gruntacular']).forEach(grunt.loadNpmTasks);

  // configurable paths
  var yeomanConfig = {
    app: 'app',
    dist: 'dist',
    componentName: 'example'
  };

  try {
    yeomanConfig.app = require('./component.json').appPath || yeomanConfig.app;
  } catch (e) {}

  grunt.initConfig({
    yeoman: yeomanConfig,
    watch: {
      compass: {
        files: ['app/styles/{,*/}*.{scss,sass}', 'component/styles/{,*/}*.{scss,sass}'],
        tasks: ['compass']
      },
      templates: {
        files: ['component/templates/*.html', 'app/views/*.html'],
        tasks: 'html2js:directives'
      },
      livereload: {
        files: [
          'app/{,*/}*.html',
          'component/{,*/}*.html',
          '.tmp/styles/{,*/}*.css',
          'app/styles/{,*/}*.scss',
          'app/scripts/{,*/}*.js',
          'component/scripts/{,*/}*.js',
          'app/images/{,*/}*.{png,jpg,jpeg}'
        ],
        tasks: ['livereload']
      }
    },
    connect: {
      livereload: {
        options: {
          port: 9000,
          // Change this to '0.0.0.0' to access the server from outside.
          hostname: '0.0.0.0',
          middleware: function (connect) {
            return [
              lrSnippet,
              mountFolder(connect, '.tmp'),
              mountFolder(connect, ''),
              mountFolder(connect, yeomanConfig.app)
            ];
          }
        }
      },
      test: {
        options: {
          port: 9001,
          middleware: function (connect) {
            return [
              mountFolder(connect, '.tmp'),
              mountFolder(connect, 'test'),
              mountFolder(connect, 'component')
            ];
          }
        }
      }
    },
    open: {
      server: {
        url: 'http://localhost:3501'
      }
    },
    clean: {
      dist: ['.tmp', 'dist/*.js', 'dist/*.scss', 'dist/*.css'],
      server: '.tmp'
    },
    jshint: {
      options: {
        jshintrc: '.jshintrc'
      },
      all: [
        'Gruntfile.js',
        'component/scripts/{,*/}*.js'
      ]
    },
    testacular: {
      unit: {
        configFile: 'testacular.conf.js',
        singleRun: true
      }
    },
    compass: {
      options: {
        sassDir: 'app/styles',
        cssDir: '.tmp/styles',
        imagesDir: 'app/images',
        javascriptsDir: 'app/scripts',
        fontsDir: 'app/styles/fonts',
        importPath: ['app/components', 'component/styles'],
        relativeAssets: true
      },
      dist: {
        files: {
          'dist/tables.scss' : [
            'component/styles/**/*.scss'
          ]
        }
      },
      server: {
        options: {
          debugInfo: true
        }
      }
    },
    html2js: {
      directives: ['component/templates/*.html', 'app/views/*.html'],
    },
    concat: {
      dist: {
        files: {
          'dist/example.js': [
            'component/scripts/**/*.js',
            'component/templates/*.js'
          ]
        }
      }
    },
    useminPrepare: {
      html: 'app/index.html',
      options: {
        dest: 'dist'
      }
    },
    usemin: {
      html: ['dist/{,*/}*.html'],
      css: ['dist/styles/{,*/}*.css'],
      options: {
        dirs: ['dist']
      }
    },
    imagemin: {
      dist: {
        files: [{
          expand: true,
          cwd: 'app/images',
          src: '{,*/}*.{png,jpg,jpeg}',
          dest: 'dist/images'
        }]
      }
    },
    cssmin: {
      dist: {
        files: {
          'dist/tables.css': [
            '.tmp/styles/{,*/}*.css',
            'app/styles/{,*/}*.css'
          ]
        }
      }
    },
    htmlmin: {
      dist: {
        options: {
          /*removeCommentsFromCDATA: true,
          // https://github.com/yeoman/grunt-usemin/issues/44
          //collapseWhitespace: true,
          collapseBooleanAttributes: true,
          removeAttributeQuotes: true,
          removeRedundantAttributes: true,
          useShortDoctype: true,
          removeEmptyAttributes: true,
          removeOptionalTags: true*/
        },
        files: [{
          expand: true,
          cwd: 'app',
          src: ['*.html', 'views/*.html'],
          dest: 'dist'
        }]
      }
    },
    cdnify: {
      dist: {
        html: ['dist/*.html']
      }
    },
    ngmin: {
      dist: {
        files: [{
          expand: true,
          cwd: 'dist/scripts',
          src: '*.js',
          dest: 'dist/scripts'
        }]
      }
    },
    uglify: {
      dist: {
        files: {
          'dist/scripts/scripts.js': [
            'dist/scripts/scripts.js'
          ],
        }
      }
    },
    copy: {
      dist: {
        files: [{
          expand: true,
          dot: true,
          cwd: 'app',
          dest: 'dist',
          src: [
            '*.{ico,txt}',
            '*.{ico,txt}'
          ]
        },
        {
          expand: true,
          dot: true,
          cwd: 'component/styles',
          dest: 'dist',
          src: [
            './**/*.scss'
          ]
        }]
      }
    }
  });

  var escapeContent = function(content) {
    return content.replace(/"/g, '\\"').replace(/\n/g, '" +\n    "');
  };

  grunt.registerMultiTask('html2js', 'Generate js version of html template.', function() {
    var files = grunt._watch_changed_files || grunt.file.expand(this.data);

    files.forEach(function(file) {
      var content  = escapeContent(grunt.file.read(file)),
          template = '';

      template += 'angular.module("' + file + '", []).run(function($templateCache) {\n';
      template += '  $templateCache.put("' + file + '",\n';
      template += '    "' + content + '");\n';
      template += '});\n';

      grunt.file.write(file + '.js', template);
    });
  });

  grunt.renameTask('regarde', 'watch');
  // remove when mincss task is renamed
  grunt.renameTask('mincss', 'cssmin');

  grunt.registerTask('server', [
    'clean:server',
    'compass:server',
    'html2js',
    'livereload-start',
    'connect:livereload',
    'open',
    'watch'
  ]);

  grunt.registerTask('test', [
    'clean:server',
    'compass',
    'html2js',
    'connect:test',
    'testacular'
  ]);

  grunt.registerTask('build', [
    'clean:dist',
    'jshint',
    'test',
    'compass:dist',
    'html2js',
    //'useminPrepare',
    //'imagemin',
    'cssmin',
    'concat',
    'copy',
    //'cdnify',
    //'usemin',
    //'ngmin',
    //'uglify'
  ]);

  grunt.registerTask('default', ['build']);
};
<|endoftext|>


<commit_before>///Global variables

// Function to retrieve information and send a
function getOSMLine(key, value, url) {
    var info = '{"osmline": {"'+ key +'": '+value+'}}';
    $( "button" ).addClass( "is-loading" );
    $.post( url, info,
        function( data ) {
            if (key === 'accept') { window.location = url; }
            else{ window.location = url + value; }
            $( "button" ).removeClass( "is-loading" );
        }
    ).fail(
        function(data){
            alert("Error " + data.status + " " + url + " " + info);
            $( "button" ).removeClass( "is-loading" );
        }
    );
}

/*Get GPS coordinates of the user*/
function getLocationRedirection(url) {
    function redirectToPosition(position) {
        window.location= url+'?userpos='+position.coords.latitude+','+position.coords.longitude;
        console.log('redirected to: ' + url+'?userpos='+position.coords.latitude+','+position.coords.longitude);
    }

    if (navigator.geolocation) {
        navigator.geolocation.getCurrentPosition(redirectToPosition);
    } else {
        alert("Geolocation is not supported by this browser.");
    }
}

/*Validate email*/
function validateEmail(email) {
    var re = /\S+@\S+\.\S+/;
    return re.test(email);
}

/*Opens a dialog page to insert the email to recover the password*/
function recover_password() {
    var email=window.prompt("Please enter your email");
    if (validateEmail(email)) {
        window.alert("An email has been sent to " + email);
    } else {
        window.alert("Your email was invalid -> " + email);
    }
}

/*Show signup*/
function show_signup() {
    $( ".log-card.is-hidden" ).removeClass( "is-hidden" );
    $( ".login-card" ).addClass( "is-hidden" );
}

var timetableColumn_counter = 1;
/*Timetable add form column*/
function add_timetableColumn(serialize_ids) {
    $( " #timetable--form").append('<fieldset id="timetable-column-' + timetableColumn_counter + '"  class="moveon-company"></fieldset>');
    for (var i = 0; i < serialize_ids.length; i++) {
        $( "#timetable-column-" + timetableColumn_counter).append('<input class="input" name="time-' + timetableColumn_counter + '-' + serialize_ids[i] + '" type="text"/>');
    }
    timetableColumn_counter++;
}

function send_timetableCalculation(route_id, stretch_id) {
    var mean_speed = $( "input[name='mean_speed']" ).val();
    /*Only for non empty values*/
    var timetable_form_empties = $('form').serializeArray();

    classified_times = []
    for (i=0; i<timetableColumn_counter; i++) {
    	classified_times.push([]);
    }

    for (i=0; i<timetable_form_empties.length;) {
        var obj = timetable_form_empties[i]
        if(obj.value == "") {
            timetable_form_empties.splice(i, 1);
        } else {
        	col = parseInt(obj.name.split("-")[1]);
        	station_id = parseInt(obj.name.split("-")[2]);

        	hour_str=obj.value.split(":")[0];
        	min_str=obj.value.split(":")[1];

        	hour = (parseInt(hour_str)%24) * 60 * 60;
        	min = parseInt(min_str) * 60;

        	classified_times[col].push(
        			{
        				"station_id" : station_id,
        				"time" : hour + min
        			});

            i++;
        }
    }

    prefix = obj.name.split("-")[0];
    data = {"prefix" : prefix, "time_list" : classified_times}

    var timetable = {
        "mean_speed":parseFloat(mean_speed)/3.6,
        "times": data,
        "route_id": route_id
    };

    $.ajax({
      type: "PUT",
      url: "/moveon/stretches/"+stretch_id,
      data: JSON.stringify(timetable),
      success: function(data) {
        decoded_data = JSON.parse(data);
        for (index in decoded_data) {
            time = decoded_data[index];
            hours = parseInt(time.value / 60 / 60)
            minutes = parseInt(time.value / 60) % 60
            final_value = hours.toString() + ":";

            if (minutes < 10) {
            	final_value += "0" + minutes.toString()
            } else {
            	final_value += minutes.toString()
            }

            $("input[name="+time.name+"]").val(final_value);
        }
      }
    });
}

function verify_last(var1, selector, alert_text){
    if (var1==""){
        $( selector ).addClass("redborder");
        alert(alert_text);
        return false;
    }else{
        $( selector ).removeClass("redborder");
        return true;
    }
}

function send_timetableAcceptation(route_id, stretch_id) {
    var days = $("input[name=day]:checked").map(function () {return this.value;}).get().join(",");
    var start = $( "input[name='start-date']" ).val();
    var end = $( "input[name='end-date']" ).val();
    var send = true;

    send = verify_last(days, '.moveon-company_day', 'Please, select at least one day in the week checkbox.');
    send = send && verify_last(start, 'input[name="start"]', 'Please, select the start date for the timetable');
    send = send && verify_last(end, 'input[name="end"]', 'Please, select the end date for the timetable');

    if (send) {
        var mean_speed = $( "input[name='mean_speed']" ).val();
        /*Only for non empty values*/
        var timetable_form_empties = $('form').serializeArray();

        var stationSignatureByCol=[]
        var timeSignatureByCol=[]
        var initialTimesPerCol=[]
        for (i=0; i<timetableColumn_counter; i++) {
        	stationSignatureByCol.push("");
        	timeSignatureByCol.push("");
        }

        var previousCol = -1;
        var first
        for (i=0; i<timetable_form_empties.length; i++) {
            var obj = timetable_form_empties[i]
            if(obj.value != "") {
            	var col = parseInt(obj.name.split("-")[1]);
            	var station_id_str = parseInt(obj.name.split("-")[2]);
            	var station_id = parseInt(station_id_str);

            	var hour_str=obj.value.split(":")[0];
            	var min_str=obj.value.split(":")[1];

            	var hour = (parseInt(hour_str)%24) * 60 * 60;
            	var min = parseInt(min_str) * 60;

            	var timestamp = hour + min;

            	if (col != previousCol) {
            		initialTimesPerCol.push(timestamp)
            	}
            	var previousCol = col;

            	var timeDifference = timestamp - initialTimesPerCol[col];

            	stationSignatureByCol[col] = stationSignatureByCol[col].concat(station_id_str).concat(".");
            	timeSignatureByCol[col] = timeSignatureByCol[col].concat(timeDifference.toString()).concat(".");
            }
        }

        var initialtimesPerStretch={};
        for (i=0; i<timetableColumn_counter; i++) {
        	var stretchSignature = stationSignatureByCol[i].concat("-").concat(timeSignatureByCol[i]);

        	if (!(stretchSignature in initialtimesPerStretch)) {
        		initialtimesPerStretch[stretchSignature] = [];
        	}
        	initialtimesPerStretch[stretchSignature].push(initialTimesPerCol[i])
        }

        var timetable = {
            "stretch_info_list": initialtimesPerStretch,
            "route_id": route_id,
            "day": days,
            "start": start, //Math.round(Date.parse("Wed Jun 20 19:20:44 +0000 2012") / 1000),
            "end": end
        };

        $.ajax({
          type: "PUT",
          url: "/moveon/stretches/"+stretch_id,
          data: JSON.stringify(timetable),
          statusCode: {
            200: function() { alert( "It worked! 200 " ); },
            201: function() { alert( "It worked! 201 " ); },
            404: function() { alert( "Something was missing" ); }
          }
        });
    }
}

var verification = [];
function verify(class_name, res) {
    if (res==null) {
        $( "input[name='"+class_name+"']" ).addClass("redborder");
        verification.push(class_name);
        $( "button" ).prop('disabled', true);
    }else{
        $( "input[name='"+class_name+"']" ).removeClass("redborder");
        verification.splice(verification.indexOf(class_name), 1);
        if (verification.length==0) {
            $( "button" ).prop('disabled', false);
        }
    }
}
function verify_time(class_name) {
    var input = $( "input[name='"+class_name+"']" ).val();
    var res = input.match(/^(([01]?[0-9]|2[0-3]):[0-5][0-9]|\s*)$/);
    verify(class_name, res);
}

function verify_speed(class_name) {
    var input = $( "input[name='"+class_name+"']" ).val();
    var res = input.match(/^[01]?[0-9]?[0-9]\.?[0-9]?[0-9]?/);
    verify(class_name, res);
}

function verify_date(class_name) {
    var input = $( "input[name='"+class_name+"']" ).val();
    var res = input.match(/^[0-9]{2}\/[0-9]{2}\/[0-9]{4}/);
    verify(class_name, res);
}

function csv_json(serialize_ids) {
    $("#csv").parse({
        skipEmptyLines: true,
        config: {
            complete: function(results, file) {
                //Calculate total of cycles before to avoid inconsistent results
                var total = results.data[0].length - timetableColumn_counter;
                for (var i = 0; i < total; i++) {
                    add_timetableColumn(serialize_ids);
                }
                //Writing in the user timetable
                for (var i = 0; i < results.data.length; i++) {
                    for (var j = 0; j < results.data[i].length; j++) {
                        $("input[name=time-"+ j + "-" + serialize_ids[i] + "]").val(results.data[i][j]);
                        verify_time("time-"+ j + "-" + serialize_ids[i]);
                    }
                }
            }
        },
        complete: function() {
            console.log("All times added!");
        }
    });
}

function erase_timetables(route_id) {
    var timetable_ids = $("input[name=timetable]:checked").map(function () {return this.value;}).get().join(",");
    console.log(timetable_ids);

    to_delete = {
        'timetable_ids': timetable_ids.split('[')[1].split(']')[0].split(',').map(Number),
        'route_id': route_id
      }

    $.ajax({
      type: "POST",
      url: "/moveon/timetables/deletes/",
      data: JSON.stringify(to_delete),
      statusCode: {
        200: function() { alert( "The elements has been erased" ); },
        201: function() { alert( "The elements has been erased 201 " ); },
        404: function() { alert( "Something was incorrect" ); }
      }
    });
}

function get_Timetable(serialize_ids, route_id){

    function onSuccess(data) {
        //Erase every .new object to avoid concatenations
        $(" .new ").remove();

        timetable = JSON.parse(data);
        for (var i = 0; i < timetable.times.length; i++) {
            aux = timetable.signatures[timetable.times[i][1]].split('-');
            stations = aux[0].split('.');
            times = aux[1].split('.');
            $(' #titles ').append("test?	");
            for (var j = 0; j < serialize_ids.length; j++) {
                k = stations.indexOf(serialize_ids[j]);
                if (k>=0) {
                    time = (parseInt(times[k]) + parseInt(timetable.times[i]));
                    var myDate = (new Date(time * 1000)).toUTCString().match(/(\d\d:\d\d)/)[0];
                } else {
                    var myDate = "- - - -";
                }

                $('#' + serialize_ids[j].toString()).append("" + myDate.toString() + "	");
            }
        }
    }

    var ids = $("option:selected").val();
    $.ajax({
      type: "POST",
      url: "/moveon/timetables/get/" + route_id + "/",
      data: JSON.stringify(ids),
      success: function(timetable){
            onSuccess(timetable);
        }
    });

}<commit_msg>Change the time to unix timestamp in the creation of a timetable<commit_after>///Global variables

// Function to retrieve information and send a
function getOSMLine(key, value, url) {
    var info = '{"osmline": {"'+ key +'": '+value+'}}';
    $( "button" ).addClass( "is-loading" );
    $.post( url, info,
        function( data ) {
            if (key === 'accept') { window.location = url; }
            else{ window.location = url + value; }
            $( "button" ).removeClass( "is-loading" );
        }
    ).fail(
        function(data){
            alert("Error " + data.status + " " + url + " " + info);
            $( "button" ).removeClass( "is-loading" );
        }
    );
}

/*Get GPS coordinates of the user*/
function getLocationRedirection(url) {
    function redirectToPosition(position) {
        window.location= url+'?userpos='+position.coords.latitude+','+position.coords.longitude;
        console.log('redirected to: ' + url+'?userpos='+position.coords.latitude+','+position.coords.longitude);
    }

    if (navigator.geolocation) {
        navigator.geolocation.getCurrentPosition(redirectToPosition);
    } else {
        alert("Geolocation is not supported by this browser.");
    }
}

/*Validate email*/
function validateEmail(email) {
    var re = /\S+@\S+\.\S+/;
    return re.test(email);
}

/*Opens a dialog page to insert the email to recover the password*/
function recover_password() {
    var email=window.prompt("Please enter your email");
    if (validateEmail(email)) {
        window.alert("An email has been sent to " + email);
    } else {
        window.alert("Your email was invalid -> " + email);
    }
}

/*Show signup*/
function show_signup() {
    $( ".log-card.is-hidden" ).removeClass( "is-hidden" );
    $( ".login-card" ).addClass( "is-hidden" );
}

var timetableColumn_counter = 1;
/*Timetable add form column*/
function add_timetableColumn(serialize_ids) {
    $( " #timetable--form").append('<fieldset id="timetable-column-' + timetableColumn_counter + '"  class="moveon-company"></fieldset>');
    for (var i = 0; i < serialize_ids.length; i++) {
        $( "#timetable-column-" + timetableColumn_counter).append('<input class="input" name="time-' + timetableColumn_counter + '-' + serialize_ids[i] + '" type="text"/>');
    }
    timetableColumn_counter++;
}

function send_timetableCalculation(route_id, stretch_id) {
    var mean_speed = $( "input[name='mean_speed']" ).val();
    /*Only for non empty values*/
    var timetable_form_empties = $('form').serializeArray();

    classified_times = []
    for (i=0; i<timetableColumn_counter; i++) {
    	classified_times.push([]);
    }

    for (i=0; i<timetable_form_empties.length;) {
        var obj = timetable_form_empties[i]
        if(obj.value == "") {
            timetable_form_empties.splice(i, 1);
        } else {
        	col = parseInt(obj.name.split("-")[1]);
        	station_id = parseInt(obj.name.split("-")[2]);

        	hour_str=obj.value.split(":")[0];
        	min_str=obj.value.split(":")[1];

        	hour = (parseInt(hour_str)%24) * 60 * 60;
        	min = parseInt(min_str) * 60;

        	classified_times[col].push(
        			{
        				"station_id" : station_id,
        				"time" : hour + min
        			});

            i++;
        }
    }

    prefix = obj.name.split("-")[0];
    data = {"prefix" : prefix, "time_list" : classified_times}

    var timetable = {
        "mean_speed":parseFloat(mean_speed)/3.6,
        "times": data,
        "route_id": route_id
    };

    $.ajax({
      type: "PUT",
      url: "/moveon/stretches/"+stretch_id,
      data: JSON.stringify(timetable),
      success: function(data) {
        decoded_data = JSON.parse(data);
        for (index in decoded_data) {
            time = decoded_data[index];
            hours = parseInt(time.value / 60 / 60)
            minutes = parseInt(time.value / 60) % 60
            final_value = hours.toString() + ":";

            if (minutes < 10) {
            	final_value += "0" + minutes.toString()
            } else {
            	final_value += minutes.toString()
            }

            $("input[name="+time.name+"]").val(final_value);
        }
      }
    });
}

function verify_last(var1, selector, alert_text){
    if (var1==""){
        $( selector ).addClass("redborder");
        alert(alert_text);
        return false;
    }else{
        $( selector ).removeClass("redborder");
        return true;
    }
}

function send_timetableAcceptation(route_id, stretch_id) {
    var days = $("input[name=day]:checked").map(function () {return this.value;}).get().join(",");
    var start = $( "input[name='start-date']" ).val();
    var end = $( "input[name='end-date']" ).val();
    var send = true;

    send = verify_last(days, '.moveon-company_day', 'Please, select at least one day in the week checkbox.');
    send = send && verify_last(start, 'input[name="start"]', 'Please, select the start date for the timetable');
    send = send && verify_last(end, 'input[name="end"]', 'Please, select the end date for the timetable');

    if (send) {
        var mean_speed = $( "input[name='mean_speed']" ).val();
        /*Only for non empty values*/
        var timetable_form_empties = $('form').serializeArray();

        var stationSignatureByCol=[]
        var timeSignatureByCol=[]
        var initialTimesPerCol=[]
        for (i=0; i<timetableColumn_counter; i++) {
        	stationSignatureByCol.push("");
        	timeSignatureByCol.push("");
        }

        var previousCol = -1;
        var first
        for (i=0; i<timetable_form_empties.length; i++) {
            var obj = timetable_form_empties[i]
            if(obj.value != "") {
            	var col = parseInt(obj.name.split("-")[1]);
            	var station_id_str = parseInt(obj.name.split("-")[2]);
            	var station_id = parseInt(station_id_str);

            	var hour_str=obj.value.split(":")[0];
            	var min_str=obj.value.split(":")[1];

            	var hour = (parseInt(hour_str)%24) * 60 * 60;
            	var min = parseInt(min_str) * 60;

            	var timestamp = hour + min;

            	if (col != previousCol) {
            		initialTimesPerCol.push(timestamp)
            	}
            	var previousCol = col;

            	var timeDifference = timestamp - initialTimesPerCol[col];

            	stationSignatureByCol[col] = stationSignatureByCol[col].concat(station_id_str).concat(".");
            	timeSignatureByCol[col] = timeSignatureByCol[col].concat(timeDifference.toString()).concat(".");
            }
        }

        var initialtimesPerStretch={};
        for (i=0; i<timetableColumn_counter; i++) {
        	var stretchSignature = stationSignatureByCol[i].concat("-").concat(timeSignatureByCol[i]);

        	if (!(stretchSignature in initialtimesPerStretch)) {
        		initialtimesPerStretch[stretchSignature] = [];
        	}
        	initialtimesPerStretch[stretchSignature].push(initialTimesPerCol[i])
        }

        var timetable = {
            "stretch_info_list": initialtimesPerStretch,
            "route_id": route_id,
            "day": days,
            "start": Math.round(Date.parse(start) / 1000),
            "end": Math.round(Date.parse(end) / 1000),
        };

        $.ajax({
          type: "PUT",
          url: "/moveon/stretches/"+stretch_id,
          data: JSON.stringify(timetable),
          statusCode: {
            200: function() { alert( "It worked! 200 " ); },
            201: function() { alert( "It worked! 201 " ); },
            404: function() { alert( "Something was missing" ); }
          }
        });
    }
}

var verification = [];
function verify(class_name, res) {
    if (res==null) {
        $( "input[name='"+class_name+"']" ).addClass("redborder");
        verification.push(class_name);
        $( "button" ).prop('disabled', true);
    }else{
        $( "input[name='"+class_name+"']" ).removeClass("redborder");
        verification.splice(verification.indexOf(class_name), 1);
        if (verification.length==0) {
            $( "button" ).prop('disabled', false);
        }
    }
}
function verify_time(class_name) {
    var input = $( "input[name='"+class_name+"']" ).val();
    var res = input.match(/^(([01]?[0-9]|2[0-3]):[0-5][0-9]|\s*)$/);
    verify(class_name, res);
}

function verify_speed(class_name) {
    var input = $( "input[name='"+class_name+"']" ).val();
    var res = input.match(/^[01]?[0-9]?[0-9]\.?[0-9]?[0-9]?/);
    verify(class_name, res);
}

function verify_date(class_name) {
    var input = $( "input[name='"+class_name+"']" ).val();
    var res = input.match(/^[0-9]{2}\/[0-9]{2}\/[0-9]{4}/);
    verify(class_name, res);
}

function csv_json(serialize_ids) {
    $("#csv").parse({
        skipEmptyLines: true,
        config: {
            complete: function(results, file) {
                //Calculate total of cycles before to avoid inconsistent results
                var total = results.data[0].length - timetableColumn_counter;
                for (var i = 0; i < total; i++) {
                    add_timetableColumn(serialize_ids);
                }
                //Writing in the user timetable
                for (var i = 0; i < results.data.length; i++) {
                    for (var j = 0; j < results.data[i].length; j++) {
                        $("input[name=time-"+ j + "-" + serialize_ids[i] + "]").val(results.data[i][j]);
                        verify_time("time-"+ j + "-" + serialize_ids[i]);
                    }
                }
            }
        },
        complete: function() {
            console.log("All times added!");
        }
    });
}

function erase_timetables(route_id) {
    var timetable_ids = $("input[name=timetable]:checked").map(function () {return this.value;}).get().join(",");
    console.log(timetable_ids);

    to_delete = {
        'timetable_ids': timetable_ids.split('[')[1].split(']')[0].split(',').map(Number),
        'route_id': route_id
      }

    $.ajax({
      type: "POST",
      url: "/moveon/timetables/deletes/",
      data: JSON.stringify(to_delete),
      statusCode: {
        200: function() { alert( "The elements has been erased" ); },
        201: function() { alert( "The elements has been erased 201 " ); },
        404: function() { alert( "Something was incorrect" ); }
      }
    });
}

function get_Timetable(serialize_ids, route_id){

    function onSuccess(data) {
        //Erase every .new object to avoid concatenations
        $(" .new ").remove();

        timetable = JSON.parse(data);
        for (var i = 0; i < timetable.times.length; i++) {
            aux = timetable.signatures[timetable.times[i][1]].split('-');
            stations = aux[0].split('.');
            times = aux[1].split('.');
            $(' #titles ').append("test?	");
            for (var j = 0; j < serialize_ids.length; j++) {
                k = stations.indexOf(serialize_ids[j]);
                if (k>=0) {
                    time = (parseInt(times[k]) + parseInt(timetable.times[i]));
                    var myDate = (new Date(time * 1000)).toUTCString().match(/(\d\d:\d\d)/)[0];
                } else {
                    var myDate = "- - - -";
                }

                $('#' + serialize_ids[j].toString()).append("" + myDate.toString() + "	");
            }
        }
    }

    var ids = $("option:selected").val();
    $.ajax({
      type: "POST",
      url: "/moveon/timetables/get/" + route_id + "/",
      data: JSON.stringify(ids),
      success: function(timetable){
            onSuccess(timetable);
        }
    });

}<|endoftext|>


<commit_before>/*
 * Copyright 2014-2015 Hewlett-Packard Development Company, L.P.
 * Licensed under the MIT License (the "License"); you may not use this file except in compliance with the License.
 */

define([
    'find/app/model/find-base-collection',
    'find/app/model/document-model',
    'underscore'
], function(FindBaseCollection, DocumentModel, _) {

    return FindBaseCollection.extend({
        model: DocumentModel,
        url: '../api/public/search/query-text-index/results',

        autoCorrection: null,
        totalResults: null,
        warnings: null,

        fetch: function(options) {
            this.autoCorrection = null;
            this.totalResults = null;
            this.warnings = null;

            var originalErrorHandler = options.error || _.noop;

            var errorHandler = function(collection, errorResponse) {
                this.autoCorrection = errorResponse.responseJSON.autoCorrection;
                originalErrorHandler.apply(options, arguments)
            }.bind(this);

            _.extend(options, {error: errorHandler});

            return FindBaseCollection.prototype.fetch.call(this, options);
        },

        parse: function(response) {
            this.autoCorrection = response.autoCorrection;
            this.totalResults = response.totalResults;
            this.warnings = response.warnings;

            return response.documents;
        },

        getAutoCorrection: function() {
            return this.autoCorrection;
        }
    });

});
<commit_msg>[FIND-247] Merged type error fix to develop.<commit_after>/*
 * Copyright 2014-2015 Hewlett-Packard Development Company, L.P.
 * Licensed under the MIT License (the "License"); you may not use this file except in compliance with the License.
 */

define([
    'find/app/model/find-base-collection',
    'find/app/model/document-model',
    'underscore'
], function(FindBaseCollection, DocumentModel, _) {

    return FindBaseCollection.extend({
        model: DocumentModel,
        url: '../api/public/search/query-text-index/results',

        autoCorrection: null,
        totalResults: null,
        warnings: null,

        fetch: function(options) {
            this.autoCorrection = null;
            this.totalResults = null;
            this.warnings = null;

            var originalErrorHandler = options.error || _.noop;

            var errorHandler = function(collection, errorResponse) {
                if (errorResponse.responseJSON) {
                    this.autoCorrection = errorResponse.responseJSON.autoCorrection;
                }

                originalErrorHandler.apply(options, arguments);
            }.bind(this);

            return FindBaseCollection.prototype.fetch.call(this, _.extend(options, {error: errorHandler}));
        },

        parse: function(response) {
            this.autoCorrection = response.autoCorrection;
            this.totalResults = response.totalResults;
            this.warnings = response.warnings;

            return response.documents;
        },

        getAutoCorrection: function() {
            return this.autoCorrection;
        }
    });

});
<|endoftext|>


<commit_before>module.exports = function(grunt) {

    // Configuration goes here
    grunt.initConfig({
        pkg: grunt.file.readJSON('package.json'),
        concat: {
            options: {
                separator: ';'
            },
            dist: {
                src: ['src/zest.js'],
                dest: 'zest.js'
            }
        },
        jshint: {
            files: ['src/**/*.js'],
            options: {
                strict: true,
                globals: {
                    console: true
                }
            }
        },
        qunit: {
            files: ['test/**/*.html']
        },
        uglify: {
            options: {
                banner: '/**\n * Zest v<%= pkg.version %>\n * Copyright 2014. <%= pkg.author %>\n * <%= pkg.homepage %>\n' +
        ' * <%= grunt.template.today("yyyy-mm-dd") %>\n */\n'
            },
            script: {
                files: {
                    'zest.min.js': ['zest.js']
                }
            }
        },
        watch: {
            scripts: {
                files: ['src/**/*.js'],
                tasks: ['jshint', 'concat', 'uglify']
            }
        }
    });

    // Load plugins here
    grunt.loadNpmTasks('grunt-contrib-concat');
    grunt.loadNpmTasks('grunt-contrib-jshint');
    grunt.loadNpmTasks('grunt-contrib-qunit');
    grunt.loadNpmTasks('grunt-contrib-uglify');
    grunt.loadNpmTasks('grunt-contrib-watch');

    // Define your tasks here
    grunt.registerTask('default', ['jshint', 'concat', 'uglify']);

    // Build
    grunt.registerTask('build', ['jshint', 'concat', 'uglify']);

    // Test
    grunt.registerTask('test', ['qunit']);

    // Watch
    grunt.registerTask('watch', ['watch']);

};<commit_msg>Modified gruntfile to output files to dist folder<commit_after>module.exports = function(grunt) {

    // Configuration goes here
    grunt.initConfig({
        pkg: grunt.file.readJSON('package.json'),
        concat: {
            options: {
                separator: ';'
            },
            dist: {
                src: ['src/zest.js'],
                dest: 'dist/zest.js'
            }
        },
        jshint: {
            files: ['src/**/*.js'],
            options: {
                strict: true,
                globals: {
                    console: true
                }
            }
        },
        qunit: {
            files: ['test/**/*.html']
        },
        uglify: {
            options: {
                banner: '/**\n * Zest v<%= pkg.version %>\n * Copyright 2014. <%= pkg.author %>\n * <%= pkg.homepage %>\n' +
        ' * <%= grunt.template.today("yyyy-mm-dd") %>\n */\n'
            },
            script: {
                files: {
                    'dist/zest.min.js': ['zest.js']
                }
            }
        },
        watch: {
            scripts: {
                files: ['src/**/*.js'],
                tasks: ['jshint', 'concat', 'uglify']
            }
        }
    });

    // Load plugins here
    grunt.loadNpmTasks('grunt-contrib-concat');
    grunt.loadNpmTasks('grunt-contrib-jshint');
    grunt.loadNpmTasks('grunt-contrib-qunit');
    grunt.loadNpmTasks('grunt-contrib-uglify');
    grunt.loadNpmTasks('grunt-contrib-watch');

    // Define your tasks here
    grunt.registerTask('default', ['jshint', 'concat', 'uglify']);

    // Build
    grunt.registerTask('build', ['jshint', 'concat', 'uglify']);

    // Test
    grunt.registerTask('test', ['qunit']);

    // Watch
    grunt.registerTask('watch', ['watch']);

};<|endoftext|>


<commit_before>/***/
(function() {

  typeof module != 'undefined' && (module.exports = timecalc);
  this.timecalc = timecalc;

  function timecalc(opts) {

    var keys = ['Y', 'M', 'D', 'h', 'm', 's', 'ms'];
    var maxv = [null, 12, 30, 24, 60, 60, 1000];
    var U = {
      enable: {},
      display: {}
    }, b = null;

    watcher.basepoint = function(v) {
      return v ? (b = v): b;
    };
    watcher.enable = function() {
      return U.enable;
    };
    watcher.display = function() {
      return U.display;
    };
    watcher.diff = function() {
      return Date.now() - b.getTime();
    };

    return mergeOpts(opts, true), watcher;

    function watcher(opts) {
      mergeOpts(opts);
      var i = keys.length, diff = watcher.diff(), lastd = null;
      if(diff < 0) // TODO accept
        throw new Error('Time is never return.');
      while(i-- > 0) {
        var test = parseInt(diff / maxv[i]), key = keys[i];
        if(test == 0 || i === 0)
          return U.enable[key] === false ? lastd: createDisp(key);
        U.enable[key] !== false && (lastd = createDisp(key)), diff = test;
      }
      function createDisp(key) {
        var repl = String(U.display[key] || key);
        if(repl.indexOf('%d') >= 0)
          return repl.replace(/[^\\]%d/g, diff);
        if(repl.indexOf('%D') == 0)
          return repl.substr(2);
        return diff + repl;
      }
    }

    function mergeOpts(opts, set_base) {
      opts = opts instanceof Object ? opts: {};
      ['enable', 'display'].forEach(function(k) {
        !opts[k] && (opts[k] = {});
        for( var i in opts[k])
          U[k][i] = opts[k][i];
      });
      var nb = new Date(opts.basepoint == null ? Date.now(): opts.basepoint);
      (set_base || opts.basepoint) && (b = nb);
    }

  }

}).call(typeof window == 'undefined' ? this: window);
<commit_msg>improve exports, v0.6.2<commit_after>/***/
(function(hasWin, hasMod) {

  hasWin && (window.timecalc = timecalc)
  hasMod && module.exports && (module.exports = timecalc);

  function timecalc(opts) {

    var keys = ['Y', 'M', 'D', 'h', 'm', 's', 'ms'];
    var maxv = [null, 12, 30, 24, 60, 60, 1000];
    var U = {
      enable: {},
      display: {}
    }, b = null;

    watcher.basepoint = function(v) {
      return v ? (b = v): b;
    };
    watcher.enable = function() {
      return U.enable;
    };
    watcher.display = function() {
      return U.display;
    };
    watcher.diff = function() {
      return Date.now() - b.getTime();
    };

    return mergeOpts(opts, true), watcher;

    function watcher(opts) {
      mergeOpts(opts);
      var i = keys.length, diff = watcher.diff(), lastd = null;
      if(diff < 0) // TODO accept
        throw new Error('Time is never return.');
      while(i-- > 0) {
        var test = parseInt(diff / maxv[i]), key = keys[i];
        if(test == 0 || i === 0)
          return U.enable[key] === false ? lastd: createDisp(key);
        U.enable[key] !== false && (lastd = createDisp(key)), diff = test;
      }
      function createDisp(key) {
        var repl = String(U.display[key] || key);
        if(repl.indexOf('%d') >= 0)
          return repl.replace(/[^\\]%d/g, diff);
        if(repl.indexOf('%D') == 0)
          return repl.substr(2);
        return diff + repl;
      }
    }

    function mergeOpts(opts, set_base) {
      opts = opts instanceof Object ? opts: {};
      ['enable', 'display'].forEach(function(k) {
        !opts[k] && (opts[k] = {});
        for( var i in opts[k])
          U[k][i] = opts[k][i];
      });
      var nb = new Date(opts.basepoint == null ? Date.now(): opts.basepoint);
      (set_base || opts.basepoint) && (b = nb);
    }

  }

})(typeof window == 'undefined', typeof module == 'undefined');
<|endoftext|>