<commit_before>var async = require('async');
var _mapValues = require('lodash/mapValues');
var _zipObject = require('lodash/zipObject');

var DEFAULT_PAGESIZE = 50;

/**
 * This is a collection of methods that allow you to create, update and delete social items.
 *
 * These methods all exclude the 'loggedinuser' parameter as they are all carried out only by
 * the currently logged in user and / or system level calls (e.g. adding a user via integration
 * with an SSO flow).
 *
 */
module.exports = function (api) {
  var client = api.client;
  var messaging = api.messaging;
  var q = client.queries;

  function joinGroup (keyspace, group, user, timestamp, cb) {
    var memberValues = [group, user, timestamp];
    client.execute(q(keyspace, 'upsertMember'), memberValues, function (err) {
      if (err) return cb(err);
      getGroup(keyspace, group, function (err, result) {
        if (err) return cb(err);
        var joinGroupContent = {
          category: 'social-group',
          type: 'new-member',
          data: {
            group: {
              id: group,
              name: result.groupname
            }
          }
        };
        api.post.addPost(keyspace, user, joinGroupContent, 'application/json', Date.now(), 'public', function (err, result) {
          if (err) return cb(err);
          cb(null, _zipObject(['group', 'user', 'timestamp'], memberValues));
        });
      });
    });
  }

  function addGroup (keyspace, groupName, supergroupId, user, timestamp, options, next) {
    if (!next) {
      next = options;
      options = {};
    }

    var groupData = options.groupData || {};
    var group = client.isValidId(options.group) ? options.group : client.generateId();

    groupData = _mapValues(groupData, function (value) {
      return value.toString();
    }); // Always ensure our groupdata is <text,text>

    // Check group doesn't already exist with this name in this supergroup
    getGroupByNameWithinSupergroup(keyspace, groupName, supergroupId, function (err, existingGroup) {
      if (err && err.statusCode !== 404) { return next(err); }
      if (existingGroup) {
        return next({
          statusCode: 409,
          message: 'Group with groupname ' + groupName + ' already exists for supergroupId ' + supergroupId
        });
      }

      var groupValues = [group, groupData, groupName, supergroupId];

      client.execute(q(keyspace, 'upsertGroup'), groupValues, {}, function (err, result) {
        if (err) { return next(err); }
        joinGroup(keyspace, group, user, timestamp, function (err, result) {
          if (err) { return next(err); }
          next(null, _zipObject(['group', 'groupData', 'groupName', 'supergroupId'], groupValues));
        });
      });
    });
  }

  function getGroupByNameWithinSupergroup (keyspace, groupName, supergroupId, next) {
    client.get(q(keyspace, 'selectGroupByNameAndSupergroup'), [groupName, supergroupId], {}, function (err, result) {
      if (err) { return next(err); }
      if (!result) { return next(api.common.error(404, 'Unable to find group by groupName: ' + groupName + ' and supergroupId ' + supergroupId)); }
      next(null, result);
    });
  }

  function getGroup (keyspace, group, next) {
    client.get(q(keyspace, 'selectGroupById'), [group], {}, function (err, result) {
      if (err) { return next(err); }
      if (!result) { return next(api.common.error(404, 'Unable to find group by id: ' + group)); }
      next(null, result);
    });
  }

  function updateGroup (keyspace, userAltid, group, groupName, supergroupId, groupData, next) {
    getGroup(keyspace, group, function (err, result) {
      if (err) { return next(err); }

      if (userAltid.toString() !== result.groupdata.admin) {
        return next(new Error('Unable to update the group, only admin can update it.'));
      }

      groupData = _mapValues(groupData, function (value) {
        return value.toString();
      }); // Always ensure our groupData is <text,text>

      var groupValues = [groupName, supergroupId, groupData, group];
      client.execute(q(keyspace, 'updateGroup'), groupValues, {}, function (err, value) {
        if (err) { return next(err); }
        next(null, _zipObject(['groupName', 'supergroupId', 'groupData', 'group'], groupValues));
      });
    });
  }

  function removeMembers (jobData, cb) {
    client.execute(q(jobData.keyspace, 'removeMembers'), [jobData.group], function (err) {
      if (err) return cb(err);
      cb(null, { status: 'removed' });
    });
  }

  function removeGroup (keyspace, userAltid, user, group, next) {
    getGroup(keyspace, group, function (err, result) {
      if (err) { return next(err); }
      if (userAltid.toString() === result.groupdata.admin) {
        return next(new Error('Unable to remove the group, only admin can remove it.'));
      }
      var jobData = {
        keyspace: keyspace,
        user: user,
        group: group
      };

      var _removeMembers = function (cb) {
        if (messaging.enabled) {
          messaging.submit('seguir-remove-members', jobData, cb);
        } else {
          removeMembers(jobData, cb);
        }
      };
      var _removeGroup = function (cb) {
        client.execute(q(keyspace, 'removeGroup'), [group], function (err) {
          if (err) return cb(err);
          cb(null, { status: 'removed' });
        });
      };
      async.series([
        _removeMembers,
        _removeGroup
      ], next);
    });
  }

  function getGroupsBySupergroupId (keyspace, supergroupId, liu, options, next) {
    if (!next) {
      next = options;
      options = {};
    }
    var pageState = options.pageState;
    var pageSize = options.pageSize || DEFAULT_PAGESIZE;

    client.execute(q(keyspace, 'selectGroupsBySupergroupId'), [supergroupId], {pageState: pageState, pageSize: pageSize}, function (err, data, nextPageState) {
      if (err) { return next(err); }

      if (data && data.length > 0) {
        async.map(data, function (item, cb) {
          api.common.isUserGroupMember(keyspace, liu, item.group, function (err) {
            if (!err) {
              item.isMember = true;
            }
            cb();
          });
        }, function () {
          next(null, data, nextPageState);
        });
      } else {
        next(null, []);
      }
    });
  }

  function getGroupMembers (keyspace, group, next) {
    client.execute(q(keyspace, 'selectGroupMembers'), [group], {}, function (err, groupMembers) {
      if (err) { return next(err); }

      async.mapSeries(groupMembers, function (member, cb) {
        api.user.mapUserIdToUser(keyspace, member, ['user'], cb);
      }, next);
    });
  }

  function leaveGroup (keyspace, group, user, cb) {
    var memberValues = [group, user];
    client.execute(q(keyspace, 'removeMember'), memberValues, function (err) {
      if (err) return cb(err);
      cb(null, { status: 'removed' });
    });
  }

  return {
    addGroup: addGroup,
    getGroup: getGroup,
    joinGroup: joinGroup,
    leaveGroup: leaveGroup,
    updateGroup: updateGroup,
    removeGroup: removeGroup,
    removeMembers: removeMembers,
    getGroupsBySupergroupId: getGroupsBySupergroupId,
    getGroupMembers: getGroupMembers
  };
};
<commit_msg>Remove group authorization fix<commit_after>var async = require('async');
var _mapValues = require('lodash/mapValues');
var _zipObject = require('lodash/zipObject');

var DEFAULT_PAGESIZE = 50;

/**
 * This is a collection of methods that allow you to create, update and delete social items.
 *
 * These methods all exclude the 'loggedinuser' parameter as they are all carried out only by
 * the currently logged in user and / or system level calls (e.g. adding a user via integration
 * with an SSO flow).
 *
 */
module.exports = function (api) {
  var client = api.client;
  var messaging = api.messaging;
  var q = client.queries;

  function joinGroup (keyspace, group, user, timestamp, cb) {
    var memberValues = [group, user, timestamp];
    client.execute(q(keyspace, 'upsertMember'), memberValues, function (err) {
      if (err) return cb(err);
      getGroup(keyspace, group, function (err, result) {
        if (err) return cb(err);
        var joinGroupContent = {
          category: 'social-group',
          type: 'new-member',
          data: {
            group: {
              id: group,
              name: result.groupname
            }
          }
        };
        api.post.addPost(keyspace, user, joinGroupContent, 'application/json', Date.now(), 'public', function (err, result) {
          if (err) return cb(err);
          cb(null, _zipObject(['group', 'user', 'timestamp'], memberValues));
        });
      });
    });
  }

  function addGroup (keyspace, groupName, supergroupId, user, timestamp, options, next) {
    if (!next) {
      next = options;
      options = {};
    }

    var groupData = options.groupData || {};
    var group = client.isValidId(options.group) ? options.group : client.generateId();

    groupData = _mapValues(groupData, function (value) {
      return value.toString();
    }); // Always ensure our groupdata is <text,text>

    // Check group doesn't already exist with this name in this supergroup
    getGroupByNameWithinSupergroup(keyspace, groupName, supergroupId, function (err, existingGroup) {
      if (err && err.statusCode !== 404) { return next(err); }
      if (existingGroup) {
        return next({
          statusCode: 409,
          message: 'Group with groupname ' + groupName + ' already exists for supergroupId ' + supergroupId
        });
      }

      var groupValues = [group, groupData, groupName, supergroupId];

      client.execute(q(keyspace, 'upsertGroup'), groupValues, {}, function (err, result) {
        if (err) { return next(err); }
        joinGroup(keyspace, group, user, timestamp, function (err, result) {
          if (err) { return next(err); }
          next(null, _zipObject(['group', 'groupData', 'groupName', 'supergroupId'], groupValues));
        });
      });
    });
  }

  function getGroupByNameWithinSupergroup (keyspace, groupName, supergroupId, next) {
    client.get(q(keyspace, 'selectGroupByNameAndSupergroup'), [groupName, supergroupId], {}, function (err, result) {
      if (err) { return next(err); }
      if (!result) { return next(api.common.error(404, 'Unable to find group by groupName: ' + groupName + ' and supergroupId ' + supergroupId)); }
      next(null, result);
    });
  }

  function getGroup (keyspace, group, next) {
    client.get(q(keyspace, 'selectGroupById'), [group], {}, function (err, result) {
      if (err) { return next(err); }
      if (!result) { return next(api.common.error(404, 'Unable to find group by id: ' + group)); }
      next(null, result);
    });
  }

  function updateGroup (keyspace, userAltid, group, groupName, supergroupId, groupData, next) {
    getGroup(keyspace, group, function (err, result) {
      if (err) { return next(err); }

      if (userAltid.toString() !== result.groupdata.admin) {
        return next(new Error('Unable to update the group, only admin can update it.'));
      }

      groupData = _mapValues(groupData, function (value) {
        return value.toString();
      }); // Always ensure our groupData is <text,text>

      var groupValues = [groupName, supergroupId, groupData, group];
      client.execute(q(keyspace, 'updateGroup'), groupValues, {}, function (err, value) {
        if (err) { return next(err); }
        next(null, _zipObject(['groupName', 'supergroupId', 'groupData', 'group'], groupValues));
      });
    });
  }

  function removeMembers (jobData, cb) {
    client.execute(q(jobData.keyspace, 'removeMembers'), [jobData.group], function (err) {
      if (err) return cb(err);
      cb(null, { status: 'removed' });
    });
  }

  function removeGroup (keyspace, userAltid, user, group, next) {
    getGroup(keyspace, group, function (err, result) {
      if (err) { return next(err); }
      if (userAltid.toString() !== result.groupdata.admin) {
        return next(new Error('Unable to remove the group, only admin can remove it.'));
      }
      var jobData = {
        keyspace: keyspace,
        user: user,
        group: group
      };

      var _removeMembers = function (cb) {
        if (messaging.enabled) {
          messaging.submit('seguir-remove-members', jobData, cb);
        } else {
          removeMembers(jobData, cb);
        }
      };
      var _removeGroup = function (cb) {
        client.execute(q(keyspace, 'removeGroup'), [group], function (err) {
          if (err) return cb(err);
          cb(null, { status: 'removed' });
        });
      };
      async.series([
        _removeMembers,
        _removeGroup
      ], next);
    });
  }

  function getGroupsBySupergroupId (keyspace, supergroupId, liu, options, next) {
    if (!next) {
      next = options;
      options = {};
    }
    var pageState = options.pageState;
    var pageSize = options.pageSize || DEFAULT_PAGESIZE;

    client.execute(q(keyspace, 'selectGroupsBySupergroupId'), [supergroupId], {pageState: pageState, pageSize: pageSize}, function (err, data, nextPageState) {
      if (err) { return next(err); }

      if (data && data.length > 0) {
        async.map(data, function (item, cb) {
          api.common.isUserGroupMember(keyspace, liu, item.group, function (err) {
            if (!err) {
              item.isMember = true;
            }
            cb();
          });
        }, function () {
          next(null, data, nextPageState);
        });
      } else {
        next(null, []);
      }
    });
  }

  function getGroupMembers (keyspace, group, next) {
    client.execute(q(keyspace, 'selectGroupMembers'), [group], {}, function (err, groupMembers) {
      if (err) { return next(err); }

      async.mapSeries(groupMembers, function (member, cb) {
        api.user.mapUserIdToUser(keyspace, member, ['user'], cb);
      }, next);
    });
  }

  function leaveGroup (keyspace, group, user, cb) {
    var memberValues = [group, user];
    client.execute(q(keyspace, 'removeMember'), memberValues, function (err) {
      if (err) return cb(err);
      cb(null, { status: 'removed' });
    });
  }

  return {
    addGroup: addGroup,
    getGroup: getGroup,
    joinGroup: joinGroup,
    leaveGroup: leaveGroup,
    updateGroup: updateGroup,
    removeGroup: removeGroup,
    removeMembers: removeMembers,
    getGroupsBySupergroupId: getGroupsBySupergroupId,
    getGroupMembers: getGroupMembers
  };
};
<|endoftext|>


<commit_before>/* global module, User, Reference, Flair */
/**
 * ReferenceController
 *
 * @description :: Server-side logic for managing References
 * @help        :: See http://links.sailsjs.org/docs/controllers
 */

var Q = require('q'),
  async = require('async');

module.exports = {
  all: function (req, res) {
    var dateQuery, query;
    dateQuery = {};
    if (req.query.before !== undefined) {
      dateQuery["<"] = new Date(req.query.before);
    }
    if (req.query.after !== undefined) {
      dateQuery[">"] = new Date(req.query.after);
    }
    query = {
      type: ["event", "casual", "shiny", "redemption", "bank"]
    };
    if (Object.keys(dateQuery).length > 0) {
      query.createdAt = dateQuery;
    }

    Reference.find(query)
      .sort({createdAt: "asc"})
      .exec(function (err, refs) {
        if (err) {
          return res.serverError(err);
        }
        async.map(refs, function (ref, callback) {
          User.findOne({id: ref.user}).exec(function (err, refUser) {
            ref.user = refUser;
            callback(null, ref);
          });
        }, function (err, results) {
          if (err) {
            return res.serverError(err);
          }
          return res.ok(results);
        });
      });

  },

  add: function (req, res) {
    req.params = req.allParams();
    var protomatch = /^(https?):\/\/(www|[a-z0-9]*\.)?reddit\.com/;
    var endOfUrl = req.params.url.replace(protomatch, '');

    User.findOne({id: req.user.id}, function (err, refUser) {
      if (!refUser) {
        return res.notFound("Can't find user");
      } else {
        Reference.findOne({url: {endsWith: endOfUrl}, user: refUser.id}, function (err, ref) {
          if (err) {
            return res.serverError(err);
          }
          if (ref && (ref.type !== "egg" || req.params.type !== "egg")) {
            return res.badRequest();
          } else {
            Reference.create(
              {
                url: req.params.url,
                user: refUser.id,
                user2: req.params.user2,
                description: req.params.descrip,
                type: req.params.type,
                gave: req.params.gave,
                got: req.params.got,
                notes: req.params.notes,
                privatenotes: req.params.privatenotes,
                edited: false,
                number: req.params.number || 0
              },
              function (err, ref) {
                if (err) {
                  console.log(err);
                  return res.serverError();
                } else {
                  return res.ok(ref);
                }
              }
            );
          }
        });
      }
    });
  },

  edit: function (req, res) {
    req.params = req.allParams();

    User.findOne({id: req.user.id}, function (err, refUser) {
      if (!refUser) {
        return res.notFound("Can't find user");
      }
      Reference.findOne({id: req.params.id, user: refUser.id}).exec(function (err, ref) {
        if (err || !ref) {
          return res.notFound();
        }
        var approved = ref.approved;
        if (ref.url !== req.params.url || ref.type !== req.params.type || ref.number !== req.params.number) {
          approved = false;
        }
        Reference.update({id: req.params.id, user: refUser.id},
            {
              url: req.params.url,
              user: refUser.id,
              user2: req.params.user2,
              description: req.params.description,
              type: req.params.type,
              gave: req.params.gave,
              got: req.params.got,
              notes: req.params.notes,
              privatenotes: req.params.privatenotes,
              approved: approved,
              edited: true,
              number: req.params.number
            })
            .exec(function (err, ref) {
              if (err) {
                return res.serverError(err);
              }
              if (!ref) {
                return res.notFound();
              }
              return res.ok(ref);
            });
      });
    });
  },

  deleteRef: function (req, res) {
    var id = req.allParams().refId;

    Reference.findOne({id: id}).exec(function (err, ref) {
      if (!ref) {
        return res.notFound();
      }
      if (err) {
        return res.serverError(err);
      }
      if (ref.user === req.user.id || req.user.isMod) {
        if (ref.verified) {
          User.findOne({name: ref.user2.substring(3)}, function (err, otherUser) {
            if (err) {
              console.log("Warning: The trade being deleted is marked 'verified', but does not appear to have a complement.");
              return;
            }
            User.findOne({id: ref.user}, function (err2, thisUser) {
              if (err2 || !thisUser) {
                return res.status(404).json("User not found");
              }
              var query = {
                user: otherUser.id,
                url: new RegExp(ref.url.substring(ref.url.indexOf("/r/"))),
                user2: '/u/' + thisUser.name
              };
              //If a verified reference is deleted, its compelmentary reference is un-verified.
              Reference.update(query, {verified: false}, function (err, otherRef) {
                if (err) {
                  console.log("Error while updating complementary trade.");
                }
              });
            });
          });
        }
        Reference.destroy({id: id})
          .exec(function (err, refs) {
            if (err) {
              return res.serverError(err);
            } else {
              return res.ok(refs);
            }
          });
      } else {
        return res.forbidden();
      }
    });

  },

  comment: function (req, res) {
    var user = req.user,
      refUser = req.allParams().refUser,
      comment = req.allParams().comment;

    User.findOne({id: refUser}, function (err, reference) {
      Comment.create({user: reference.id, user2: user.name, message: comment}, function (err, com) {
        if (err) {
          return res.serverError(err);
        }
        return res.ok(com);
      });
    });

  },

  delComment: function (req, res) {
    var user = req.user,
      refUser = req.allParams().refUser,
      id = req.allParams().id;

    User.findOne({id: refUser}, function () {
      Comment.findOne({id: id}, function (err, comment) {
        if (!comment || err) {
          return res.notFound(err);
        }
        if ((user.name === comment.user2) || user.isMod) {
          Comment.destroy({id: id}, function (err, com) {
            return res.ok(com);
          });
        } else {
          return res.forbidden();
        }
      });
    });

  },

  approve: function (req, res) {
    if (!req.user.isMod) {
      return res.json("Not a mod", 403);
    }

    var id = req.allParams().id,
      approve = req.allParams().approve;

    User.findOne({id: req.allParams().userid}, function (err, refUser) {
      if (!refUser) {
        return res.notFound("User not found");
      }
      Reference.findOne(id, function (err, ref) {
        References.approve(ref, refUser.name, approve).then(function (result) {
          return res.status(200).json(ref);
        }, function (error) {
          return res.json(error);
        });
      });
    });
  },

  approveAll: function (req, res) {
    if (!req.user.isMod) {
      return res.json("Not a mod", 403);
    }

    User.findOne({id: req.allParams().userid}, function (err, refUser) {
      if (!refUser) {
        return res.notFound("User not found");
      }
      var promises = [];
      Reference.find({user: refUser.id, type: req.allParams().type}, function (err, refs) {
        if (err) {
          return res.serverError(err);
        }
        console.log(refs);
        for (var i = 0; i < refs.length; i++) {
          promises.push(References.approve(refs[i], refUser.name, true));
        }
        Promise.all(promises).then(function (err, result) {
          return res.status(200).json(result);
        }, function (error) {
          console.log(error);
          return res.status(error.statusCode).json(error);
        });
      });
    });
  },

  saveFlairs: function (req, res) {
    var flairs = req.allParams().flairs;
    Flair.destroy({}, function (err) {
      if (err) {
        return res.serverError(err);
      }
      var promises = [],
        added = [];
      flairs.forEach(function (flair) {
        promises.push(
          Flair.create(flair)
            .exec(function (err, newFlair) {
              added.push(newFlair);
            })
        );
      });

      Q.all(promises).then(function () {
        res.ok(added);
      });

    });

  },

  getFlairs: function (req, res) {
    Flair.find().exec(function (err, flairs) {
      res.ok(flairs);
    });
  }
};

<commit_msg>Removed unneeded console message<commit_after>/* global module, User, Reference, Flair */
/**
 * ReferenceController
 *
 * @description :: Server-side logic for managing References
 * @help        :: See http://links.sailsjs.org/docs/controllers
 */

var Q = require('q'),
  async = require('async');

module.exports = {
  all: function (req, res) {
    var dateQuery, query;
    dateQuery = {};
    if (req.query.before !== undefined) {
      dateQuery["<"] = new Date(req.query.before);
    }
    if (req.query.after !== undefined) {
      dateQuery[">"] = new Date(req.query.after);
    }
    query = {
      type: ["event", "casual", "shiny", "redemption", "bank"]
    };
    if (Object.keys(dateQuery).length > 0) {
      query.createdAt = dateQuery;
    }

    Reference.find(query)
      .sort({createdAt: "asc"})
      .exec(function (err, refs) {
        if (err) {
          return res.serverError(err);
        }
        async.map(refs, function (ref, callback) {
          User.findOne({id: ref.user}).exec(function (err, refUser) {
            ref.user = refUser;
            callback(null, ref);
          });
        }, function (err, results) {
          if (err) {
            return res.serverError(err);
          }
          return res.ok(results);
        });
      });

  },

  add: function (req, res) {
    req.params = req.allParams();
    var protomatch = /^(https?):\/\/(www|[a-z0-9]*\.)?reddit\.com/;
    var endOfUrl = req.params.url.replace(protomatch, '');

    User.findOne({id: req.user.id}, function (err, refUser) {
      if (!refUser) {
        return res.notFound("Can't find user");
      } else {
        Reference.findOne({url: {endsWith: endOfUrl}, user: refUser.id}, function (err, ref) {
          if (err) {
            return res.serverError(err);
          }
          if (ref && (ref.type !== "egg" || req.params.type !== "egg")) {
            return res.badRequest();
          } else {
            Reference.create(
              {
                url: req.params.url,
                user: refUser.id,
                user2: req.params.user2,
                description: req.params.descrip,
                type: req.params.type,
                gave: req.params.gave,
                got: req.params.got,
                notes: req.params.notes,
                privatenotes: req.params.privatenotes,
                edited: false,
                number: req.params.number || 0
              },
              function (err, ref) {
                if (err) {
                  console.log(err);
                  return res.serverError();
                } else {
                  return res.ok(ref);
                }
              }
            );
          }
        });
      }
    });
  },

  edit: function (req, res) {
    req.params = req.allParams();

    User.findOne({id: req.user.id}, function (err, refUser) {
      if (!refUser) {
        return res.notFound("Can't find user");
      }
      Reference.findOne({id: req.params.id, user: refUser.id}).exec(function (err, ref) {
        if (err || !ref) {
          return res.notFound();
        }
        var approved = ref.approved;
        if (ref.url !== req.params.url || ref.type !== req.params.type || ref.number !== req.params.number) {
          approved = false;
        }
        Reference.update({id: req.params.id, user: refUser.id},
            {
              url: req.params.url,
              user: refUser.id,
              user2: req.params.user2,
              description: req.params.description,
              type: req.params.type,
              gave: req.params.gave,
              got: req.params.got,
              notes: req.params.notes,
              privatenotes: req.params.privatenotes,
              approved: approved,
              edited: true,
              number: req.params.number
            })
            .exec(function (err, ref) {
              if (err) {
                return res.serverError(err);
              }
              if (!ref) {
                return res.notFound();
              }
              return res.ok(ref);
            });
      });
    });
  },

  deleteRef: function (req, res) {
    var id = req.allParams().refId;

    Reference.findOne({id: id}).exec(function (err, ref) {
      if (!ref) {
        return res.notFound();
      }
      if (err) {
        return res.serverError(err);
      }
      if (ref.user === req.user.id || req.user.isMod) {
        if (ref.verified) {
          User.findOne({name: ref.user2.substring(3)}, function (err, otherUser) {
            if (err) {
              console.log("Warning: The trade being deleted is marked 'verified', but does not appear to have a complement.");
              return;
            }
            User.findOne({id: ref.user}, function (err2, thisUser) {
              if (err2 || !thisUser) {
                return res.status(404).json("User not found");
              }
              var query = {
                user: otherUser.id,
                url: new RegExp(ref.url.substring(ref.url.indexOf("/r/"))),
                user2: '/u/' + thisUser.name
              };
              //If a verified reference is deleted, its compelmentary reference is un-verified.
              Reference.update(query, {verified: false}, function (err, otherRef) {
                if (err) {
                  console.log("Error while updating complementary trade.");
                }
              });
            });
          });
        }
        Reference.destroy({id: id})
          .exec(function (err, refs) {
            if (err) {
              return res.serverError(err);
            } else {
              return res.ok(refs);
            }
          });
      } else {
        return res.forbidden();
      }
    });

  },

  comment: function (req, res) {
    var user = req.user,
      refUser = req.allParams().refUser,
      comment = req.allParams().comment;

    User.findOne({id: refUser}, function (err, reference) {
      Comment.create({user: reference.id, user2: user.name, message: comment}, function (err, com) {
        if (err) {
          return res.serverError(err);
        }
        return res.ok(com);
      });
    });

  },

  delComment: function (req, res) {
    var user = req.user,
      refUser = req.allParams().refUser,
      id = req.allParams().id;

    User.findOne({id: refUser}, function () {
      Comment.findOne({id: id}, function (err, comment) {
        if (!comment || err) {
          return res.notFound(err);
        }
        if ((user.name === comment.user2) || user.isMod) {
          Comment.destroy({id: id}, function (err, com) {
            return res.ok(com);
          });
        } else {
          return res.forbidden();
        }
      });
    });

  },

  approve: function (req, res) {
    if (!req.user.isMod) {
      return res.json("Not a mod", 403);
    }

    var id = req.allParams().id,
      approve = req.allParams().approve;

    User.findOne({id: req.allParams().userid}, function (err, refUser) {
      if (!refUser) {
        return res.notFound("User not found");
      }
      Reference.findOne(id, function (err, ref) {
        References.approve(ref, refUser.name, approve).then(function (result) {
          return res.status(200).json(ref);
        }, function (error) {
          return res.json(error);
        });
      });
    });
  },

  approveAll: function (req, res) {
    if (!req.user.isMod) {
      return res.json("Not a mod", 403);
    }

    User.findOne({id: req.allParams().userid}, function (err, refUser) {
      if (!refUser) {
        return res.notFound("User not found");
      }
      var promises = [];
      Reference.find({user: refUser.id, type: req.allParams().type}, function (err, refs) {
        if (err) {
          return res.serverError(err);
        }
        for (var i = 0; i < refs.length; i++) {
          promises.push(References.approve(refs[i], refUser.name, true));
        }
        Promise.all(promises).then(function (err, result) {
          return res.status(200).json(result);
        }, function (error) {
          console.log(error);
          return res.status(error.statusCode).json(error);
        });
      });
    });
  },

  saveFlairs: function (req, res) {
    var flairs = req.allParams().flairs;
    Flair.destroy({}, function (err) {
      if (err) {
        return res.serverError(err);
      }
      var promises = [],
        added = [];
      flairs.forEach(function (flair) {
        promises.push(
          Flair.create(flair)
            .exec(function (err, newFlair) {
              added.push(newFlair);
            })
        );
      });

      Q.all(promises).then(function () {
        res.ok(added);
      });

    });

  },

  getFlairs: function (req, res) {
    Flair.find().exec(function (err, flairs) {
      res.ok(flairs);
    });
  }
};

<|endoftext|>


<commit_before>module.export = Crafty.c('<%= name %>', {

  _placeholder: "..",

  init: function() {
    // called when this component is added to an entity
  },

  remove: function (entityDestroyed) {
    // called just before this component is removed
    //  or before an entity is destroyed
  },

  // constructor
  <%= name %>: function(placeholder) {
    this.placeholder = placeholder;
  }

});
<commit_msg>Removed modules.export from non-module script<commit_after>Crafty.c('<%= name %>', {

  _placeholder: "..",

  init: function() {
    // called when this component is added to an entity
  },

  remove: function (entityDestroyed) {
    // called just before this component is removed
    //  or before an entity is destroyed
  },

  // constructor
  <%= name %>: function(placeholder) {
    this.placeholder = placeholder;
  }

});
<|endoftext|>


<commit_before>define(['js/core/DomElement', 'js/core/List', 'js/core/Bindable'], function (DomElement, List, Bindable) {

    var undefined,
        SvgElement = DomElement.inherit("js.svg.SvgElement", {

            defaults: {
                transformations: List,
                _transform: null,

                translateX: undefined,
                translateY: undefined,

                scaleX: undefined,
                scaleY: undefined,

                rotation: undefined,
                rotationX: undefined,
                rotationY: undefined
            },

            $classAttributes: ["transformations", "translateX", "translateY", "scaleX", "scaleY", "rotation", "rotationX", "rotationY"],

            ctor: function () {
                // default namespace
                this.$namespace = SvgElement.SVG_NAMESPACE;
                this.callBase();

                this.bind("transformations", '*', this._refreshTransform, this);
            },

            transform: function (transform) {
                if (this.$transform) {
                    this.$transform.set("transform", transform);
                } else {
                    this.$transform = new SvgElement.Transform({
                        transform: transform
                    });
                    this.$.transformations.add(this.$transform);
                }

                return this;
            },

            addChild: function (child) {
                this.callBase();
                child.$svgRoot = this.$svgRoot;
            },

            getSvgRoot: function () {
                if(!this.$svgRoot){
                    var parent = this.$parent;
                    while(parent instanceof SvgElement && !parent.$svgRoot){
                        parent = this.$parent.$parent;
                    }

                    if (!parent) {
                        return null;
                    }

                    return parent.$svgRoot;

                }
                return this.$svgRoot;
            },

            _commitChangedAttributes: function ($) {
                var x, y, r;

                if (this._hasSome($, ["translateX", "translateY"])) {
                    x = this.$.translateX;
                    y = this.$.translateY;

                    !(x === undefined && y === undefined) && this.translate(x, y);
                }

                if (this._hasSome($, ["scaleX", "scaleY"])) {
                    x = this.$.scaleX;
                    y = this.$.scaleY;

                    !(x === undefined && y === undefined) && this.scale(x, y);
                }

                if (this._hasSome($, ["rotation", "rotationX", "rotationY"])) {
                    r = this.$.rotation;
                    x = this.$.rotationX;
                    y = this.$.rotationY;

                    !(x === undefined && y === undefined && r === undefined) && this.rotate(r, x, y);
                }

                this.callBase();
            },

            scale: function (sx, sy) {

                if (sx === null || sy === null) {
                    return;
                }

                if (!sy && sy !== 0) {
                    sy = sx;
                }

                if (this.$scale) {
                    this.$scale.set({
                        sx: sx,
                        sy: sy
                    });
                } else {
                    this.$scale = new SvgElement.Scale({
                        sx: sx,
                        sy: sy
                    });
                    this.$.transformations.add(this.$scale);
                }

                return this;
            },

            translate: function (x, y) {

                if (this.$translate) {
                    this.$translate.set({
                        x: x,
                        y: y
                    });
                } else {
                    this.$translate = new SvgElement.Translate({
                        x: x,
                        y: y
                    });
                    this.$.transformations.add(this.$translate);
                }

                return this;
            },

            rotate: function (r, x, y) {
                if (this.$rotate) {
                    this.$rotate.set({
                        r: r,
                        x: x,
                        y: y
                    });
                } else {
                    this.$rotate = new SvgElement.Rotate({
                        r: r,
                        x: x,
                        y: y
                    });
                    this.$.transformations.add(this.$rotate);
                }

                return this;
            },

            _refreshTransform: function () {

                var transformations = [];

                this.$.transformations.each(function (t) {
                    if (t instanceof SvgElement.TransformBase) {
                        transformations.push(t.toString());
                    } else {
                        transformations.push(t);
                    }
                });

                this.set('_transform', transformations.join(" "));
            },

            _renderTransform: function () {
                // transforms needs to be set via transformations
            },

            _render_transform: function (transform) {
                this._setAttribute("transform", transform);
            },

            // render each href Element in xlink namespace
            _renderHref: function (href, oldHref) {
                this._setAttribute("href", href, SvgElement.XLINK_NAMESPACE);
            },

            localToGlobalFactor: function () {
                if (this.$parent) {
                    // TODO: add scale
                    return this.$parent.localToGlobalFactor();
                }

                return {
                    x: 1,
                    y: 1
                };
            },

            globalToLocalFactor: function () {
                if (this.$parent) {
                    // TODO: add scale
                    return this.$parent.globalToLocalFactor();
                }

                return {
                    x: 1,
                    y: 1
                };
            },

            localPointToGlobal: function (point) {

                var factor = this.localToGlobalFactor();

                return {
                    x: point.x * factor.x,
                    y: point.y * factor.y
                }
            },

            globalPointToLocal: function (point) {

                var factor = this.globalToLocalFactor();

                return {
                    x: point.x * factor.x,
                    y: point.y * factor.y
                }

            }
        });

    SvgElement.XLINK_NAMESPACE = "http://www.w3.org/1999/xlink";
    SvgElement.SVG_NAMESPACE = "http://www.w3.org/2000/svg";

    SvgElement.Matrix = function (a, b, c, d, e, f) {
        if (arguments.length) {
            this.a = a;
            this.b = b;
            this.c = c;
            this.d = d;
            this.e = e;
            this.f = f;
        } else {
            this.a = 1;
            this.b = 0;
            this.c = 0;
            this.d = 1;
            this.e = 0;
            this.f = 0;
        }
    };

    SvgElement.TransformBase = Bindable.inherit('js.svg.SvgElement.TransformBase', {
    });

    SvgElement.Transform = SvgElement.TransformBase.inherit('js.svg.SvgElement.TransformBase', {
        defaults: {
            transform: null
        },

        toString: function () {
            return this.$.transform || "";
        }
    });

    SvgElement.Translate = SvgElement.TransformBase.inherit("js.svg.SvgElement.Translate", {
        toString: function () {
            return "translate(" + (this.$.x || 0) + "," + (this.$.y || 0) + ")";
        }
    });

    SvgElement.Scale = SvgElement.TransformBase.inherit("js.svg.SvgElement.Scale", {

        defaults: {
            sx: 1,
            sy: 1
        },

        toString: function () {
            return "scale(" + this.$.sx + "," + this.$.sy + ")";
        }
    });

    SvgElement.Rotate = SvgElement.TransformBase.inherit("js.svg.SvgElement.Rotate", {

        defaults: {
            r: 0,
            x: 0,
            y: 0
        },

        toString: function () {
            return "rotate(" + (this.$.r || 0) + "," + (this.$.x || 0) + "," + (this.$.y || 0) + ")";
        }
    });

    return SvgElement;
});<commit_msg>fixed getSvgRoot<commit_after>define(['js/core/DomElement', 'js/core/List', 'js/core/Bindable'], function (DomElement, List, Bindable) {

    var undefined,
        SvgElement = DomElement.inherit("js.svg.SvgElement", {

            defaults: {
                transformations: List,
                _transform: null,

                translateX: undefined,
                translateY: undefined,

                scaleX: undefined,
                scaleY: undefined,

                rotation: undefined,
                rotationX: undefined,
                rotationY: undefined
            },

            $classAttributes: ["transformations", "translateX", "translateY", "scaleX", "scaleY", "rotation", "rotationX", "rotationY"],

            ctor: function () {
                // default namespace
                this.$namespace = SvgElement.SVG_NAMESPACE;
                this.callBase();

                this.bind("transformations", '*', this._refreshTransform, this);
            },

            transform: function (transform) {
                if (this.$transform) {
                    this.$transform.set("transform", transform);
                } else {
                    this.$transform = new SvgElement.Transform({
                        transform: transform
                    });
                    this.$.transformations.add(this.$transform);
                }

                return this;
            },

            addChild: function (child) {
                this.callBase();
                child.$svgRoot = this.$svgRoot;
            },

            getSvgRoot: function () {
                if(!this.$svgRoot){
                    var parent = this.$parent;
                    while(parent instanceof SvgElement && !parent.$svgRoot){
                        parent = parent.$parent;
                    }

                    if (!parent) {
                        return null;
                    }

                    return parent.$svgRoot;

                }
                return this.$svgRoot;
            },

            _commitChangedAttributes: function ($) {
                var x, y, r;

                if (this._hasSome($, ["translateX", "translateY"])) {
                    x = this.$.translateX;
                    y = this.$.translateY;

                    !(x === undefined && y === undefined) && this.translate(x, y);
                }

                if (this._hasSome($, ["scaleX", "scaleY"])) {
                    x = this.$.scaleX;
                    y = this.$.scaleY;

                    !(x === undefined && y === undefined) && this.scale(x, y);
                }

                if (this._hasSome($, ["rotation", "rotationX", "rotationY"])) {
                    r = this.$.rotation;
                    x = this.$.rotationX;
                    y = this.$.rotationY;

                    !(x === undefined && y === undefined && r === undefined) && this.rotate(r, x, y);
                }

                this.callBase();
            },

            scale: function (sx, sy) {

                if (sx === null || sy === null) {
                    return;
                }

                if (!sy && sy !== 0) {
                    sy = sx;
                }

                if (this.$scale) {
                    this.$scale.set({
                        sx: sx,
                        sy: sy
                    });
                } else {
                    this.$scale = new SvgElement.Scale({
                        sx: sx,
                        sy: sy
                    });
                    this.$.transformations.add(this.$scale);
                }

                return this;
            },

            translate: function (x, y) {

                if (this.$translate) {
                    this.$translate.set({
                        x: x,
                        y: y
                    });
                } else {
                    this.$translate = new SvgElement.Translate({
                        x: x,
                        y: y
                    });
                    this.$.transformations.add(this.$translate);
                }

                return this;
            },

            rotate: function (r, x, y) {
                if (this.$rotate) {
                    this.$rotate.set({
                        r: r,
                        x: x,
                        y: y
                    });
                } else {
                    this.$rotate = new SvgElement.Rotate({
                        r: r,
                        x: x,
                        y: y
                    });
                    this.$.transformations.add(this.$rotate);
                }

                return this;
            },

            _refreshTransform: function () {

                var transformations = [];

                this.$.transformations.each(function (t) {
                    if (t instanceof SvgElement.TransformBase) {
                        transformations.push(t.toString());
                    } else {
                        transformations.push(t);
                    }
                });

                this.set('_transform', transformations.join(" "));
            },

            _renderTransform: function () {
                // transforms needs to be set via transformations
            },

            _render_transform: function (transform) {
                this._setAttribute("transform", transform);
            },

            // render each href Element in xlink namespace
            _renderHref: function (href, oldHref) {
                this._setAttribute("href", href, SvgElement.XLINK_NAMESPACE);
            },

            localToGlobalFactor: function () {
                if (this.$parent) {
                    // TODO: add scale
                    return this.$parent.localToGlobalFactor();
                }

                return {
                    x: 1,
                    y: 1
                };
            },

            globalToLocalFactor: function () {
                if (this.$parent) {
                    // TODO: add scale
                    return this.$parent.globalToLocalFactor();
                }

                return {
                    x: 1,
                    y: 1
                };
            },

            localPointToGlobal: function (point) {

                var factor = this.localToGlobalFactor();

                return {
                    x: point.x * factor.x,
                    y: point.y * factor.y
                }
            },

            globalPointToLocal: function (point) {

                var factor = this.globalToLocalFactor();

                return {
                    x: point.x * factor.x,
                    y: point.y * factor.y
                }

            }
        });

    SvgElement.XLINK_NAMESPACE = "http://www.w3.org/1999/xlink";
    SvgElement.SVG_NAMESPACE = "http://www.w3.org/2000/svg";

    SvgElement.Matrix = function (a, b, c, d, e, f) {
        if (arguments.length) {
            this.a = a;
            this.b = b;
            this.c = c;
            this.d = d;
            this.e = e;
            this.f = f;
        } else {
            this.a = 1;
            this.b = 0;
            this.c = 0;
            this.d = 1;
            this.e = 0;
            this.f = 0;
        }
    };

    SvgElement.TransformBase = Bindable.inherit('js.svg.SvgElement.TransformBase', {
    });

    SvgElement.Transform = SvgElement.TransformBase.inherit('js.svg.SvgElement.TransformBase', {
        defaults: {
            transform: null
        },

        toString: function () {
            return this.$.transform || "";
        }
    });

    SvgElement.Translate = SvgElement.TransformBase.inherit("js.svg.SvgElement.Translate", {
        toString: function () {
            return "translate(" + (this.$.x || 0) + "," + (this.$.y || 0) + ")";
        }
    });

    SvgElement.Scale = SvgElement.TransformBase.inherit("js.svg.SvgElement.Scale", {

        defaults: {
            sx: 1,
            sy: 1
        },

        toString: function () {
            return "scale(" + this.$.sx + "," + this.$.sy + ")";
        }
    });

    SvgElement.Rotate = SvgElement.TransformBase.inherit("js.svg.SvgElement.Rotate", {

        defaults: {
            r: 0,
            x: 0,
            y: 0
        },

        toString: function () {
            return "rotate(" + (this.$.r || 0) + "," + (this.$.x || 0) + "," + (this.$.y || 0) + ")";
        }
    });

    return SvgElement;
});<|endoftext|>


<commit_before><commit_msg>ugly attempt at fixing flaky test<commit_after><|endoftext|>


<commit_before>var Buildings = [];
Buildings.idMap = {};

var finishedLoads = [];
var loading = false;

var buildingLoadReady = false;

$.holdReady(true);

window.loadBuilding = function(JS_FILE_NAME, BUILDING_NAME, VARIABLE_NAME, MACHINE_NAME){
	buildingLoadReady = false;

	//load the building
	if(loading){
		return finishedLoads.push(arguments);
	} else {
		loading = true;

		util.loadJS("../../data/"+JS_FILE_NAME, function(){
			Buildings.push([BUILDING_NAME, window[VARIABLE_NAME]]);
			Buildings.idMap[MACHINE_NAME.toLowerCase()] = Buildings.length - 1;

			loading = false;
			if(finishedLoads.length > 0){
				window.loadBuilding.apply(window, finishedLoads.pop())
			} else {
				buildingLoadReady = true;
			}
		});

	}
}

window.endBuildingLoad = function(){
	$.holdReady(false);
}

var Data = {};

Data.findRoomById = function(id){
	//if found, returns [room, Building_id, floor_id]
	//otherwise returns false.
	return Data.iterateRooms(function(Room, i, j){
		var RoomIds = Room[5];
		if(typeof RoomIds != "undefined"){
			for(var l=0;l<RoomIds.length;l++){
				if(RoomIds[l] === id){
					return [Room, i, j, RoomIds]
				}
			}
		}
	}, false);
}

Data.iterateRooms = function(filter, def){
	// filter = function(RoomObject, Building, Floor)
	// return true from filter to abort loop.
	for(var i=0;i<Buildings.length;i++){
		var Floors = Buildings[i][1];
		for(var j=0;j<Floors.length;j++){
			var Rooms = Floors[j][1];
			for(var k=0;k<Rooms.length;k++){
				var res = filter(Rooms[k], i, j)
				if(res){
					return res;
				}
			}
		}
	}
	return def;
}

Data.searchSingle = function(query, callback){
	//Search single map
	if(query.length < 3){
		return callback(false);
	}

	var results = [];

	//match a string
	var matches = function(q, str){
		if(typeof str == "string"){
			return (str.toLowerCase().indexOf(q.toLowerCase()) !== -1);
		} else if(typeof str !== "undefined"){
			try{
				for(var i=0;i<str.length;i++){
					if(matches(q, str[i])){
						return true;
					}
				}
			} catch(e){}
			return false;
		} else {
			return false;
		}
	}

	var matchesW = function(q, str){
		var res = (matches(q, str) || matches(q.split(" ").join("-"), str));
		return res;
	}

	var data = Data.iterateRooms(function(room, i, j){
		//do stuff here
		//search for query somehow
		if(matchesW(query, room[4]) || matchesW(query, room[5]) || matchesW(query, room[6]) || matchesW(query, Buildings[i][0])){
			results.push(
			{
				"id": (typeof room[5] !== "undefined")?room[5][0]:undefined,
				"name": room[4],
				"building": Buildings[i][0],
				"floor": Buildings[i][1][j][0]
			})
		}
	});

	callback(results);
}<commit_msg>only use student rooms in room search (closes #7)<commit_after>var Buildings = [];
Buildings.idMap = {};

var finishedLoads = [];
var loading = false;

var buildingLoadReady = false;

$.holdReady(true);

window.loadBuilding = function(JS_FILE_NAME, BUILDING_NAME, VARIABLE_NAME, MACHINE_NAME){
	buildingLoadReady = false;

	//load the building
	if(loading){
		return finishedLoads.push(arguments);
	} else {
		loading = true;

		util.loadJS("../../data/"+JS_FILE_NAME, function(){
			Buildings.push([BUILDING_NAME, window[VARIABLE_NAME]]);
			Buildings.idMap[MACHINE_NAME.toLowerCase()] = Buildings.length - 1;

			loading = false;
			if(finishedLoads.length > 0){
				window.loadBuilding.apply(window, finishedLoads.pop())
			} else {
				buildingLoadReady = true;
			}
		});

	}
}

window.endBuildingLoad = function(){
	$.holdReady(false);
}

var Data = {};

Data.findRoomById = function(id){
	//if found, returns [room, Building_id, floor_id]
	//otherwise returns false.
	return Data.iterateRooms(function(Room, i, j){
		var RoomIds = Room[5];
		if(typeof RoomIds != "undefined"){
			for(var l=0;l<RoomIds.length;l++){
				if(RoomIds[l] === id){
					return [Room, i, j, RoomIds]
				}
			}
		}
	}, false);
}

Data.iterateRooms = function(filter, def){
	// filter = function(RoomObject, Building, Floor)
	// return true from filter to abort loop.
	for(var i=0;i<Buildings.length;i++){
		var Floors = Buildings[i][1];
		for(var j=0;j<Floors.length;j++){
			var Rooms = Floors[j][1];
			for(var k=0;k<Rooms.length;k++){
				var res = filter(Rooms[k], i, j)
				if(res){
					return res;
				}
			}
		}
	}
	return def;
}

Data.searchSingle = function(query, callback){
	//Search single map
	if(query.length < 3){
		return callback(false);
	}

	var results = [];

	//match a string
	var matches = function(q, str){
		if(typeof str == "string"){
			return (str.toLowerCase().indexOf(q.toLowerCase()) !== -1);
		} else if(typeof str !== "undefined"){
			try{
				for(var i=0;i<str.length;i++){
					if(matches(q, str[i])){
						return true;
					}
				}
			} catch(e){}
			return false;
		} else {
			return false;
		}
	}

	var matchesW = function(q, str){
		var res = (matches(q, str) || matches(q.split(" ").join("-"), str));
		return res;
	}

	var data = Data.iterateRooms(function(room, i, j){
		//do stuff here
		//search for query somehow
		if(room[6] !== "student" && room[7] !== true){
			//include only student rooms or rooms with forced attribute in search
			return;
		}
		if(matchesW(query, room[4]) || matchesW(query, room[5]) || matchesW(query, room[6]) || matchesW(query, Buildings[i][0])){
			results.push(
			{
				"id": (typeof room[5] !== "undefined")?room[5][0]:undefined,
				"name": room[4],
				"building": Buildings[i][0],
				"floor": Buildings[i][1][j][0]
			})
		}
	});

	callback(results);
}<|endoftext|>


<commit_before>/**
 * Created by ebbaholmstrom on 16-04-15.
 */
$ (function() {
    var d = new Date();
var weekday = new Array(7);
weekday[0] = "Sunday";
weekday[1] = "Monday";
weekday[2] = "Tuesday";
weekday[3] = "Wednesday";
weekday[4] = "Thursday";
weekday[5] = "Friday";
weekday[6] = "Saturday";

var n = weekday[d.getDay()];
document.getElementById("getDay").innerHTML = n;
})

$ (function(){
    var p = new Date();
var q = p.getDate();
document.getElementById("getDate").innerHTML = q;
})

$ (function() {
    var a = new Date();
var month = new Array(12);

month[0] = "January";
month[1] = "February";
month[2] = "Mars";
month[3] = "April";
month[4] = "May";
month[5] = "June";
month[6] = "July";
month[7] = "August";
month[8] = "September";
month[9] = "October";
month[10] = "November";
month[11] = "December";

var b = month[a.getMonth()];
document.getElementById("getMonth").innerHTML = b;
})
<commit_msg>Update dateAndTime.js<commit_after>/**
 * Created by ebbaholmstrom on 16-04-15.
 */
$ (function() {
    var d = new Date();
    var weekday = new Array(7);
    weekday[0] = "Sunday";
    weekday[1] = "Monday";
    weekday[2] = "Tuesday";
    weekday[3] = "Wednesday";
    weekday[4] = "Thursday";
    weekday[5] = "Friday";
    weekday[6] = "Saturday";

    var n = weekday[d.getDay()];
    document.getElementById("getDay").innerHTML = n;
})

$ (function(){
    var p = new Date();
    var q = p.getDate();
    document.getElementById("getDate").innerHTML = q;
})

$ (function() {
    var a = new Date();
    var month = new Array(12);

    month[0] = "January";
    month[1] = "February";
    month[2] = "Mars";
    month[3] = "April";
    month[4] = "May";
    month[5] = "June";
    month[6] = "July";
    month[7] = "August";
    month[8] = "September";
    month[9] = "October";
    month[10] = "November";
    month[11] = "December";

    var b = month[a.getMonth()];
    document.getElementById("getMonth").innerHTML = b;
})
<|endoftext|>


<commit_before>// code from jsx-render package by elie rotenberg
// not using the package as it references an old version of react
// and updating it to convert some HTML attributes to DOM, do some housekeeping

var _ = require("lodash");
var htmlparser = require("htmlparser2");
var React = require("react");
var ReactDOM = React.DOM;
var assert = require("assert");

var parseJSX = function parseJSX(source, env) {
    env = _.extend({}, React.DOM, env);
    var root = {
        parent: null,
        children: []
    };
    var curr = root;
    var parser = new htmlparser.Parser({
        onopentag: function onopentag(tagName, attribs) {
            attribs = attribs || {};
            curr = {
                parent: curr,
                children: [],
                tagName: tagName,
                attribs: attribs,
            };

            // remove dodgy/breaking attribs
            ['style','width','height'].forEach(function(attr){
                delete attribs[attr];
            });

            // convert html class attribute into DOM attribute
            if (attribs.class) {
                attribs.className = attribs.class;
                delete attribs.class;
            }

        },
        onclosetag: function onclosetag(tagName) {
            curr.parent.children.push(curr);
            curr = curr.parent;
        },
        ontext: function ontext(text) {
            curr.children.push(text);
        },
    }, {
        xmlMode: true,
    });
    var bfsConstruct = function bfsConstruct(curr) {
        if(!_.has(env, curr.tagName)) {
            throw new Error("Unknown tag " + curr.tagName);
        }
        else if(env[curr.tagName] === null) {
            throw new Error("Forbidden tag " + curr.tagName);
        }
        return env[curr.tagName].apply(null, [curr.attribs].concat(_.map(curr.children, function(child) { return _.isString(child) ? child : bfsConstruct(child); })));
    };
    parser.write(source);
    parser.end();
    return _.map(root.children, function(child) {
        return bfsConstruct(child);
    });
};

var JSXRender = React.createClass({
    displayName: "JSXRender",
    propTypes: {
        env: React.PropTypes.object,
        code: React.PropTypes.string.isRequired,
    },
    shouldComponentUpdate: function shouldComponentUpdate(nextProps) {
        return !(_.isEqual(this.props.env, nextProps.env) && (this.props.code === nextProps.code));
    },
    render: function render() {
        var env = this.props.env || {};
        var code = this.props.code;
        try {
            return ReactDOM.div.apply(null, [{ className: "JSXRender" }].concat(parseJSX(code, env)));
        }
        catch(e) {
            return ReactDOM.div({ className: "JSXRender JSXRender-error" }, "Error: ", e.toString());
        }
    },
});

module.exports = JSXRender;
<commit_msg>cleanup unuseds<commit_after>// code from jsx-render package by elie rotenberg
// not using the package as it references an old version of react
// and updating it to convert some HTML attributes to DOM, do some housekeeping

var _ = require("lodash");
var htmlparser = require("htmlparser2");
var React = require("react");
var ReactDOM = React.DOM;

var parseJSX = function parseJSX(source, env) {
    env = _.extend({}, React.DOM, env);
    var root = {
        parent: null,
        children: []
    };
    var curr = root;
    var parser = new htmlparser.Parser({
        onopentag: function onopentag(tagName, attribs) {
            attribs = attribs || {};
            curr = {
                parent: curr,
                children: [],
                tagName: tagName,
                attribs: attribs,
            };

            // remove dodgy/breaking attribs
            ['style','width','height'].forEach(function(attr){
                delete attribs[attr];
            });

            // convert html class attribute into DOM attribute
            if (attribs.class) {
                attribs.className = attribs.class;
                delete attribs.class;
            }

        },
        onclosetag: function onclosetag(/* tagName */) {
            curr.parent.children.push(curr);
            curr = curr.parent;
        },
        ontext: function ontext(text) {
            curr.children.push(text);
        },
    }, {
        xmlMode: true,
    });
    var bfsConstruct = function bfsConstruct(curr) {
        if(!_.has(env, curr.tagName)) {
            throw new Error("Unknown tag " + curr.tagName);
        }
        else if(env[curr.tagName] === null) {
            throw new Error("Forbidden tag " + curr.tagName);
        }
        return env[curr.tagName].apply(null, [curr.attribs].concat(_.map(curr.children, function(child) { return _.isString(child) ? child : bfsConstruct(child); })));
    };
    parser.write(source);
    parser.end();
    return _.map(root.children, function(child) {
        return bfsConstruct(child);
    });
};

var JSXRender = React.createClass({
    displayName: "JSXRender",
    propTypes: {
        env: React.PropTypes.object,
        code: React.PropTypes.string.isRequired,
    },
    shouldComponentUpdate: function shouldComponentUpdate(nextProps) {
        return !(_.isEqual(this.props.env, nextProps.env) && (this.props.code === nextProps.code));
    },
    render: function render() {
        var env = this.props.env || {};
        var code = this.props.code;
        try {
            return ReactDOM.div.apply(null, [{ className: "JSXRender" }].concat(parseJSX(code, env)));
        }
        catch(e) {
            return ReactDOM.div({ className: "JSXRender JSXRender-error" }, "Error: ", e.toString());
        }
    },
});

module.exports = JSXRender;
<|endoftext|>


<commit_before>/*globals define: false, console: false */
define(['underscore', 'immutable', 'defer'], function(_, immutable, defer) {
	'use strict';

	var slice = Array.prototype.slice;

	_.mixin({defer: defer}); // override underscore defer
	_.mixin(immutable);       // add immutable methods

	function fmap(m, fn) {
		var x = {};
		_.each(m, function (v, k) { x[k] = fn(v, k); });
		return x;
	}

	// Return function that takes an array
	function apply(fn, self) {
		return fn.apply.bind(fn, self);
	}

	// Create array from arguments
	function array() {
		return _.toArray(arguments);
	}

	// Concat array with following arguments
	function concat(arr) {
		return arr.concat(slice.call(arguments, 1));
	}

	function pluckPaths(paths, obj) {
		return _.fmap(paths, _.partial(_.get_in, obj));
	}

	function pluckPathsArray(paths, obj) {
		return _.map(paths, _.partial(_.get_in, obj));
	}

	function partition_n(arr, n, step, pad) {
		var i, last, len, ret = [];

		step = step || n;
		for (i = 0; i < arr.length; i += step) {
			ret.push(arr.slice(i, i + n));
		}

		last = ret[ret.length - 1];
		if (last) {
			len = last.length;
			if (pad && len < n) {
				ret[ret.length - 1] = last.concat(pad.slice(0, n - len));
			}
		}
		return ret;
	}

	function object_fn(keys, fn) {
		return _.reduce(keys, function (acc, k) {
			acc[k] = fn(k);
			return acc;
		}, {});
	}

	/* Like _.find, but return the result of the predicate */
	function findValue(obj, predicate, context) {
		var result;
		_.any(obj, function (value, index, list) {
			result = predicate.call(context, value, index, list);
			return result;
		});
		return result;
	}

	// XXX Drop this when upgrading underscore
	function negate(predicate) {
		return function () {
			return !predicate.apply(this, slice.call(arguments, 0));
		};
	}

	function spy(msg, x) {
        if (console) {
            console.log(msg, x);
        }
		return x;
	}

	// Find max using a cmp function. Same as arr.slice[0].sort(cmp)[0],
	// but O(n) instead of O(n log n).
	function maxWith(arr, cmp) {
		return _.reduce(arr, function (x,y) {
			return cmp(x, y) < 0 ? x : y;
		});
	}

	_.mixin({
		fmap: fmap,
		apply: apply,
		pluckPaths: pluckPaths,
		pluckPathsArray: pluckPathsArray,
		array: array,
		concat: concat,
		partition_n: partition_n,
		object_fn: object_fn,
		findValue: findValue,
		negate: negate,
		spy: spy,
		flatmap: _.compose(_.partial(_.flatten, _, 1), _.map),
		maxWith: maxWith
	});

	return _;
});
<commit_msg>Add immutable object merge method.<commit_after>/*globals define: false, console: false */
define(['underscore', 'immutable', 'defer'], function(_, immutable, defer) {
	'use strict';

	var slice = Array.prototype.slice;

	_.mixin({defer: defer}); // override underscore defer
	_.mixin(immutable);       // add immutable methods

	function fmap(m, fn) {
		var x = {};
		_.each(m, function (v, k) { x[k] = fn(v, k); });
		return x;
	}

	// Return function that takes an array
	function apply(fn, self) {
		return fn.apply.bind(fn, self);
	}

	// Create array from arguments
	function array() {
		return _.toArray(arguments);
	}

	// Concat array with following arguments
	function concat(arr) {
		return arr.concat(slice.call(arguments, 1));
	}

	function pluckPaths(paths, obj) {
		return _.fmap(paths, _.partial(_.get_in, obj));
	}

	function pluckPathsArray(paths, obj) {
		return _.map(paths, _.partial(_.get_in, obj));
	}

	function partition_n(arr, n, step, pad) {
		var i, last, len, ret = [];

		step = step || n;
		for (i = 0; i < arr.length; i += step) {
			ret.push(arr.slice(i, i + n));
		}

		last = ret[ret.length - 1];
		if (last) {
			len = last.length;
			if (pad && len < n) {
				ret[ret.length - 1] = last.concat(pad.slice(0, n - len));
			}
		}
		return ret;
	}

	function object_fn(keys, fn) {
		return _.reduce(keys, function (acc, k) {
			acc[k] = fn(k);
			return acc;
		}, {});
	}

	/* Like _.find, but return the result of the predicate */
	function findValue(obj, predicate, context) {
		var result;
		_.any(obj, function (value, index, list) {
			result = predicate.call(context, value, index, list);
			return result;
		});
		return result;
	}

	// XXX Drop this when upgrading underscore
	function negate(predicate) {
		return function () {
			return !predicate.apply(this, slice.call(arguments, 0));
		};
	}

	function spy(msg, x) {
        if (console) {
            console.log(msg, x);
        }
		return x;
	}

	// Find max using a cmp function. Same as arr.slice[0].sort(cmp)[0],
	// but O(n) instead of O(n log n).
	function maxWith(arr, cmp) {
		return _.reduce(arr, function (x,y) {
			return cmp(x, y) < 0 ? x : y;
		});
	}

	function merge(...objs) {
		return _.extend.apply(null, [{}].concat(objs));
	}

	_.mixin({
		fmap: fmap,
		merge: merge,
		apply: apply,
		pluckPaths: pluckPaths,
		pluckPathsArray: pluckPathsArray,
		array: array,
		concat: concat,
		partition_n: partition_n,
		object_fn: object_fn,
		findValue: findValue,
		negate: negate,
		spy: spy,
		flatmap: _.compose(_.partial(_.flatten, _, 1), _.map),
		maxWith: maxWith
	});

	return _;
});
<|endoftext|>


<commit_before>/**
* _Internal Class_, not generally used outside of the engine's internals.
*
* @class SAT
*/

// TODO: true circles and curves

var SAT = {};

(function() {

    /**
     * Description
     * @method collides
     * @param {body} bodyA
     * @param {body} bodyB
     * @param {collision} previousCollision
     * @return {collision} collision
     */
    SAT.collides = function(bodyA, bodyB, previousCollision) {
        var overlapAB,
            overlapBA,
            minOverlap,
            collision,
            prevCol = previousCollision,
            canReusePrevCol = false;

        if (prevCol) {
            // estimate total motion
            var parentA = bodyA.parent,
                parentB = bodyB.parent,
                motion = parentA.speed * parentA.speed + parentA.angularSpeed * parentA.angularSpeed
                       + parentB.speed * parentB.speed + parentB.angularSpeed * parentB.angularSpeed;

            // we may be able to (partially) reuse collision result
            // but only safe if collision was resting
            canReusePrevCol = prevCol && prevCol.collided && motion < 0.2;

            // reuse collision object
            collision = prevCol;
        } else {
            collision = { collided: false, bodyA: bodyA, bodyB: bodyB };
        }

        if (prevCol && canReusePrevCol) {
            // if we can reuse the collision result
            // we only need to test the previously found axis
            var axes = [prevCol.bodyA.axes[prevCol.axisNumber]];

            minOverlap = _overlapAxes(prevCol.bodyA.vertices, prevCol.bodyB.vertices, axes);
            collision.reused = true;

            if (minOverlap.overlap <= 0) {
                collision.collided = false;
                return collision;
            }
        } else {
            // if we can't reuse a result, perform a full SAT test

            overlapAB = _overlapAxes(bodyA.vertices, bodyB.vertices, bodyA.axes);

            if (overlapAB.overlap <= 0) {
                collision.collided = false;
                return collision;
            }

            overlapBA = _overlapAxes(bodyB.vertices, bodyA.vertices, bodyB.axes);

            if (overlapBA.overlap <= 0) {
                collision.collided = false;
                return collision;
            }

            if (overlapAB.overlap < overlapBA.overlap) {
                minOverlap = overlapAB;
                collision.bodyA = bodyA;
                collision.bodyB = bodyB;
            } else {
                minOverlap = overlapBA;
                collision.bodyA = bodyB;
                collision.bodyB = bodyA;
            }

            // important for reuse later
            collision.axisNumber = minOverlap.axisNumber;
        }

        collision.collided = true;
        collision.normal = minOverlap.axis;
        collision.depth = minOverlap.overlap;
        collision.parentA = collision.bodyA.parent;
        collision.parentB = collision.bodyB.parent;

        bodyA = collision.bodyA;
        bodyB = collision.bodyB;

        // ensure normal is facing away from bodyA
        if (Vector.dot(collision.normal, Vector.sub(bodyB.position, bodyA.position)) > 0)
            collision.normal = Vector.neg(collision.normal);

        collision.tangent = Vector.perp(collision.normal);

        collision.penetration = {
            x: collision.normal.x * collision.depth,
            y: collision.normal.y * collision.depth
        };

        // find support points, there is always either exactly one or two
        var verticesB = _findSupports(bodyA, bodyB, collision.normal),
            supports = collision.supports || [];
        supports.length = 0;

        // find the supports from bodyB that are inside bodyA
        if (Vertices.contains(bodyA.vertices, verticesB[0]))
            supports.push(verticesB[0]);

        if (verticesB[1] && Vertices.contains(bodyA.vertices, verticesB[1]))
            supports.push(verticesB[1]);

        // find the supports from bodyA that are inside bodyB
        if (supports.length < 2) {
            var verticesA = _findSupports(bodyB, bodyA, Vector.neg(collision.normal));

            if (Vertices.contains(bodyB.vertices, verticesA[0]))
                supports.push(verticesA[0]);

            if (verticesA[1] && supports.length < 2 && Vertices.contains(bodyB.vertices, verticesA[1]))
                supports.push(verticesA[1]);
        }

        // account for the edge case of overlapping but no vertex containment
        if (supports.length < 1)
            supports = [verticesB[0]];

        collision.supports = supports;
        collision.supportCorrected = Vector.sub(supports[0], collision.penetration);

        return collision;
    };

    /**
     * Description
     * @method _overlapAxes
     * @private
     * @param {} verticesA
     * @param {} verticesB
     * @param {} axes
     * @return result
     */
    var _overlapAxes = function(verticesA, verticesB, axes) {
        var projectionA = Vector._temp[0],
            projectionB = Vector._temp[1],
            result = { overlap: Number.MAX_VALUE },
            overlap,
            axis;

        for (var i = 0; i < axes.length; i++) {
            axis = axes[i];

            _projectToAxis(projectionA, verticesA, axis);
            _projectToAxis(projectionB, verticesB, axis);

            overlap = Math.min(projectionA.max - projectionB.min, projectionB.max - projectionA.min);

            if (overlap <= 0) {
                result.overlap = overlap;
                return result;
            }

            if (overlap < result.overlap) {
                result.overlap = overlap;
                result.axis = axis;
                result.axisNumber = i;
            }
        }

        return result;
    };

    /**
     * Description
     * @method _projectToAxis
     * @private
     * @param {} projection
     * @param {} vertices
     * @param {} axis
     */
    var _projectToAxis = function(projection, vertices, axis) {
        var min = Vector.dot(vertices[0], axis),
            max = min;

        for (var i = 1; i < vertices.length; i += 1) {
            var dot = Vector.dot(vertices[i], axis);

            if (dot > max) {
                max = dot;
            } else if (dot < min) {
                min = dot;
            }
        }

        projection.min = min;
        projection.max = max;
    };

    /**
     * Description
     * @method _findSupports
     * @private
     * @param {} bodyA
     * @param {} bodyB
     * @param {} normal
     * @return ArrayExpression
     */
    var _findSupports = function(bodyA, bodyB, normal) {
        var nearestDistance = Number.MAX_VALUE,
            vertexToBody = Vector._temp[0],
            vertices = bodyB.vertices,
            bodyAPosition = bodyA.position,
            distance,
            vertex,
            vertexA,
            vertexB;

        // find closest vertex on bodyB
        for (var i = 0; i < vertices.length; i++) {
            vertex = vertices[i];
            vertexToBody.x = vertex.x - bodyAPosition.x;
            vertexToBody.y = vertex.y - bodyAPosition.y;
            distance = -Vector.dot(normal, vertexToBody);

            if (distance < nearestDistance) {
                nearestDistance = distance;
                vertexA = vertex;
            }
        }

        // find next closest vertex using the two connected to it
        var prevIndex = vertexA.index - 1 >= 0 ? vertexA.index - 1 : vertices.length - 1;
        vertex = vertices[prevIndex];
        vertexToBody.x = vertex.x - bodyAPosition.x;
        vertexToBody.y = vertex.y - bodyAPosition.y;
        nearestDistance = -Vector.dot(normal, vertexToBody);
        vertexB = vertex;

        // if the closest vertex is internal, we can't use the next connected vertex
        if (!vertexA.isInternal) {
            var nextIndex = (vertexA.index + 1) % vertices.length;
            vertex = vertices[nextIndex];
            vertexToBody.x = vertex.x - bodyAPosition.x;
            vertexToBody.y = vertex.y - bodyAPosition.y;
            distance = -Vector.dot(normal, vertexToBody);
            if (distance < nearestDistance) {
                vertexB = vertex;
            }
        }

        if (!vertexB)
            return [vertexA];

        return [vertexA, vertexB];
    };

})();
<commit_msg>fixed collision incident and reference body mapping<commit_after>/**
* _Internal Class_, not generally used outside of the engine's internals.
*
* @class SAT
*/

// TODO: true circles and curves

var SAT = {};

(function() {

    /**
     * Description
     * @method collides
     * @param {body} bodyA
     * @param {body} bodyB
     * @param {collision} previousCollision
     * @return {collision} collision
     */
    SAT.collides = function(bodyA, bodyB, previousCollision) {
        var overlapAB,
            overlapBA,
            minOverlap,
            collision,
            prevCol = previousCollision,
            canReusePrevCol = false;

        if (prevCol) {
            // estimate total motion
            var parentA = bodyA.parent,
                parentB = bodyB.parent,
                motion = parentA.speed * parentA.speed + parentA.angularSpeed * parentA.angularSpeed
                       + parentB.speed * parentB.speed + parentB.angularSpeed * parentB.angularSpeed;

            // we may be able to (partially) reuse collision result
            // but only safe if collision was resting
            canReusePrevCol = prevCol && prevCol.collided && motion < 0.2;

            // reuse collision object
            collision = prevCol;
        } else {
            collision = { collided: false, bodyA: bodyA, bodyB: bodyB };
        }

        if (prevCol && canReusePrevCol) {
            // if we can reuse the collision result
            // we only need to test the previously found axis
            var axisBodyA = collision.axisBody,
                axisBodyB = axisBodyA === bodyA ? bodyB : bodyA,
                axes = [axisBodyA.axes[prevCol.axisNumber]];

            minOverlap = _overlapAxes(axisBodyA.vertices, axisBodyB.vertices, axes);
            collision.reused = true;

            if (minOverlap.overlap <= 0) {
                collision.collided = false;
                return collision;
            }
        } else {
            // if we can't reuse a result, perform a full SAT test

            overlapAB = _overlapAxes(bodyA.vertices, bodyB.vertices, bodyA.axes);

            if (overlapAB.overlap <= 0) {
                collision.collided = false;
                return collision;
            }

            overlapBA = _overlapAxes(bodyB.vertices, bodyA.vertices, bodyB.axes);

            if (overlapBA.overlap <= 0) {
                collision.collided = false;
                return collision;
            }

            if (overlapAB.overlap < overlapBA.overlap) {
                minOverlap = overlapAB;
                collision.axisBody = bodyA;
            } else {
                minOverlap = overlapBA;
                collision.axisBody = bodyB;
            }

            // important for reuse later
            collision.axisNumber = minOverlap.axisNumber;
        }

        collision.bodyA = bodyA.id < bodyB.id ? bodyA : bodyB;
        collision.bodyB = bodyA.id < bodyB.id ? bodyB : bodyA;
        collision.collided = true;
        collision.normal = minOverlap.axis;
        collision.depth = minOverlap.overlap;
        collision.parentA = collision.bodyA.parent;
        collision.parentB = collision.bodyB.parent;

        bodyA = collision.bodyA;
        bodyB = collision.bodyB;

        // ensure normal is facing away from bodyA
        if (Vector.dot(collision.normal, Vector.sub(bodyB.position, bodyA.position)) > 0)
            collision.normal = Vector.neg(collision.normal);

        collision.tangent = Vector.perp(collision.normal);

        collision.penetration = {
            x: collision.normal.x * collision.depth,
            y: collision.normal.y * collision.depth
        };

        // find support points, there is always either exactly one or two
        var verticesB = _findSupports(bodyA, bodyB, collision.normal),
            supports = collision.supports || [];
        supports.length = 0;

        // find the supports from bodyB that are inside bodyA
        if (Vertices.contains(bodyA.vertices, verticesB[0]))
            supports.push(verticesB[0]);

        if (verticesB[1] && Vertices.contains(bodyA.vertices, verticesB[1]))
            supports.push(verticesB[1]);

        // find the supports from bodyA that are inside bodyB
        if (supports.length < 2) {
            var verticesA = _findSupports(bodyB, bodyA, Vector.neg(collision.normal));

            if (Vertices.contains(bodyB.vertices, verticesA[0]))
                supports.push(verticesA[0]);

            if (verticesA[1] && supports.length < 2 && Vertices.contains(bodyB.vertices, verticesA[1]))
                supports.push(verticesA[1]);
        }

        // account for the edge case of overlapping but no vertex containment
        if (supports.length < 1)
            supports = [verticesB[0]];

        collision.supports = supports;
        collision.supportCorrected = Vector.sub(supports[0], collision.penetration);

        return collision;
    };

    /**
     * Description
     * @method _overlapAxes
     * @private
     * @param {} verticesA
     * @param {} verticesB
     * @param {} axes
     * @return result
     */
    var _overlapAxes = function(verticesA, verticesB, axes) {
        var projectionA = Vector._temp[0],
            projectionB = Vector._temp[1],
            result = { overlap: Number.MAX_VALUE },
            overlap,
            axis;

        for (var i = 0; i < axes.length; i++) {
            axis = axes[i];

            _projectToAxis(projectionA, verticesA, axis);
            _projectToAxis(projectionB, verticesB, axis);

            overlap = Math.min(projectionA.max - projectionB.min, projectionB.max - projectionA.min);

            if (overlap <= 0) {
                result.overlap = overlap;
                return result;
            }

            if (overlap < result.overlap) {
                result.overlap = overlap;
                result.axis = axis;
                result.axisNumber = i;
            }
        }

        return result;
    };

    /**
     * Description
     * @method _projectToAxis
     * @private
     * @param {} projection
     * @param {} vertices
     * @param {} axis
     */
    var _projectToAxis = function(projection, vertices, axis) {
        var min = Vector.dot(vertices[0], axis),
            max = min;

        for (var i = 1; i < vertices.length; i += 1) {
            var dot = Vector.dot(vertices[i], axis);

            if (dot > max) {
                max = dot;
            } else if (dot < min) {
                min = dot;
            }
        }

        projection.min = min;
        projection.max = max;
    };

    /**
     * Description
     * @method _findSupports
     * @private
     * @param {} bodyA
     * @param {} bodyB
     * @param {} normal
     * @return ArrayExpression
     */
    var _findSupports = function(bodyA, bodyB, normal) {
        var nearestDistance = Number.MAX_VALUE,
            vertexToBody = Vector._temp[0],
            vertices = bodyB.vertices,
            bodyAPosition = bodyA.position,
            distance,
            vertex,
            vertexA,
            vertexB;

        // find closest vertex on bodyB
        for (var i = 0; i < vertices.length; i++) {
            vertex = vertices[i];
            vertexToBody.x = vertex.x - bodyAPosition.x;
            vertexToBody.y = vertex.y - bodyAPosition.y;
            distance = -Vector.dot(normal, vertexToBody);

            if (distance < nearestDistance) {
                nearestDistance = distance;
                vertexA = vertex;
            }
        }

        // find next closest vertex using the two connected to it
        var prevIndex = vertexA.index - 1 >= 0 ? vertexA.index - 1 : vertices.length - 1;
        vertex = vertices[prevIndex];
        vertexToBody.x = vertex.x - bodyAPosition.x;
        vertexToBody.y = vertex.y - bodyAPosition.y;
        nearestDistance = -Vector.dot(normal, vertexToBody);
        vertexB = vertex;

        // if the closest vertex is internal, we can't use the next connected vertex
        if (!vertexA.isInternal) {
            var nextIndex = (vertexA.index + 1) % vertices.length;
            vertex = vertices[nextIndex];
            vertexToBody.x = vertex.x - bodyAPosition.x;
            vertexToBody.y = vertex.y - bodyAPosition.y;
            distance = -Vector.dot(normal, vertexToBody);
            if (distance < nearestDistance) {
                vertexB = vertex;
            }
        }

        if (!vertexB)
            return [vertexA];

        return [vertexA, vertexB];
    };

})();
<|endoftext|>


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

angular.module('app', ['ngRoute', 'ui.bootstrap', 'angularMoment', 'firebase', 'hgDefer', 'hgUnique'])

.config(function ($routeProvider) {
  $routeProvider
    .when('/login', {
      templateUrl: 'login.html',
      controller: 'loginController',
    })
    .when('/names', {
      templateUrl: 'names.html',
      controller: 'MainController',
      controllerAs: 'main',
      resolve: {
        submissions: function ($firebase, submissionFirebaseReference, defer, user, $location, upgrade) {
          return defer(function (promise) {
            if (!user.loggedIn) {
              promise.reject();
              $location.path('/login');
            } else {
              var submissions = $firebase(submissionFirebaseReference);
              submissions.$on('loaded', function () {
                upgrade(submissions);
                submissions.$save();
                promise.resolve(submissions);
              });
            }
          });
        },
      },
    })
    .otherwise({
      redirectTo: '/names',
    });
})

.run(function (amMoment, $rootScope, user) {
  amMoment.changeLanguage('fr');
  $rootScope.user = user;
})

.factory('upgrade', function (user) {
  return function (data) {
    _.each(data.$getIndex(), function (key, index) {
      var item = data[key];
      if (item.version === undefined) {
        item.version = 1;
      }
      if (item.version === 1) {
        delete item.ratings;
        item.version = 2;
      }
      if (item.version >= 2) {
        if (angular.isUndefined(item.ranking)) {
          item.ranking = {};
        }
      }
    });
  };
})

.controller('loginController', function ($scope, $location, authentication, user) {
  var onLoginSucess = function (thirdPartyUser) {
    user.set(thirdPartyUser);
    $location.path('/names');
  };

  $scope.busy = true;
  $scope.autoLoginInProgress = true;
  authentication.autoLogin().then(function (user) {
    onLoginSucess(user);
  }).catch(function () {
    $scope.autoLoginFailed = true;
    $scope.busy = false;
  });

  $scope.login = function (provider) {
    $scope.busy = true;
    authentication.manualLogin(provider).then(function (user) {
      $scope.autoLoginInProgress = false;
      $scope.autoLoginFailed = false;
      $scope.manuallyLoggedIn = true;
      onLoginSucess(user);
    }).catch(function (error) {
      $scope.busy = false;
      $scope.error = error;
    });
  };
})

.factory('authentication', function ($firebaseSimpleLogin, submissionFirebaseReference, $rootScope, defer) {
  var firebaseSimpleLogin = $firebaseSimpleLogin(submissionFirebaseReference);
  return {
    autoLogin: function () {
      return defer(function (promise) {
        var unsubscribeFromLoginEvent = $rootScope.$on('$firebaseSimpleLogin:login', function(event, user) {
          unsubscribeFromLoginEvent();
          unsubscribeFromLogoutEvent();
          promise.resolve(user);
        });
        var unsubscribeFromLogoutEvent = $rootScope.$on('$firebaseSimpleLogin:logout', function(event) {
          unsubscribeFromLoginEvent();
          unsubscribeFromLogoutEvent();
          promise.reject();
        });
      });
    },
    manualLogin: function (provider) {
      return firebaseSimpleLogin.$login(provider);
    },
  };
})

.factory('user', function () {
  var user;
  return {
    loggedIn: false,
    set: function (thirdPartyUser) {
      user = thirdPartyUser;
      this.name = user.thirdPartyUserData.given_name;
      this.loggedIn = true;
    },
  }
})

.factory('submissionFirebaseReference', function ($location, $interpolate) {
  var url = 'boiling-fire-3739.firebaseIO.com/apps/names/{{env}}/submissions';
  if ($location.host().match(/localhost|127\.0\.0\.1|192\.168\./)) {
    return new Firebase($interpolate(url)({env: 'dev'}));
  } else {
    return new Firebase($interpolate(url)({env: 'prod'}));
  }
})

.controller('NameSubmissionFormController', function (submissionFirebaseReference, user, $firebase) {
  var that = this;

  var fb = $firebase(submissionFirebaseReference);

  that.submission = '';

  that.submit = function (name) {
    var submission = {
      name: name,
      submitter: user.name,
      time: new Date(),
      ranking: {},
      version: 3,
    };
    submission.ranking[user.name] = fb.$getIndex().length;
    fb.$add(submission);
    that.name = '';
    that.form.$setPristine();
  };
})

.filter('orderUsing', function () {
  return function (input, ordering) {
    return ordering.apply(input);
  };
})

.controller('MainController', function (submissions, Ordering) {
  var that = this;
  that.names = submissions;
  that.ranking = Ordering.for(submissions.$getIndex());
})

.controller('SubmissionItemController', function ($scope, user) {
  var that = this;
})

.factory('Ordering', function () {
  function Ordering(orderMap) {
    var that = this;
    that.up = function (index) {
      if (index <= 0 || index > orderMap.length - 1) return;
      var pulled = orderMap[index];
      var pushed = orderMap[index - 1];
      orderMap[index] = pushed;
      orderMap[index - 1] = pulled;
      return that;
    };
    that.down = function (index) {
      return that.up(index + 1)
    };
    that.apply = function (array) {
      if (array.length !== orderMap.length)
        throw 'Cannot apply an ordering of length ' + orderMap.length + ' on an array of length ' + array.length + '!';
      return _.map(orderMap, function (index) {
        return array[index];
      });
    };
  }
  Ordering.ofLength = function (length) {
    return new Ordering(_.range(length));
  };
  Ordering.for = function (array) {
    return Ordering.ofLength(array.length);
  }
  return Ordering;
})

}())
<commit_msg>refactor(ranking): ordering loaded from firebase<commit_after>(function () { 'use strict';

angular.module('app', ['ngRoute', 'ui.bootstrap', 'angularMoment', 'firebase', 'hgDefer', 'hgUnique'])

.config(function ($routeProvider) {
  $routeProvider
    .when('/login', {
      templateUrl: 'login.html',
      controller: 'loginController',
    })
    .when('/names', {
      templateUrl: 'names.html',
      controller: 'MainController',
      controllerAs: 'main',
      resolve: {
        submissions: function ($firebase, submissionFirebaseReference, defer, user, $location, upgrade) {
          return defer(function (promise) {
            if (!user.loggedIn) {
              promise.reject();
              $location.path('/login');
            } else {
              var submissions = $firebase(submissionFirebaseReference);
              submissions.$on('loaded', function () {
                upgrade(submissions);
                submissions.$save();
                promise.resolve(submissions);
              });
            }
          });
        },
        ranking: function ($firebase, rankingFirebaseReference, defer, user) {
          return defer(function (promise) {
            var rankings = $firebase(rankingFirebaseReference);
            rankings.$on('loaded', function () {
              promise.resolve(rankings[user.name]);
            });
          });
        },
      },
    })
    .otherwise({
      redirectTo: '/names',
    });
})

.run(function (amMoment, $rootScope, user) {
  amMoment.changeLanguage('fr');
  $rootScope.user = user;
})

.factory('upgrade', function (user) {
  return function (data) {
    _.each(data.$getIndex(), function (key, index) {
      var item = data[key];
      if (item.version === undefined) {
        item.version = 1;
      }
      if (item.version === 1) {
        delete item.ratings;
        item.version = 2;
      }
      if (item.version >= 2) {
        if (angular.isUndefined(item.ranking)) {
          item.ranking = {};
        }
      }
    });
  };
})

.controller('loginController', function ($scope, $location, authentication, user) {
  var onLoginSucess = function (thirdPartyUser) {
    user.set(thirdPartyUser);
    $location.path('/names');
  };

  $scope.busy = true;
  $scope.autoLoginInProgress = true;
  authentication.autoLogin().then(function (user) {
    onLoginSucess(user);
  }).catch(function () {
    $scope.autoLoginFailed = true;
    $scope.busy = false;
  });

  $scope.login = function (provider) {
    $scope.busy = true;
    authentication.manualLogin(provider).then(function (user) {
      $scope.autoLoginInProgress = false;
      $scope.autoLoginFailed = false;
      $scope.manuallyLoggedIn = true;
      onLoginSucess(user);
    }).catch(function (error) {
      $scope.busy = false;
      $scope.error = error;
    });
  };
})

.factory('authentication', function ($firebaseSimpleLogin, submissionFirebaseReference, $rootScope, defer) {
  var firebaseSimpleLogin = $firebaseSimpleLogin(submissionFirebaseReference);
  return {
    autoLogin: function () {
      return defer(function (promise) {
        var unsubscribeFromLoginEvent = $rootScope.$on('$firebaseSimpleLogin:login', function(event, user) {
          unsubscribeFromLoginEvent();
          unsubscribeFromLogoutEvent();
          promise.resolve(user);
        });
        var unsubscribeFromLogoutEvent = $rootScope.$on('$firebaseSimpleLogin:logout', function(event) {
          unsubscribeFromLoginEvent();
          unsubscribeFromLogoutEvent();
          promise.reject();
        });
      });
    },
    manualLogin: function (provider) {
      return firebaseSimpleLogin.$login(provider);
    },
  };
})

.factory('user', function () {
  var user;
  return {
    loggedIn: false,
    set: function (thirdPartyUser) {
      user = thirdPartyUser;
      this.name = user.thirdPartyUserData.given_name;
      this.loggedIn = true;
    },
  }
})

.factory('submissionFirebaseReference', function ($location, $interpolate) {
  var url = 'boiling-fire-3739.firebaseIO.com/apps/names/{{env}}/submissions';
  if ($location.host().match(/localhost|127\.0\.0\.1|192\.168\./)) {
    return new Firebase($interpolate(url)({env: 'dev'}));
  } else {
    return new Firebase($interpolate(url)({env: 'prod'}));
  }
})

.factory('rankingFirebaseReference', function ($location, $interpolate) {
  var url = 'boiling-fire-3739.firebaseIO.com/apps/names/{{env}}/rankings';
  if ($location.host().match(/localhost|127\.0\.0\.1|192\.168\./)) {
    return new Firebase($interpolate(url)({env: 'dev'}));
  } else {
    return new Firebase($interpolate(url)({env: 'prod'}));
  }
})

.controller('NameSubmissionFormController', function (submissionFirebaseReference, user, $firebase) {
  var that = this;

  var fb = $firebase(submissionFirebaseReference);

  that.submission = '';

  that.submit = function (name) {
    var submission = {
      name: name,
      submitter: user.name,
      time: new Date(),
      ranking: {},
      version: 3,
    };
    submission.ranking[user.name] = fb.$getIndex().length;
    fb.$add(submission);
    that.name = '';
    that.form.$setPristine();
  };
})

.filter('orderUsing', function () {
  return function (input, ordering) {
    return ordering.apply(input);
  };
})

.controller('MainController', function (submissions, ranking, Ordering) {
  var that = this;
  that.names = submissions;
  that.ranking = new Ordering(ranking ? ranking : _.range(submissions.$getIndex().length));
})

.controller('SubmissionItemController', function ($scope, user) {
  var that = this;
})

.factory('Ordering', function () {
  function Ordering(orderMap) {
    var that = this;
    that.up = function (index) {
      if (index <= 0 || index > orderMap.length - 1) return;
      var pulled = orderMap[index];
      var pushed = orderMap[index - 1];
      orderMap[index] = pushed;
      orderMap[index - 1] = pulled;
      return that;
    };
    that.down = function (index) {
      return that.up(index + 1)
    };
    that.apply = function (array) {
      if (array.length !== orderMap.length)
        throw 'Cannot apply an ordering of length ' + orderMap.length + ' on an array of length ' + array.length + '!';
      return _.map(orderMap, function (index) {
        return array[index];
      });
    };
  }
  Ordering.ofLength = function (length) {
    return new Ordering(_.range(length));
  };
  Ordering.for = function (array) {
    return Ordering.ofLength(array.length);
  }
  return Ordering;
})

}())
<|endoftext|>