Fix broken .closest check for double mpu

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/lonelyplanet/rizzo.git/'


misc typo fix in logs

misc typo fix in logs

--- server/models/mailbox.coffee
+++ server/models/mailbox.coffee
@@ -503,7 +503,7 @@
     #
     # Returns (callback) at completion
     applyFlagsChanges: (flagsChange, reporter, callback) ->
-        log.debug "applyFlagsChange", flagsChange.length
+        log.debug "applyFlagsChanges", flagsChange.length
         async.eachSeries flagsChange, (change, cb) ->
             Message.applyFlagsChanges change.id, change.flags, (err) ->
                 reporter.onError err if err


Refactored simulator, removed duplication bug

This merge is going to be terrible

--- server/queues/scoring.coffee
+++ server/queues/scoring.coffee
@@ -43,17 +43,17 @@

 addPairwiseTaskToQueue = (taskPair, cb) ->
   LevelSession.findOne(_id:taskPair[0]).lean().exec (err, firstSession) =>
-    if err? then return cb err, false
+    if err? then return cb err
     LevelSession.find(_id:taskPair[1]).exec (err, secondSession) =>
-      if err? then return cb err, false
+      if err? then return cb err
       try
         taskPairs = generateTaskPairs(secondSession, firstSession)
       catch e
-        if e then return cb e, false
+        if e then return cb e

       sendEachTaskPairToTheQueue taskPairs, (taskPairError) ->
-        if taskPairError? then return cb taskPairError,false
-        cb null, true
+        if taskPairError? then return cb taskPairError
+        cb null

 module.exports.resimulateAllSessions = (req, res) ->
   unless isUserAdmin req then return errors.unauthorized res, "Unauthorized. Even if you are authorized, you shouldn't do this"
@@ -68,8 +68,8 @@
       majorVersion: levelMajorVersion

   query = LevelSession
-    .find(findParameters)
-    .lean()
+  .find(findParameters)
+  .lean()

   query.exec (err, result) ->
     if err? then return errors.serverError res, err
@@ -107,7 +107,7 @@
   originalLevelID = req.body.originalLevelID
   currentLevelID = req.body.levelID
   requestLevelMajorVersion = parseInt(req.body.levelMajorVersion)
-
+
   async.waterfall [
     validatePermissions.bind(@,req,requestSessionID)
     fetchAndVerifyLevelType.bind(@,currentLevelID)
@@ -115,12 +115,12 @@
     updateSessionToSubmit
     fetchInitialSessionsToRankAgainst.bind(@, requestLevelMajorVersion, originalLevelID)
     generateAndSendTaskPairsToTheQueue
-
+
   ], (err, successMessageObject) ->
     if err? then return errors.serverError res, "There was an error submitting the game to the queue:#{err}"
     sendResponseObject req, res, successMessageObject

-
+
 validatePermissions = (req,sessionID, callback) ->
   if isUserAnonymous req then return callback "You are unauthorized to submit that game to the simulator"
   if isUserAdmin req then return callback null
@@ -136,7 +136,7 @@
   query.exec (err, retrievedSession) ->
     if err? then return callback err
     userHasPermissionToSubmitCode = retrievedSession.creator is req.user?.id and
-    not _.isEqual(retrievedSession.code, retrievedSession.submittedCode)
+      not _.isEqual(retrievedSession.code, retrievedSession.submittedCode)
     unless userHasPermissionToSubmitCode then return callback "You are unauthorized to submit that game to the simulator"
     callback null

@@ -209,7 +209,7 @@
   sendEachTaskPairToTheQueue taskPairs, (taskPairError) ->
     if taskPairError? then return callback taskPairError
     callback null, {"message": "All task pairs were succesfully sent to the queue"}
-
+

 module.exports.dispatchTaskToConsumer = (req, res) ->
   async.waterfall [
@@ -221,7 +221,7 @@
     constructTaskLogObject.bind(@, getUserIDFromRequest(req))
     processTaskObject
   ], (err, taskObjectToSend) ->
-    if err?
+    if err?
       if typeof err is "string" and err.indexOf "No more games in the queue" isnt -1
         res.send(204, "No games to score.")
         return res.end()
@@ -229,16 +229,16 @@
         return errors.serverError res, "There was an error dispatching the task: #{err}"
     sendResponseObject req, res, taskObjectToSend

-
-
+
+
 checkSimulationPermissions = (req, cb) ->
-  if isUserAnonymous req
+  if isUserAnonymous req
     cb "You need to be logged in to simulate games"
   else
     cb null
-
+
 receiveMessageFromSimulationQueue = (cb) ->
-  scoringTaskQueue.receiveMessage (err, message) ->
+  scoringTaskQueue.receiveMessage (err, message) ->
     if err? then return cb "No more games in the queue, error:#{err}"
     if messageIsInvalid(message) then return cb "Message received from queue is invalid"
     cb null, message
@@ -292,19 +292,19 @@
   cb null, taskObject

 getSessionInformation = (sessionIDString, callback) ->
-  findParameters =
+  findParameters =
     _id: sessionIDString
   selectString = 'submitDate team submittedCode teamSpells levelID creator creatorName'
   query = LevelSession
-    .findOne(findParameters)
-    .select(selectString)
-    .lean()
-
+  .findOne(findParameters)
+  .select(selectString)
+  .lean()
+
   query.exec (err, session) ->
     if err? then return callback err, {"error":"There was an error retrieving the session."}
     callback null, session

-
+###
 module.exports.processTaskResult = (req, res) ->
   clientResponseObject = verifyClientResponse req.body, res

@@ -373,9 +373,178 @@
                   LevelSession.update {_id: originalSessionID}, {isRanking: false}, {multi: false}, (err, affected) ->
                     if err? then return errors.serverError res, "There was an error marking the completed session as not being ranked."
                     sendResponseObject req, res, {"message":"The scores were updated successfully, person lost so no more games are being inserted!"}
-
-
-determineIfSessionShouldContinueAndUpdateLog = (sessionID, sessionRank, cb) ->
+###
+module.exports.processTaskResult = (req, res) ->
+  async.waterfall [
+    verifyClientResponse.bind(@,req.body)
+    fetchTaskLog.bind(@)
+    checkTaskLog.bind(@)
+    deleteQueueMessage.bind(@)
+    fetchLevelSession.bind(@)
+    checkSubmissionDate.bind(@)
+    logTaskComputation.bind(@)
+    updateSessions.bind(@)
+    indexNewScoreArray.bind(@)
+    addMatchToSessions.bind(@)
+    updateUserSimulationCounts.bind(@, req.user._id)
+    determineIfSessionShouldContinueAndUpdateLog.bind(@)
+    findNearestBetterSessionID.bind(@)
+    addNewSessionsToQueue.bind(@)
+  ], (err, results) ->
+    if err is "shouldn't continue"
+      sendResponseObject req, res, {"message":"The scores were updated successfully, person lost so no more games are being inserted!"}
+    else if err is "no session was found"
+      sendResponseObject req, res, {"message":"There were no more games to rank (game is at top)!"}
+    else if err?
+      errors.serverError res, "There was an error:#{err}"
+    else
+      sendResponseObject req, res, {"message":"The scores were updated successfully and more games were sent to the queue!"}
+
+verifyClientResponse = (responseObject, callback) ->
+  #TODO: better verification
+  unless typeof responseObject is "object"
+    callback "The response to that query is required to be a JSON object."
+  else
+    @clientResponseObject = responseObject
+    log.info "Verified client response!"
+    callback null, responseObject
+
+fetchTaskLog = (responseObject, callback) ->
+  findParameters =
+    _id: responseObject.taskID
+  query = TaskLog
+  .findOne(findParameters)
+  query.exec (err, taskLog) =>
+    @taskLog = taskLog
+    log.info "Fetched task log!"
+    callback err, taskLog.toObject()
+
+checkTaskLog = (taskLog, callback) ->
+  if taskLog.calculationTimeMS then return callback "That computational task has already been performed"
+  if hasTaskTimedOut taskLog.sentDate then return callback "The task has timed out"
+  log.info "Checked task log"
+  callback null
+
+deleteQueueMessage = (callback) ->
+  scoringTaskQueue.deleteMessage @clientResponseObject.receiptHandle, (err) ->
+    log.info "Deleted queue message"
+    callback err
+
+fetchLevelSession = (callback) ->
+  findParameters =
+    _id: @clientResponseObject.originalSessionID
+  query = LevelSession
+  .findOne(findParameters)
+  .lean()
+  query.exec (err, session) =>
+    @levelSession = session
+    log.info "Fetched level session"
+    callback err
+
+
+checkSubmissionDate = (callback) ->
+  supposedSubmissionDate = new Date(@clientResponseObject.sessions[0].submitDate)
+  if Number(supposedSubmissionDate) isnt Number(@levelSession.submitDate)
+    callback "The game has been resubmitted. Removing from queue..."
+  else
+    log.info "Checked submission date"
+    callback null
+
+logTaskComputation = (callback) ->
+  @taskLog.set('calculationTimeMS',@clientResponseObject.calculationTimeMS)
+  @taskLog.set('sessions')
+  @taskLog.calculationTimeMS = @clientResponseObject.calculationTimeMS
+  @taskLog.sessions = @clientResponseObject.sessions
+  @taskLog.save (err, saved) ->
+    log.info "Logged task computation"
+    callback err
+
+updateSessions = (callback) ->
+  sessionIDs = _.pluck @clientResponseObject.sessions, 'sessionID'
+
+  async.map sessionIDs, retrieveOldSessionData, (err, oldScores) =>
+    if err? then callback err, {"error": "There was an error retrieving the old scores"}
+
+    oldScoreArray = _.toArray putRankingFromMetricsIntoScoreObject @clientResponseObject, oldScores
+    newScoreArray = bayes.updatePlayerSkills oldScoreArray
+    saveNewScoresToDatabase newScoreArray, callback
+
+
+saveNewScoresToDatabase = (newScoreArray, callback) ->
+  async.eachSeries newScoreArray, updateScoreInSession, (err) ->
+    log.info "Saved new scores to database"
+    callback err,newScoreArray
+
+
+updateScoreInSession = (scoreObject,callback) ->
+  LevelSession.findOne {"_id": scoreObject.id}, (err, session) ->
+    if err? then return callback err, null
+
+    session = session.toObject()
+    newTotalScore = scoreObject.meanStrength - 1.8 * scoreObject.standardDeviation
+    scoreHistoryAddition = [Date.now(), newTotalScore]
+    updateObject =
+      meanStrength: scoreObject.meanStrength
+      standardDeviation: scoreObject.standardDeviation
+      totalScore: newTotalScore
+      $push: {scoreHistory: {$each: [scoreHistoryAddition], $slice: -1000}}
+
+    LevelSession.update {"_id": scoreObject.id}, updateObject, callback
+    log.info "New total score for session #{scoreObject.id} is #{updateObject.totalScore}"
+
+indexNewScoreArray = (newScoreArray, callback) ->
+  newScoresObject = _.indexBy newScoreArray, 'id'
+  @newScoresObject = newScoresObject
+  callback null, newScoresObject
+
+addMatchToSessions = (newScoreObject, callback) ->
+  matchObject = {}
+  matchObject.date = new Date()
+  matchObject.opponents = {}
+  for session in @clientResponseObject.sessions
+    sessionID = session.sessionID
+    matchObject.opponents[sessionID] = {}
+    matchObject.opponents[sessionID].sessionID = sessionID
+    matchObject.opponents[sessionID].userID = session.creator
+    matchObject.opponents[sessionID].metrics = {}
+    matchObject.opponents[sessionID].metrics.rank = Number(newScoreObject[sessionID].gameRanking)
+
+  log.info "Match object computed, result: #{matchObject}"
+  log.info "Writing match object to database..."
+  #use bind with async to do the writes
+  sessionIDs = _.pluck @clientResponseObject.sessions, 'sessionID'
+  async.each sessionIDs, updateMatchesInSession.bind(@,matchObject), (err) -> callback err
+
+updateMatchesInSession = (matchObject, sessionID, callback) ->
+  currentMatchObject = {}
+  currentMatchObject.date = matchObject.date
+  currentMatchObject.metrics = matchObject.opponents[sessionID].metrics
+  opponentsClone = _.cloneDeep matchObject.opponents
+  opponentsClone = _.omit opponentsClone, sessionID
+  opponentsArray = _.toArray opponentsClone
+  currentMatchObject.opponents = opponentsArray
+
+  sessionUpdateObject =
+    $push: {matches: {$each: [currentMatchObject], $slice: -200}}
+  log.info "Updating session #{sessionID}"
+  LevelSession.update {"_id":sessionID}, sessionUpdateObject, callback
+
+updateUserSimulationCounts = (reqUserID,callback) ->
+  incrementUserSimulationCount reqUserID, 'simulatedBy', (err) =>
+    if err? then return callback err
+    incrementUserSimulationCount @levelSession.creator, 'simulatedFor', callback
+
+incrementUserSimulationCount = (userID, type, callback) =>
+  inc = {}
+  inc[type] = 1
+  User.update {_id: userID}, {$inc: inc}, (err, affected) ->
+    log.error "Error incrementing #{type} for #{userID}: #{err}" if err
+    callback err
+
+determineIfSessionShouldContinueAndUpdateLog = (cb) ->
+  sessionID = @clientResponseObject.originalSessionID
+  sessionRank = parseInt @clientResponseObject.originalSessionRank
+
   queryParameters =
     _id: sessionID

@@ -394,18 +563,28 @@
     totalNumberOfGamesPlayed = updatedSession.numberOfWinsAndTies + updatedSession.numberOfLosses
     if totalNumberOfGamesPlayed < 10
       console.log "Number of games played is less than 10, continuing..."
-      cb null, true
+      cb null
     else
       ratio = (updatedSession.numberOfLosses) / (totalNumberOfGamesPlayed)
       if ratio > 0.33
-        cb null, false
+        cb "shouldn't continue"
         console.log "Ratio(#{ratio}) is bad, ending simulation"
       else
         console.log "Ratio(#{ratio}) is good, so continuing simulations"
-        cb null, true
-
-
-findNearestBetterSessionID = (levelOriginalID, levelMajorVersion, sessionID, sessionTotalScore, opponentSessionTotalScore, opponentSessionID, opposingTeam, cb) ->
+        cb null
+
+
+findNearestBetterSessionID = (cb) ->
+  levelOriginalID = @levelSession.level.original
+  levelMajorVersion = @levelSession.level.majorVersion
+  sessionID = @clientResponseObject.originalSessionID
+  sessionTotalScore = @newScoresObject[sessionID].totalScore
+  opponentSessionID = _.pull(_.keys(@newScoresObject), sessionID)
+  opponentSessionTotalScore = @newScoresObject[opponentSessionID].totalScore
+  opposingTeam = calculateOpposingTeam(@clientResponseObject.originalSessionTeam)
+
+
+
   retrieveAllOpponentSessionIDs sessionID, (err, opponentSessionIDs) ->
     if err? then return cb err, null

@@ -434,23 +613,23 @@
     selectString = '_id totalScore'

     query = LevelSession.findOne(queryParameters)
-      .sort(sortParameters)
-      .limit(limitNumber)
-      .select(selectString)
-      .lean()
+    .sort(sortParameters)
+    .limit(limitNumber)
+    .select(selectString)
+    .lean()

     console.log "Finding session with score near #{opponentSessionTotalScore}"
     query.exec (err, session) ->
       if err? then return cb err, session
-      unless session then return cb err, null
+      unless session then return cb "no session was found"
       console.log "Found session with score #{session.totalScore}"
       cb err, session._id

 retrieveAllOpponentSessionIDs = (sessionID, cb) ->
   query = LevelSession.findOne({"_id":sessionID})
-    .select('matches.opponents.sessionID matches.date submitDate')
-    .lean()
+  .select('matches.opponents.sessionID matches.date submitDate')
+  .lean()
   query.exec (err, session) ->
     if err? then return cb err, null
     opponentSessionIDs = (match.opponents[0].sessionID for match in session.matches when match.date > session.submitDate)
@@ -462,44 +641,11 @@
   opposingTeams = _.pull teams, sessionTeam
   return opposingTeams[0]

-incrementUserSimulationCount = (userID, type) ->
-  inc = {}
-  inc[type] = 1
-  User.update {_id: userID}, {$inc: inc}, (err, affected) ->
-    log.error "Error incrementing #{type} for #{userID}: #{err}" if err
-
-
-addMatchToSessions = (clientResponseObject, newScoreObject, callback) ->
-  matchObject = {}
-  matchObject.date = new Date()
-  matchObject.opponents = {}
-  for session in clientResponseObject.sessions
-    sessionID = session.sessionID
-    matchObject.opponents[sessionID] = {}
-    matchObject.opponents[sessionID].sessionID = sessionID
-    matchObject.opponents[sessionID].userID = session.creator
-    matchObject.opponents[sessionID].metrics = {}
-    matchObject.opponents[sessionID].metrics.rank = Number(newScoreObject[sessionID].gameRanking)
-
-  log.info "Match object computed, result: #{matchObject}"
-  log.info "Writing match object to database..."
-  #use bind with async to do the writes
-  sessionIDs = _.pluck clientResponseObject.sessions, 'sessionID'
-  async.each sessionIDs, updateMatchesInSession.bind(@,matchObject), (err) -> callback err, null
-
-updateMatchesInSession = (matchObject, sessionID, callback) ->
-  currentMatchObject = {}
-  currentMatchObject.date = matchObject.date
-  currentMatchObject.metrics = matchObject.opponents[sessionID].metrics
-  opponentsClone = _.cloneDeep matchObject.opponents
-  opponentsClone = _.omit opponentsClone, sessionID
-  opponentsArray = _.toArray opponentsClone
-  currentMatchObject.opponents = opponentsArray
-
-  sessionUpdateObject =
-    $push: {matches: {$each: [currentMatchObject], $slice: -200}}
-  log.info "Updating session #{sessionID}"
-  LevelSession.update {"_id":sessionID}, sessionUpdateObject, callback
+
+addNewSessionsToQueue = (sessionID, callback) ->
+  sessions = [@clientResponseObject.originalSessionID, sessionID]
+  addPairwiseTaskToQueue sessions, callback
+

@@ -545,49 +691,6 @@

 handleTimedOutTask = (req, res, taskBody) -> errors.clientTimeout res, "The results weren't provided within the timeout"

-verifyClientResponse = (responseObject, res) ->
-  unless typeof responseObject is "object"
-    errors.badInput res, "The response to that query is required to be a JSON object."
-    null
-  else
-    responseObject
-
-logTaskComputation = (taskObject,taskLogObject, callback) ->
-  taskLogObject.calculationTimeMS = taskObject.calculationTimeMS
-  taskLogObject.sessions = taskObject.sessions
-  taskLogObject.save callback
-
-
-updateSessions = (taskObject,callback) ->
-  sessionIDs = _.pluck taskObject.sessions, 'sessionID'
-
-  async.map sessionIDs, retrieveOldSessionData, (err, oldScores) ->
-    if err? then callback err, {"error": "There was an error retrieving the old scores"}
-
-    oldScoreArray = _.toArray putRankingFromMetricsIntoScoreObject taskObject, oldScores
-    newScoreArray = bayes.updatePlayerSkills oldScoreArray
-    saveNewScoresToDatabase newScoreArray, callback
-
-
-saveNewScoresToDatabase = (newScoreArray, callback) ->
-  async.eachSeries newScoreArray, updateScoreInSession, (err) -> callback err,newScoreArray
-
-
-updateScoreInSession = (scoreObject,callback) ->
-  LevelSession.findOne {"_id": scoreObject.id}, (err, session) ->
-    if err? then return callback err, null
-
-    session = session.toObject()
-    newTotalScore = scoreObject.meanStrength - 1.8 * scoreObject.standardDeviation
-    scoreHistoryAddition = [Date.now(), newTotalScore]
-    updateObject =
-      meanStrength: scoreObject.meanStrength
-      standardDeviation: scoreObject.standardDeviation
-      totalScore: newTotalScore
-      $push: {scoreHistory: {$each: [scoreHistoryAddition], $slice: -1000}}
-
-    LevelSession.update {"_id": scoreObject.id}, updateObject, callback
-    log.info "New total score for session #{scoreObject.id} is #{updateObject.totalScore}"

 putRankingFromMetricsIntoScoreObject = (taskObject,scoreObject) ->


Add background color back for avatars

Add background color back for avatars

--- server/startup/avatar.coffee
+++ server/startup/avatar.coffee
@@ -21,7 +21,8 @@
 		# - Resize the image using the width or height as minium value
 		# - Keep the image aspect ratio
 		# - Crop image to keep max size of width and height
-		RocketChatFile.gm(readStream, file.fileName).resize(width, height+'^').gravity('Center').crop(width, height).stream('jpeg').pipe(writeStream)
+		# - Use extent to set background color for transparent images
+		RocketChatFile.gm(readStream, file.fileName).background('#ffffff').resize(width, height+'^').gravity('Center').crop(width, height).extent(width, height).stream('jpeg').pipe(writeStream)

 	path = "~/uploads"


Drag move map around

Drag move map around

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/tommycli/tabledice.git/'


Step 3 of moving client into class/module: index.coffee requires and instantiates it

error: pathspec 'apps/client-cli/index.coffee' did not match any file(s) known to git

--- apps/client-cli/index.coffee
+++ apps/client-cli/index.coffee
@@ -0,0 +1,3 @@
+ShellClient = require './shell-client'
+global.client = new ShellClient
+


Turned off magnifier if user click on center tab items. (#1934)

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/evercam/evercam-dashboard.git/'


client/app: remove ActivityItemMenuItem

client/app: remove ActivityItemMenuItem

Signed-off-by: Umut Sirin <4055abbc0e40a1254e715b952ccd414607e0b365@gmail.com>

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/andrewjcasal/koding.git/'


CLI Packages activation command

CLI Packages activation command

error: pathspec 'cli/commands/activate.coffee' did not match any file(s) known to git

--- cli/commands/activate.coffee
+++ cli/commands/activate.coffee
@@ -0,0 +1,55 @@
+#
+# This command is used to switch which version of
+# a package should be used as the default one
+#
+# Copyright (C) 2011 Nikolay Nemshilov
+#
+
+# searches for the latest version of the package in the directory
+find_latest = (location)->
+  fs       = require('fs')
+  versions = []
+
+  for entry in fs.readdirSync(location)
+    if fs.statSync("#{location}/#{entry}").isDirectory()
+      versions.push(entry)
+
+  versions.sort()
+  versions[versions.length - 1]
+
+
+# the main function
+exports.init = (args)->
+  fs       = require('fs')
+  path     = require('path')
+  location = lovelyrc.base
+  path     = require('path')
+  package  = args.shift()
+
+  if !package
+    print "FAILED:".red + " You should specify the package name"
+  else
+    location[location.length - 1] == '/' || (location += '/')
+    location += "packages/#{package}"
+
+    if !path.existsSync(location)
+      print "FAILED: ".red + "Could not locate package '#{package}'"
+    else
+      version = args.shift()
+      version = find_latest(location) unless version
+
+      if !path.existsSync("#{location}/#{version}")
+        print "FAILED: ".red + "Could not version '#{version}' of '#{package}'"
+      else
+        system("cd #{location}; ln -s #{version} current")
+
+
+exports.help = (args)->
+  """
+  Activates a certain package version to be the default one
+
+  Usage:
+    lovely activate <package-name> [version]
+
+  If no version is specified then the latest one will be used
+  """


missing formatter?

missing formatter?

error: pathspec 'client/formatters/png.coffee' did not match any file(s) known to git

--- client/formatters/png.coffee
+++ client/formatters/png.coffee
@@ -0,0 +1,15 @@
+# Plain SVG Formatter
+
+fs = require('fs')
+
+exports.init = ->
+
+  extensions: ['png']
+  assetType: 'png'
+  contentType: 'image/png'
+
+  compile: (path, options, cb) ->
+
+    input = fs.readFileSync(path, 'utf8')
+
+    cb(input)


Activity: CommentList: Updated link text

--- servers/lib/crawler/staticpages/activity.coffee
+++ servers/lib/crawler/staticpages/activity.coffee
@@ -74,7 +74,9 @@
   commentsList = prepareComments activityContent
   repliesCount = activityContent.replies?.length
   count        = Math.min (commentCount - repliesCount), 10
-  repliesText  = "There #{if count is 1 then 'is' else 'are'} #{count} number of comments above, login to see"
+  repliesText  = if count is 1
+  then "There is one comment above, please login to see."
+  else "There are #{count} comments above, please login to see."
   hasComments  = if repliesCount > 0
   then 'has-comments'
   else 'no-comments'


Activity: resize autogrow after submission

--- client/Social/Activity/views/inputview.coffee
+++ client/Social/Activity/views/inputview.coffee
@@ -24,8 +24,6 @@
     @emit 'Enter', value

-  empty: -> @setValue ''
-
-  setFocus: ->
-    el = @getElement()
-    @setCaretPosition @getValue().length
+  empty: ->
+    @setValue ''
+    @resize()


Added missing require, so colors works now...

--- lib/utils.coffee
+++ lib/utils.coffee
@@ -1,4 +1,4 @@
-
+require 'colors'
 fs = require 'fs-extra'
 path = require 'path-extra'

@@ -17,10 +17,10 @@
     console.log "[INFO] #{str}"
   warn: (str) ->
     str = stringify str
-    console.warn "[WARN] #{str}" #.yellow   # colors may not compatible with latest Electron, and make all messages "undefined"
+    console.warn "[WARN] #{str}".yellow
   error: (str) ->
     str = stringify str
-    console.error "[ERROR] #{str}" #.bold.red
+    console.error "[ERROR] #{str}".bold.red
   setBounds: (options) ->
     global.mainWindow.setBounds options
   getBounds: ->


don't exit till done

don't exit till done

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/mantacode/ftoggle-cli.git/'


account: fix format, space issues

account: fix format, space issues


payment: add subscribe group plan functionality


throw Norma error

throw Norma error

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/NewSpring/norma-sass.git/'


Adds visualization JS file

Adds visualization JS file

error: pathspec 'app/assets/javascripts/visualization.js.coffee' did not match any file(s) known to git

--- app/assets/javascripts/visualization.js.coffee
+++ app/assets/javascripts/visualization.js.coffee
@@ -0,0 +1,224 @@
+(($) ->
+  "use strict"
+
+  $.widget "ui.visualization",
+    options:
+      box:
+        height: 400
+        width: null
+      back: "OpenStreetMap.HOT"
+      show: null
+      edit: null
+      change: null
+      view: 'auto'
+      showStyle:
+        weight: 1
+        color: "#333"
+      editStyle:
+        weight: 2
+        color: "#33A"
+      controls:
+        draw:
+          edit:
+            featureGroup: null
+            edit:
+              color: "#A40"
+          draw:
+            marker: false
+            polyline: false
+            rectangle: false
+            circle: false
+            polygon:
+              allowIntersection: false
+              showArea: true
+        zoom:
+          position: "topleft"
+          zoomInText: ""
+          zoomOutText: ""
+        scale:
+          position: "bottomright"
+          imperial: false
+          maxWidth: 200
+
+    _create: ->
+      this.oldElementType = this.element.attr "type"
+      this.element.attr "type", "hidden"
+
+      $.extend(true, this.options, this.element.data("map-editor"))
+
+      this.mapElement = $("<div>", class: "map")
+        .insertAfter(this.element)
+      this.map = L.map(this.mapElement[0],
+        maxZoom: 25
+        zoomControl: false
+        attributionControl: false
+      )
+
+      widget = this
+
+      this.map.on "draw:created", (e) ->
+        widget.edition.addLayer e.layer
+        widget._saveUpdates()
+        widget.element.trigger "mapchange"
+
+      this.map.on "draw:edited", (e) ->
+        widget._saveUpdates()
+        widget.element.trigger "mapchange"
+
+      this.map.on "draw:deleted", (e) ->
+        widget._saveUpdates()
+        widget.element.trigger "mapchange"
+
+      this._resize()
+      # console.log "resized"
+      this._refreshBackgroundLayer()
+      # console.log "backgrounded"
+      this._refreshReferenceLayerGroup()
+      # console.log "shown"
+      this._refreshEditionLayerGroup()
+      # console.log "edited"
+      this._refreshView()
+      # console.log "viewed"
+      this._refreshControls()
+      # console.log "controlled"
+
+    _destroy: ->
+      this.element.attr this.oldElementType
+      this.mapElement.remove()
+
+    back: (back) ->
+      return this.options.back unless back?
+      this.options.back = back
+      this._refreshBackgroundLayer()
+
+    show: (geojson) ->
+      return this.options.show unless geojson?
+      this.options.show = geojson
+      this._refreshReferenceLayerGroup()
+
+    edit: (geojson) ->
+      return this.options.edit unless geojson?
+      this.options.edit = geojson
+      this._refreshEditionLayerGroup()
+
+    view: (view) ->
+      return this.options.view unless view?
+      this.options.view = view
+      this._refreshView()
+
+    zoom: (zoom) ->
+      return this.map.getZoom() unless zoom?
+      this.options.view.zoom = zoom
+      this._refreshZoom()
+
+    height: (height) ->
+      return this.options.box.height() unless height?
+      this.options.view.box.height = height
+      this._resize()
+
+    _resize: ->
+      if this.options.box?
+        if this.options.box.height?
+          this.mapElement.height this.options.box.height
+        if this.options.box.width?
+          this.mapElement.width this.options.box.width
+        this._trigger "resize"
+
+    _refreshBackgroundLayer: ->
+      if this.backgroundLayer?
+        this.map.removeLayer(this.backgroundLayer)
+      if this.options.back?
+        if this.options.back.constructor.name is "String"
+          this.backgroundLayer = L.tileLayer.provider(this.options.back)
+          this.backgroundLayer.addTo this.map
+        else
+          console.log "How to set background with #{this.options.back}?"
+          console.log this.options.back
+      this
+
+    _refreshReferenceLayerGroup: ->
+      if this.reference?
+        this.map.removeLayer this.reference
+      if this.options.show?
+        this.reference = L.GeoJSON.geometryToLayer(this.options.show).setStyle this.options.showStyle
+        this.reference.addTo this.map
+      this
+
+    _refreshEditionLayerGroup: ->
+      if this.edition?
+        this.map.removeLayer this.edition
+      if this.options.edit?
+        this.edition = L.GeoJSON.geometryToLayer(this.options.edit)
+      else
+        this.edition = new L.GeoJSON()
+      this.edition.setStyle this.options.editStyle
+      this.edition.addTo this.map
+      this._refreshControls()
+      this._saveUpdates()
+      this
+
+    _refreshView: (view) ->
+      view ?= this.options.view
+      if view is 'auto'
+        try
+          this._refreshView('show')
+        catch
+          try
+            this._refreshView('edit')
+          catch
+            this._setDefaultView()
+      else if view is 'show'
+        this.map.fitBounds this.reference.getLayers()[0].getBounds()
+      else if view is 'edit'
+        this.map.fitBounds this.edition.getLayers()[0].getBounds()
+      else if view is 'default'
+        this._setDefaultView()
+      else if view.center?
+        center = L.latLng(view.center[0], view.center[1])
+        if view.zoom?
+          this.map.setView(center, view.zoom)
+        else
+          this.map.setView(center, 12)
+      else if view.bounds?
+        this.map.fitBounds(view.bounds)
+      else
+        console.log "How to set view with #{view}?"
+        console.log view
+      this
+
+    _setDefaultView: ->
+      this.map.fitWorld()
+      this.map.setZoom 6
+
+    _refreshZoom: ->
+      if this.options.view.zoom?
+        this.map.setZoom(this.options.view.zoom)
+
+    _refreshControls: ->
+      if this.controls?
+        for name, control of this.controls
+          this.map.removeControl(control)
+      this.controls = {}
+      unless this.options.controls.zoom is false
+        this.controls.zoom = new L.Control.Zoom(this.options.controls.zoom)
+        this.map.addControl this.controls.zoom
+      unless this.options.controls.fullscreen is false
+        this.controls.fullscreen = new L.Control.FullScreen(this.options.controls.fullscreen)
+        this.map.addControl this.controls.fullscreen
+      if this.edition?
+        this.controls.draw = new L.Control.Draw($.extend(true, {}, this.options.controls.draw, {edit: {featureGroup: this.edition}}))
+        this.map.addControl this.controls.draw
+      unless this.options.controls.scale is false
+        this.controls.scale = new L.Control.Scale(this.options.controls.scale)
+        this.map.addControl this.controls.scale
+
+    _saveUpdates: ->
+      if this.edition?
+        this.element.val JSON.stringify(this.edition.toGeoJSON())
+      true
+
+  $(document).ready ->
+    $("input[data-visualization]").each ->
+      $(this).visualization()
+
+) jQuery


Modified in browser at pixie.strd6.com

Modified in browser at pixie.strd6.com

error: pathspec 'src/TiledBackground.coffee' did not match any file(s) known to git

--- src/TiledBackground.coffee
+++ src/TiledBackground.coffee
@@ -0,0 +1,17 @@
+Tilebackground = (I={}) ->
+  # Set some default properties
+  Object.reverseMerge I,
+    color: "blue"
+    height: 32
+    width: 32
+    # spriteName: "block" # Use the name of a sprite in the images folder
+
+  # Inherit from game object
+  self = GameObject(I)
+
+  # Add events and methods here
+  self.bind "update", ->
+    # Add update method behavior
+
+  # We must always return self as the last line
+  return self


added basic app

added basic app

error: pathspec 'app.coffee' did not match any file(s) known to git

--- app.coffee
+++ app.coffee
@@ -0,0 +1,38 @@
+express = require 'express'
+http = require 'http'
+mongoose = require 'mongoose'
+
+SkuResource = require './resources/sku_resource'
+SkuQuantityResource = require './resources/sku_quantity_resource'
+ProductResource = require './resources/product_resource'
+OfferResource = require './resources/offer_resource'
+DealResource = require './resources/deal_resource'
+
+
+app = express()
+
+
+mongoose.connect process.env.MONGODB_CONNECTION_STRING or 'mongodb://localhost:27017/balto-dev'
+
+
+app.set 'port', process.env.PORT or 3000
+
+
+app.use express.logger()
+app.use express.json()
+app.use express.urlencoded()
+app.use express.methodOverride()
+app.use app.router
+app.use express.errorHandler()
+
+
+# routes
+SkuResource.make_routes app
+SkuQuantityResource.make_routes app
+ProductResource.make_routes app
+OfferResource.make_routes app
+DealResource.make_routes app
+
+
+http.createServer(app).listen app.get('port'), ->
+  console.log "express server listening on port #{app.get('port')}"


client/webpack: add mocks path for easy access


Fixed registerbutton disabling/re-enabling

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/C-Bouthoorn/Anthony-Server.git/'


Add internal logger and remove console.log calls.

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/RobotSnacks/stout-server.git/'


ComputeController::handlenNewMachineRequest: create new machine if there is not one

--- client/Main/providers/computecontroller.coffee
+++ client/Main/providers/computecontroller.coffee
@@ -426,21 +426,46 @@

   handleNewMachineRequest: ->

+    return  if @_inprogress
+    @_inprogress = yes
+
     @fetchUserPlan (plan)=>

       @fetchPlans (plans)=>

-        @fetchUsage provider: "koding", (err, usage)->
-
-          return  if KD.showError err
+        @fetchUsage provider: "koding", (err, usage)=>
+
+          if KD.showError err
+            return @_inprogress = no

           limits  = plans[plan]
           options = { plan, limits, usage }

           if plan in ['developer', 'professional', 'super']
+
             new ComputePlansModal.Paid options
+            @_inprogress = no
+
           else
-            new ComputePlansModal.Free options
+
+            @fetchMachines (err, machines)=>
+
+              warn err  if err?
+
+              if err? or machines.length > 0
+                new ComputePlansModal.Free options
+                @_inprogress = no
+
+              else if machines.length is 0
+
+                stack = @stacks.first._id
+
+                @create { provider : "koding", stack }, (err, machine)=>
+
+                  @_inprogress = no
+
+                  unless KD.showError err
+                    KD.userMachines.push machine

   triggerReviveFor:(machineId)->


client: make sure to return when there is an error

Signed-off-by: Umut Sirin <4055abbc0e40a1254e715b952ccd414607e0b365@gmail.com>

--- client/app/lib/flux/environment/actions.coffee
+++ client/app/lib/flux/environment/actions.coffee
@@ -483,7 +483,7 @@
   remote.api.JStackTemplate.some query, { limit: 30 }, (err, templates) ->

     if err
-      reactor.dispatch actions.LOAD_PRIVATE_STACK_TEMPLATES_FAIL, { query, err }
+      return reactor.dispatch actions.LOAD_PRIVATE_STACK_TEMPLATES_FAIL, { query, err }

     templates = templates.filter (t) -> t.accessLevel is 'private'


Update src/scripts/translate.coffee

Update src/scripts/translate.coffee

simply changed '&&' to 'and' to make it more coffee-fied

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/sharabash/hubot.git/'


js fix for codepick

js fix for codepick

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/treasures-io/main.git/'


Bugfix - change table name

Bugfix - change table name

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/keboola/kbc-ui-gooddata-writer.git/'


Remove focusout validations

Remove focusout validations

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/luminopolis/catarse_credit_card_net.git/'


MachineStateModal: revert to old state if there is an error with the request


Client: add apitokenlist.coffee

Client: add apitokenlist.coffee

error: pathspec 'client/admin/lib/views/api/apitokenlist.coffee' did not match any file(s) known to git

--- client/admin/lib/views/api/apitokenlist.coffee
+++ client/admin/lib/views/api/apitokenlist.coffee
@@ -0,0 +1,39 @@
+kd                    = require 'kd'
+showError             = require 'app/util/showError'
+KDListView            = kd.ListView
+KDModalView           = kd.ModalView
+KDOverlayView         = kd.OverlayView
+ApiTokenItemView      = require './apitokenitemview'
+
+
+module.exports = class ApiTokenList extends KDListView
+
+  constructor: (options = {}, data) ->
+    options.wrapper   ?= yes
+    options.itemClass ?= ApiTokenItemView
+
+    super options, data
+
+
+  deleteItem: (item) ->
+
+    stack = item.getData()
+
+    overlay = new KDOverlayView cssClass: 'second-overlay'
+
+    modal   = KDModalView.confirm
+      title       : 'Remove Api Token'
+      description : 'Do you want to remove ?'
+      ok          :
+        title     : 'Yes'
+        callback  : =>
+          apiToken = item.data
+          apiToken.remove (err) =>
+            modal.destroy()
+            @emit 'ItemDeleted', item  unless showError err
+
+    modal.once   'KDObjectWillBeDestroyed', overlay.bound 'destroy'
+    overlay.once 'click',                   modal.bound   'destroy'
+
+    return modal
+


Tests: AppManager: Refactor tests to use helper fn.


kite: rename callback to cb

kite: rename callback to cb


Moved ProjectUtils to bismuth-utility.

Moved ProjectUtils to bismuth-utility.

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/urbanetic/bismuth-schema.git/'


New default hover message background color

Does not override "mention ticks" on scrollbar

--- packages/rocketchat-theme/server/variables.coffee
+++ packages/rocketchat-theme/server/variables.coffee
@@ -20,7 +20,7 @@
 RocketChat.theme.addPublicColor "info-font-color", "#aaaaaa"
 RocketChat.theme.addPublicColor "input-font-color", "rgba(255, 255, 255, 0.85)"
 RocketChat.theme.addPublicColor "link-font-color", "#008ce3"
-RocketChat.theme.addPublicColor "message-hover-background-color", "#f9f9f9"
+RocketChat.theme.addPublicColor "message-hover-background-color", "rgba(0, 0, 0, 0.025)"
 RocketChat.theme.addPublicColor "smallprint-font-color", "#c2e7ff"
 RocketChat.theme.addPublicColor "smallprint-hover-color", "#ffffff"
 RocketChat.theme.addPublicColor "status-away", "#fcb316"


got rid of ie-specific stuff and moved each functions to BaseMap

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/genericdave/speedr.js.git/'


removing pagination limits

removing pagination limits

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/netguru/review.git/'


remove skipDuplicates kludge due to current visibility state behavior on android (claims 'visible' by default, but we also want to listen to when it actually becomes visible)

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/AppGyver/supersonic.git/'


A critical fix for Kodingen users merge collection jOldUser

--- workers/social/lib/social/models/olduser.coffee
+++ workers/social/lib/social/models/olduser.coffee
@@ -67,8 +67,13 @@

       csv.on 'record', (line, lineNumber)->
         if iterations < limit or limit is 0
-          f_name = line[9].slice(0, line[9].indexOf(' ')) or line[9]
-          l_name = line[9].slice line[9].indexOf(' ')+1
+
+          if not line[9].indexOf(' ')
+            f_name = line[9].slice(0, line[9].indexOf(' '))
+            l_name = line[9].slice line[9].indexOf(' ')+1
+          else
+            f_name = line[9]
+            l_name = ''

           olduser = new JOldUser
             email     : line[4]


payment: fix exported method signature

payment: fix exported method signature

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/andrewjcasal/koding.git/'


Compare input with last input before requesting preview

--- resources/assets/coffee/_classes/forum-topic-reply.coffee
+++ resources/assets/coffee/_classes/forum-topic-reply.coffee
@@ -30,6 +30,8 @@
     @editBox = document.getElementsByClassName('js-forum-reply-write')
     @previewBox = document.getElementsByClassName('js-forum-reply-preview')

+    @lastBody = null
+
     $(document).on 'ajax:success', '.js-forum-topic-reply', @posted

     $(document).on 'click', '.js-forum-reply-preview--show', @fetchPreview
@@ -125,24 +127,30 @@

   fetchPreview: =>
-    return if $(@previewButton).hasClass('active')
-
-    if $(@previewButton).attr('data-should-refresh') == '0'
+    $button = $(@previewButton)
+    url = $button.attr 'data-preview-url'
+
+    $input = $(@input)
+    body = $input.val()
+
+    $preview = $(@previewBox)
+
+    return if $button.hasClass('active')
+
+    if @lastBody == body
       @showPreview()
       return

     $.ajax
-      url: $(@previewButton).attr('data-preview-url')
+      url: url
       method: 'POST'
       data:
-        body: $(@input).val()
+        body: body

     .done (data) =>
-      $(@previewBox).html(data)
-
-      $(@previewButton).attr('data-should-refresh', '0')
-      $(@input).one 'input', @invalidatePreview
-
+      @lastBody = body
+
+      $preview.html(data)
       @showPreview()

@@ -161,10 +169,6 @@

     $(@previewButton).removeClass('active')
     $(@writeButton).addClass('active')
-
-
-  invalidatePreview: =>
-    $(@previewButton).attr('data-should-refresh', '1')

   posted: (e, data) =>


Add sort by update date option

Add sort by update date option

--- resources/assets/coffee/react/beatmaps/search-sort.coffee
+++ resources/assets/coffee/react/beatmaps/search-sort.coffee
@@ -22,7 +22,7 @@
 class Beatmaps.SearchSort extends React.PureComponent
   render: =>
     div className: 'beatmapsets-sorting',
-      for field in ['title', 'artist', 'difficulty', 'ranked', 'rating', 'plays']
+      for field in ['title', 'artist', 'difficulty', 'ranked', 'rating', 'updated', 'plays']
         selected = @selected(field)

         a


Add task to log loop returns

Add task to log loop returns

error: pathspec 'build/tasks/output-for-loop-returns.coffee' did not match any file(s) known to git

--- build/tasks/output-for-loop-returns.coffee
+++ build/tasks/output-for-loop-returns.coffee
@@ -0,0 +1,22 @@
+path = require 'path'
+
+module.exports = (grunt) ->
+  grunt.registerTask 'output-for-loop-returns', 'Log methods that end with a for loop', ->
+    appDir = grunt.config.get('atom.appDir')
+
+    jsPaths = []
+    grunt.file.recurse path.join(appDir, 'src'), (absolutePath, rootPath, relativePath, fileName) ->
+      jsPaths.push(absolutePath) if path.extname(fileName) is '.js'
+
+    jsPaths.forEach (jsPath) ->
+      js = grunt.file.read(jsPath)
+      method = null
+      for line, index in js.split('\n')
+        [match, className, methodName] = /^\s*([a-zA-Z]+)\.prototype\.([a-zA-Z]+)\s*=\s*function\(/.exec(line) ? []
+        if className and methodName
+          method = "#{className}::#{methodName}"
+        else
+          [match, ctorName] = /^\s*function\s+([a-zA-Z]+)\(/.exec(line) ? []
+
+        if /^\s*return\s+_results;\s*$/.test(line)
+          console.log(method ? "#{path.basename(jsPath)}:#{index}")


GitLab: Handler: for Key events

GitLab: Handler: for Key events

error: pathspec 'servers/lib/server/handlers/api/gitlab/key.coffee' did not match any file(s) known to git

--- servers/lib/server/handlers/api/gitlab/key.coffee
+++ servers/lib/server/handlers/api/gitlab/key.coffee
@@ -0,0 +1,27 @@
+GenericHandler = require './generichandler'
+
+module.exports = class Key extends GenericHandler
+
+
+  # event key_create
+  @create = (data, callback = ->) ->
+    {
+     username
+     key
+    } = data
+
+    # IMPLEMENT ME
+
+    callback { message: 'key create handler is not implemented' }
+
+
+  # event key_destroy
+  @destroy = (data, callback = ->) ->
+    {
+     username
+     key
+    } = data
+
+    # IMPLEMENT ME
+
+    callback { message: 'key destroy handler is not implemented' }


Return the public interface explicitly

Return the public interface explicitly

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/enrmarc/f.git/'


clicking text input x in ie-10 resets filter

closes CNVS-9967

test plan:
  - duplicate test with default and fabulous ember quizzes
    - navigate to quiz index in IE 10
    - enter text in filter / search for quiz
    - click the 'x' to clear the input
      - text input should clear
      - filter should be removed (all quizzes should display)

Change-Id: Iccd67fc8c4c5fffaafeea72d60af693d6630f0cd
Reviewed-on: https://gerrit.instructure.com/27736
Tested-by: Jenkins <d95b56ce41a2e1ac4cecdd398defd7414407cc08@instructure.com>
Reviewed-by: Derek DeVries <ff87a0776152510efd53bb1f4ea089dbbc90e730@instructure.com>
QA-Review: Nathan Rogowski <2e8aa918660411855c6d44d5bb2da677aa033255@instructure.com>
Product-Review: Jason Madsen <bcb5fff571a20f07c35d17ba9c364855c776dce7@instructure.com>

--- app/coffeescripts/views/quizzes/IndexView.coffee
+++ app/coffeescripts/views/quizzes/IndexView.coffee
@@ -17,6 +17,7 @@

     events:
       'keyup #searchTerm': 'keyUpSearch'
+      'mouseup #searchTerm': 'keyUpSearch' #ie10 x-close workaround

     initialize: ->
       super
@@ -53,4 +54,4 @@
       for part in keys
         #not using match to avoid javascript string to regex oddness
         numMatches++ if title.indexOf(part) != -1
-      numMatches == keys.length+      numMatches == keys.length


 Merge branch 'master.copy' into 'master'

Master.Copy


ComputeStateChecker: disable statechecker toggle logs


add a perf spec

add a perf spec

error: pathspec 'test/perf/perf-specs/flatten-vs-flatmap.coffee' did not match any file(s) known to git

--- test/perf/perf-specs/flatten-vs-flatmap.coffee
+++ test/perf/perf-specs/flatten-vs-flatmap.coffee
@@ -0,0 +1,18 @@
+Kefir = require('../../../dist/kefir.js')
+
+id = (x) -> x
+toConstant = (x) -> Kefir.constant(x)
+
+fromArray = (arr) ->
+  Kefir.stream ({emit, end}) ->
+    for x in arr
+      emit(x)
+    end()
+
+arr = [1..1000]
+
+
+require('../perf-helper.coffee').setupTest 'A: s.flatten(fn), B: s.flatMap(fn)', {
+  kefirA: (stream) -> stream.flatten(-> arr)
+  kefirB: (stream) -> stream.flatMap(-> fromArray(arr))
+}


no need to check for id, isStartedView does it already


Implement the confirm().

Implement the confirm().

--- renderer/lib/override.coffee
+++ renderer/lib/override.coffee
@@ -41,3 +41,10 @@
   dialog = remote.require 'dialog'
   buttons = ['OK']
   dialog.showMessageBox remote.getCurrentWindow(), {message, title, buttons}
+
+# And the confirm().
+window.confirm = (message, title='') ->
+  remote = require 'remote'
+  dialog = remote.require 'dialog'
+  buttons = ['OK', 'Cancel']
+  not dialog.showMessageBox remote.getCurrentWindow(), {message, title, buttons}


made more space by making stars smaller

made more space by making stars smaller

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/UCSFMemoryAndAging/tabcat.git/'


switch link to github profile

switch link to github profile

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/stevelacy/slacy.me.git/'


refactor

refactor

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/netguru/people.git/'


added test

added test

error: pathspec 'test/unit/factory/page-loader-factory-spec.coffee' did not match any file(s) known to git

--- test/unit/factory/page-loader-factory-spec.coffee
+++ test/unit/factory/page-loader-factory-spec.coffee
@@ -0,0 +1,29 @@
+define [
+  'config'
+  'angular'
+  'factory/page-loader-factory'
+], (cfg, A) ->
+  describe 'Page loader factory', () ->
+    factory = null
+
+    beforeEach module cfg.ngApp
+
+    beforeEach inject ($injector) ->
+      factory = $injector.get 'pageLoaderFactory'
+
+    it 'should $emit an event that says whether to hide or show the loader', () ->
+      showing = true
+      cb =
+        handleLoader: (event, show) ->
+          expect(show).toBe showing
+
+      factory.addListener cb.handleLoader
+
+      runs () ->
+        factory.show()
+
+      waits 250
+
+      runs () ->
+        showing = false
+        factory.hide()


adds missing exports

adds missing exports

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/kevgo/asynchronizer-rails.git/'


add next exp

add next exp


fix(Dragger): disableDragging logic fixed

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/VenDream/MoePlayer.git/'


GroupStackSettings: remove/move old helpers

--- client/admin/lib/views/groupstacksettings.coffee
+++ client/admin/lib/views/groupstacksettings.coffee
@@ -12,27 +12,6 @@
 module.exports     = class GroupStackSettings extends kd.View

   StacksCustomViews.mixin @prototype
-
-  # This will be used if stack template is not defined yet
-  defaultTemplate = """
-  {
-    "provider": {
-      "aws": {
-        "access_key": "${var.access_key}",
-        "secret_key": "${var.secret_key}",
-        "region": "ap-northeast-1"
-      }
-    },
-    "resource": {
-      "aws_instance": {
-        "example": {
-          "instance_type": "t2.micro",
-          "ami": "ami-936d9d93"
-        }
-      }
-    }
-  }
-  """

   constructor: (options = {}, data) ->

@@ -84,21 +63,6 @@
     steps.first()

-  createEditorPane: (content) ->
-
-    content = Encoder.htmlDecode content
-    file    = FSHelper.createFileInstance path: 'localfile:/stack.json'
-
-    @addSubView editorContainer = new kd.View
-    editorContainer.setCss height: '240px'
-
-    editorContainer.addSubView @editorPane = new IDEEditorPane {
-      file, content, delegate: this
-    }
-
-    @editorPane.setCss background: 'black'
-
-
   createCredentialsBox: ->

     creds = ({title: c.title, value: c.publicKey} for c in @_credentials)
@@ -109,27 +73,6 @@
     @addSubView @credentialBox = new kd.SelectBox
       name          : "credential"
       selectOptions : creds
-
-
-  createOutputView: ->
-
-    @outputView = new kd.View
-    @outputView.setCss height: 'auto'
-
-    @addSubView @outputView
-
-
-  checkCredential: (callback) ->
-
-    selected   = @credentialBox.getValue()
-    credential = cred for cred in @_credentials when cred.publicKey is selected
-
-    credential.isBootstrapped (err, state) ->
-      return callback err  if err
-
-      callback if not state then {
-        message: 'Credential is not bootstrapped yet.'
-      } else null

   fetchData: (callback) ->
@@ -190,19 +133,6 @@

       .catch   @bound 'showError'
       .finally @saveButton.bound 'hideLoader'
-
-
-  showError: (err) ->
-
-    console.warn "ERROR:", err
-
-    err = err.message  if err.message?
-
-    @outputView.updatePartial applyMarkdown """
-      An error occured:
-
-      ```json\n#{err}\n```
-    """

   updateStackTemplate: (data)->


GroupStackSettings: make step generator more generic


added link parsing of the header

added link parsing of the header

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/mjpuser/riak-client.git/'


Workspace: Rename detachable pane variable.


use Block

use Block

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/showell/CoffeeCoffee.git/'


Adjust image helper aspect ratios from 4x3 to 6x5 to more accurately classify images.

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/lonelyplanet/rizzo.git/'


Display message if there is no snapshot

Display message if there is no snapshot

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/evercam/evercam-dashboard.git/'


forget a box when its destroyed

forget a box when its destroyed

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/clochix/cozy-emails.git/'


Adds applause, Orson Welles style

Adds applause, Orson Welles style

error: pathspec 'src/scripts/applause.coffee' did not match any file(s) known to git

--- src/scripts/applause.coffee
+++ src/scripts/applause.coffee
@@ -0,0 +1,18 @@
+# Description:
+#   Applause from Orson Welles
+#
+# Dependencies:
+#   None
+#
+# Configuration:
+#   None
+#
+# Commands:
+#   (applause|applaud|bravo|slow clap) - Get applause
+#
+# Author:
+#   joshfrench
+
+module.exports = (robot) ->
+  robot.hear /applau(d|se)|bravo|slow clap/i, (msg) ->
+    msg.send "http://i.imgur.com/9Zv4V.gif"


Removed logging

Removed logging

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/urbanetic/bismuth-schema.git/'


added goat facts

added goat facts

error: pathspec 'scripts/goatfacts.coffee' did not match any file(s) known to git

--- scripts/goatfacts.coffee
+++ scripts/goatfacts.coffee
@@ -0,0 +1,20 @@
+# Description:
+#   GoatFacts is the most important thing in your life
+#
+# Dependencies:
+#   None
+#
+# Configuration:
+#   None
+#
+# Commands:
+#   hubot goat facts - Receive a goat fact
+
+module.exports = (robot) ->
+
+  robot.respond /goat fact/i, (msg) ->
+    msg.http("http://sheep-facts.herokuapp.com/facts")
+      .get() (err, res, body) ->
+        msg.send JSON.parse(body).fact
+
+


Fix race-condition when loading entry pages

--- assets/javascripts/views/content/entry_page.coffee
+++ assets/javascripts/views/content/entry_page.coffee
@@ -89,6 +89,7 @@
     return

   onSuccess: (response) =>
+    return unless @activated
     @xhr = null
     @render @prepareContent(response)
     return


IDE: routes: handle collaboration only for shared machines

--- client/ide/lib/routes.coffee
+++ client/ide/lib/routes.coffee
@@ -112,10 +112,14 @@

       if machine

+        mine          = machine.isMine()
+        collaboration = machine.channelId? and not machine.isPermanent()
         # which means there is a collaboration session for this machine ~ GG
-        if machine.channelId and not machine.isPermanent()
+        if not mine and collaboration

           socialapi.cacheable 'channel', machine.channelId, (err, channel) ->
+
+            return loadIDE { machine }  if err or not channel

             query = { socialApiId: channel.creatorId }


add widget for students list in rtm

add widget for students list in rtm

error: pathspec 'rtm_student.widget/main.coffee' did not match any file(s) known to git

--- rtm_student.widget/main.coffee
+++ rtm_student.widget/main.coffee
@@ -0,0 +1,51 @@
+command: "/Users/yina/.pyenv/shims/python /Users/yina/Dropbox/Backups/geektool/ubersicht_widgets/bin/rtm_cli.py -c -p ls list:students priority:0"
+
+refreshFrequency: 10000
+
+style: """
+  top: 450px
+  left: 375px
+
+	*
+		margin 0
+		padding 0
+
+	#container1
+		margin 0
+		padding 0
+		color rgba(#fff, .9)
+		font-family Lucida Grande
+		font-size 10pt
+
+	ul
+		list-style none
+
+	li
+		padding 10px
+		&:not(:last-child)
+			border-bottom solid 1px white
+
+	tbody
+		font-size 12pt
+
+  td
+  	width 60px
+   text-align right
+
+"""
+
+render: (output) -> """
+

+

+

+

+

+

+       #{output}
+

+

+

+

+

+

+"""


Add search frontmatter and markup to the data events reference index page.

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/fulcrumapp/fulcrum-expressions.git/'


Have mongo-admin search search by slugs too

--- server/middleware/users.coffee
+++ server/middleware/users.coffee
@@ -406,6 +406,7 @@
       $or: [
         {emailLower: search.toLowerCase()}
         {nameLower: search.toLowerCase()}
+        {slug: _.str.slugify(search)}
       ]
     }
     query.$or.push {_id: mongoose.Types.ObjectId(search)} if utils.isID search


Don't redirect to 'getting started' for lack of events

--- lib/www_routes.coffee
+++ lib/www_routes.coffee
@@ -56,7 +56,6 @@
     ], (err, results) ->
       return www_methods.handle_error(req, res, err) if err?
       [events, groups_docs] = results
-      return res.redirect("/about/starting/") if events.length == 0
       res.render 'home/dashboard', context(req, {
         title: "InterTwinkles"
       }, {


Added REDIS_URL to support dokku

Added REDIS_URL to support dokku

--- src/scripts/redis-brain.coffee
+++ src/scripts/redis-brain.coffee
@@ -5,7 +5,7 @@
 #   "redis": "0.8.4"
 #
 # Configuration:
-#   REDISTOGO_URL or REDISCLOUD_URL or BOXEN_REDIS_URL
+#   REDISTOGO_URL or REDISCLOUD_URL or BOXEN_REDIS_URL or REDIS_URL
 #
 # Commands:
 #   None
@@ -17,7 +17,7 @@
 Redis = require "redis"

 module.exports = (robot) ->
-  info   = Url.parse process.env.REDISTOGO_URL or process.env.REDISCLOUD_URL or process.env.BOXEN_REDIS_URL or 'redis://localhost:6379'
+  info   = Url.parse process.env.REDISTOGO_URL or process.env.REDISCLOUD_URL or process.env.BOXEN_REDIS_URL or process.env.REDIS_URL or 'redis://localhost:6379'
   client = Redis.createClient(info.port, info.hostname)

   robot.brain.setAutoSave false


Add menu items

Add menu items

error: pathspec 'menus/package-generator.cson' did not match any file(s) known to git

--- menus/package-generator.cson
+++ menus/package-generator.cson
@@ -0,0 +1,10 @@
+'menu': [
+  'label': 'Packages'
+  'submenu': [
+    'label': 'Package Generator'
+    'submenu': [
+      { 'label': 'Generate Atom Package', 'command': 'package-generator:generate-package' }
+      { 'label': 'Generate Atom Theme', 'command': 'package-generator:generate-theme' }
+    ]
+  ]
+]


Hubot keeps your grocery list organized

Hubot keeps your grocery list organized

error: pathspec 'src/scripts/grocery-list.coffee' did not match any file(s) known to git

--- src/scripts/grocery-list.coffee
+++ src/scripts/grocery-list.coffee
@@ -0,0 +1,63 @@
+# Description:
+#   Organize your grocery list
+#
+# Dependencies:
+#   None
+#
+# Configuration:
+#   None
+#
+# Commands:
+#   hubot grocery list - list items on your grocery list
+#   hubot remind me to buy <item> - add item to grocery list
+#   hubot i bought <item> - mark item as purchased
+#   hubot remove <item> from my grocery lists
+#
+# Author:
+#   parkr
+
+module.exports = (robot) ->
+
+  robot.brain.data.groceryList =
+    toBuy: {},
+    purchased: {}
+  groceryList =
+    get: ->
+      Object.keys(robot.brain.data.groceryList.toBuy)
+
+    getPurchased: ->
+      Object.keys(robot.brain.data.groceryList.purchased)
+
+    add: (item) ->
+      robot.brain.data.groceryList.toBuy[item] = true
+
+    remove: (item) ->
+      delete robot.brain.data.groceryList.toBuy[item]
+      true
+
+    bought: (item) ->
+      delete robot.brain.data.groceryList.toBuy[item]
+      robot.brain.data.groceryList.purchased[item] = true
+
+  robot.respond /grocery list$/i, (msg) ->
+    list = groceryList.get().join("\n") || "No items in your grocery list."
+    msg.send list
+
+  robot.respond /remind me to (buy|get) (.*)/i, (msg) ->
+    item = msg.match[2].trim()
+    groceryList.add item
+    msg.send "ok, added #{item} to your grocery list."
+
+  robot.respond /i bought (.*)/i, (msg) ->
+    item = msg.match[1].trim()
+    groceryList.bought item
+    msg.send "ok, marked #{item} as purchased."
+
+  robot.respond /remove (.*)/i, (msg) ->
+    item = msg.match[1].trim()
+    groceryList.remove item
+    msg.send "ok, removed #{item} from your grocery list."
+
+  robot.respond /what have i purchased/i, (msg) ->
+    list = groceryList.getPurchased().join("\n") || "You haven't purchased anything."
+    msg.send list


Generic TextArea Ember view

Generic TextArea Ember view

error: pathspec 'app/assets/javascripts/views/textarea.js.coffee' did not match any file(s) known to git

--- app/assets/javascripts/views/textarea.js.coffee
+++ app/assets/javascripts/views/textarea.js.coffee
@@ -0,0 +1,4 @@
+ETahi.TextArea = Ember.TextArea.extend
+  attributeBindings: [ "name", "type", "value", "model"]
+  focusOut: ->
+    @get('model').save()


CustomDataListItem: initial commit

CustomDataListItem: initial commit

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/andrewjcasal/koding.git/'


Check there's data to handle

Check there's data to handle

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/leonidas/qa-dashboard.git/'


filereading attempt 13

filereading attempt 13

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/newsdev/geoip.git/'


Create even-occuring-element.coffee

Create even-occuring-element.coffee

error: pathspec 'even-occuring-element/even-occuring-element.coffee' did not match any file(s) known to git

--- even-occuring-element/even-occuring-element.coffee
+++ even-occuring-element/even-occuring-element.coffee
@@ -0,0 +1,12 @@
+evenOccuringElement = (array) ->
+  hash = {}
+
+  # Loop though the array adding all the elements together in a hash
+  array.forEach (num) ->
+    hash[num] = hash[num] + 1 or 1
+
+  # Loop through all the keys in the hash, returning the number if we have an
+  # even number of occurances
+  for i of hash
+    return Number(i)  unless hash[i] & 1
+  false


Fix automigrate in coffee, closes #592

Fix automigrate in coffee, closes #592

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/weber/compound-ex4.git/'


Create tracking-bot.coffee

Create tracking-bot.coffee

error: pathspec 'scripts/tracking-bot.coffee' did not match any file(s) known to git

--- scripts/tracking-bot.coffee
+++ scripts/tracking-bot.coffee
@@ -0,0 +1,42 @@
+https = require 'https'
+http = require 'http'
+
+module.exports = (robot) ->
+  prefix = "tracking"
+  robot.hear /track (.*)|(.*)/i, (res) ->
+    tracking = res.match[1] + "|" + res.match[2]
+    key = "#{prefix}:tracking"
+    data = redis.brain.get(key) || {}
+    data[tracking] = "1"
+    redis.brain.set(key, data)
+    #var myHash = new Hash('one',[1,10,5],'two', [2], 'three',[3,30,300]);
+    #do some tracking
+  robot.hear /MD (.*)|(.*)/i, (res) -> #mark delivered
+    tracking = res.match[1] + "|" + res.match[2]
+    key = "#{prefix}:tracking"
+    data = redis.brain.get(key) || {}
+    #data.remove
+    redis.brain.set(key, data)
+    key = "#{prefix}:delivered"
+    data = redis.brain.get(key) || {}
+    data[tracking] = "2"
+    redis.brain.set(key, data)
+    #
+  robot.hear /refresh status(.*)/i, (res) ->
+    key = "#{prefix}:tracking"
+    data = redis.brain.get(key) || {}
+    for tracking, _ of data
+      #
+      key = "#{prefix}:status:#{tracking}"
+      status = redis.brain.get(key) || {}
+
+      #
+  robot.hear /note (.*)|(.*) (.*)/i, (res) ->
+    tracking = res.match[1] + "|" + res.match[2]
+    key = "#{prefix}:note:#{tracking}"
+    redis.brain.set(key, res.match[3])
+
+  robot.hear /list carriers(.*)/i, (res) ->
+    robot.logger.info "list carriers"
+
+


Cleanup vendor.coffee

Cleanup vendor.coffee

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/startae/hub.git/'


clean

clean

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/stevelacy/portal.git/'


Update specs now that syntax themes have stylesheets folders

--- spec/theme-manager-spec.coffee
+++ spec/theme-manager-spec.coffee
@@ -32,7 +32,7 @@

   describe "getImportPaths()", ->
     it "returns the theme directories before the themes are loaded", ->
-      atom.config.set('core.themes', ['atom-dark-syntax', 'atom-dark-ui', 'atom-light-ui'])
+      atom.config.set('core.themes', ['theme-with-index-less', 'atom-dark-ui', 'atom-light-ui'])

       paths = themeManager.getImportPaths()

@@ -67,8 +67,8 @@
       atom.config.set('core.themes', [])
       expect($('style.theme').length).toBe 0

-      # atom-dark-ui has an directory path, the syntax ones dont.
-      atom.config.set('core.themes', ['atom-light-syntax', 'atom-dark-ui', 'atom-dark-syntax'])
+      # atom-dark-ui has an directory path, the syntax one doesn't
+      atom.config.set('core.themes', ['theme-with-index-less', 'atom-dark-ui'])
       importPaths = themeManager.getImportPaths()
       expect(importPaths.length).toBe 1
       expect(importPaths[0]).toContain 'atom-dark-ui'


Add timeout

Add timeout

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/skgcorp/swf.git/'


remove time stuff

remove time stuff

--- worker.coffee
+++ worker.coffee
@@ -31,7 +31,7 @@
       return callback() unless result?

       [queueName, jobStr] = result
-      @processJobStr jobStr, Date.now(), callback
+      @processJobStr jobStr, callback

   parseJob: (jobStr, callback) =>
     try
@@ -39,17 +39,15 @@
     catch error
       callback error

-  processJobStr: (jobStr, time, callback) =>
+  processJobStr: (jobStr, callback) =>
     @parseJob jobStr, (error, job) =>
       return callback error if error?

-      @processJob job, time, callback
+      @processJob job, callback

-  processJob: (job, time, callback) =>
+  processJob: (job, callback) =>
     {auth,message,http} = job
     {uuid,token} = auth
-    message.payload.times.http = http
-    message.payload.times.worker = time

     authDevice uuid, token, (error, device) =>
       return callback error if error?


Only pre-require core packages if we're generating a snapshot

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/stinsonga/atom.git/'


added optout handler test file

added optout handler test file


reduce flickering during map bounds changes

--- app/assets/javascripts/main.coffee
+++ app/assets/javascripts/main.coffee
@@ -1,12 +1,8 @@
 class MainController extends SimpleMVC.Controller
     _navigateToNewBounds: () =>
-        # Clear existing markers and info windows if needed.
-        if this._locations?
-            for i in this._locations
-                i.marker.setMap null
-            this._locations.length = 0
-        else
-            this._locations = []
+        # Set not seen flag so we know which ones to remove later
+        for i in this._locations
+            i.notSeen = true

         mapBounds = this._map.getBounds()
         mapNE = mapBounds.getNorthEast()
@@ -16,31 +12,48 @@
         self = this
         query.done (data) ->
             for i in data
-                # TODO: ick. Use views for this.
-                checked = ""
-                if i.pin_enabled == "true"
-                    checked = "checked"
-                windowContents = '
' +
-                    '
' + i.name + '
' +
-                    '
<address>' + i.address + '</address>
' +
-                    '
<input type="checkbox" id="pinEnabled" value="true" ' + checked  + ' disabled />business has PIN pad
' +
-                    '
report errors

'
+                notExists = true
+                for j in self._locations
+                    if i.id == j.id
+                        i.notSeen = false
+                        notExists = false
+
+                if notExists
+                    # TODO: ick. Use views for this.
+                    checked = ""
+                    if i.pin_enabled == "true"
+                        checked = "checked"
+                    windowContents = '
' +
+                        '
' + i.name + '
' +
+                        '
<address>' + i.address + '</address>
' +
+                        '
<input type="checkbox" id="pinEnabled" value="true" ' + checked  + ' disabled />business has PIN pad
' +
+                        '
report errors

'

-                newMarker = {
-            	    marker: new google.maps.Marker({
-            	        position: new google.maps.LatLng(i.lat, i.lng),
-            	        map: self._map
-            	    }),
-            	    infoWindow: new google.maps.InfoWindow({
-            	        content: windowContents
-            	    })
-                }
-                aMarker = newMarker.marker
-                aMarker._____refToSelf = newMarker
-                google.maps.event.addListener aMarker, "click", () ->
-                    this._____refToSelf.infoWindow.open self._map, this._____refToSelf.marker
-                self._locations.push newMarker
-
+                    newMarker = {
+                        marker: new google.maps.Marker({
+                            position: new google.maps.LatLng(i.lat, i.lng),
+                            map: self._map
+                        }),
+                        infoWindow: new google.maps.InfoWindow({
+                            content: windowContents
+                        }),
+                        notSeen: false
+                    }
+                    aMarker = newMarker.marker
+                    aMarker._____refToSelf = newMarker
+                    google.maps.event.addListener aMarker, "click", () ->
+                        this._____refToSelf.infoWindow.open self._map, this._____refToSelf.marker
+                    self._locations.push newMarker
+
+            # Remove unseen items from list.
+            tmp = []
+            for i in self._locations
+                if not i.notSeen
+                    tmp.push i
+                else
+                    i.marker.setMap null
+            self._locations = tmp
+
             if self._handlePossibleAdd
                 self._handlePossibleAdd = false
                 found = false


Added 'Classic Algorithms' level section

--- app/views/play/MainPlayView.coffee
+++ app/views/play/MainPlayView.coffee
@@ -192,6 +192,44 @@
         levelPath: 'ladder'
       }
     ]
+
+    classicAlgorithms = [
+      {
+        name: 'Bubble Sort Bootcamp Battle'
+        difficulty: 3
+        id: 'bubble-sort-bootcamp-battle'
+        image: '/file/db/level/525ef8ef06e1ab0962000003/commanding_followers_icon.png'
+        description: 'Write a bubble sort to organize your soldiers. - by Alexandru Caciulescu'
+      }
+      {
+        name: 'Ogres of Hanoi'
+        difficulty: 3
+        id: 'ogres-of-hanoi'
+        image: '/file/db/level/526fd3043c637ece50001bb2/the_herd_icon.png'
+        description: 'Transfer a stack of ogres while preserving their honor. - by Alexandru Caciulescu'
+      }
+      {
+        name: 'Danger! Minefield'
+        difficulty: 3
+        id: 'danger-minefield'
+        image: '/file/db/level/526bda3fe79aefde2a003e36/mobile_artillery_icon.png'
+        description: 'Learn how to find prime numbers while defusing mines! - by Alexandru Caciulescu'
+      }
+      {
+        name: 'K-means++ Cluster Wars'
+        difficulty: 4
+        id: 'k-means-cluster-wars'
+        image: '/file/db/level/525ef8ef06e1ab0962000003/commanding_followers_icon.png'
+        description: 'Learn cluster analysis while leading armies into battle! - by Alexandru Caciulescu'
+      }
+      {
+        name: 'Quicksort the Spiral'
+        difficulty: 3
+        id: 'quicksort-the-spiral'
+        image: '/file/db/level/525ef8ef06e1ab0962000003/commanding_followers_icon.png'
+        description: 'Learn Quicksort while sorting a spiral of ogres! - by Alexandru Caciulescu'
+      }
+    ]

     playerCreated = [
       {
@@ -221,41 +259,6 @@
         id: 'coin-mania'
         image: '/file/db/level/529662dfe0df8f0000000007/grab_the_mushroom_icon.png'
         description: 'Learn while-loops to grab coins and potions. - by Prabh Simran Singh Baweja'
-      }
-      {
-        name: 'Bubble Sort Bootcamp Battle'
-        difficulty: 3
-        id: 'bubble-sort-bootcamp-battle'
-        image: '/file/db/level/525ef8ef06e1ab0962000003/commanding_followers_icon.png'
-        description: 'Write a bubble sort to organize your soldiers. - by Alexandru Caciulescu'
-      }
-      {
-        name: 'Ogres of Hanoi'
-        difficulty: 3
-        id: 'ogres-of-hanoi'
-        image: '/file/db/level/526fd3043c637ece50001bb2/the_herd_icon.png'
-        description: 'Transfer a stack of ogres while preserving their honor. - by Alexandru Caciulescu'
-      }
-      {
-        name: 'Danger! Minefield'
-        difficulty: 3
-        id: 'danger-minefield'
-        image: '/file/db/level/526bda3fe79aefde2a003e36/mobile_artillery_icon.png'
-        description: 'Learn how to find prime numbers while defusing mines! - by Alexandru Caciulescu'
-      }
-      {
-        name: 'K-means++ Cluster Wars'
-        difficulty: 4
-        id: 'k-means-cluster-wars'
-        image: '/file/db/level/525ef8ef06e1ab0962000003/commanding_followers_icon.png'
-        description: 'Learn cluster analysis while leading armies into battle! - by Alexandru Caciulescu'
-      }
-      {
-        name: 'Quicksort the Spiral'
-        difficulty: 3
-        id: 'quicksort-the-spiral'
-        image: '/file/db/level/525ef8ef06e1ab0962000003/commanding_followers_icon.png'
-        description: 'Learn Quicksort while sorting a spiral of ogres! - by Alexandru Caciulescu'
       }
       {
         name: 'Find the Spy'
@@ -291,6 +294,7 @@
       {id: 'beginner', name: 'Beginner Campaign', description: '... in which you learn the wizardry of programming.', levels: tutorials}
       {id: 'multiplayer', name: 'Multiplayer Arenas', description: '... in which you code head-to-head against other players.', levels: arenas}
       {id: 'dev', name: 'Random Harder Levels', description: '... in which you learn the interface while doing something a little harder.', levels: experienced}
+      {id: 'classic' ,name: 'Classic Algorithms', description: '... in which you learn the most popular algorithms in Computer Science.', levels: classicAlgorithms}
       {id: 'player_created', name: 'Player-Created', description: '... in which you battle against the creativity of your fellow Artisan Wizards.', levels: playerCreated}
     ]
     context.levelStatusMap = @levelStatusMap


Added WorldMapView ambient sounds.

Added WorldMapView ambient sounds.

--- app/views/play/WorldMapView.coffee
+++ app/views/play/WorldMapView.coffee
@@ -33,9 +33,13 @@
     @listenToOnce @sessions, 'sync', @onSessionsLoaded
     @getLevelPlayCounts()
     $(window).on 'resize', @onWindowResize
+    @playAmbientSound()

   destroy: ->
     $(window).off 'resize', @onWindowResize
+    if ambientSound = @ambientSound
+      # Doesn't seem to work; stops immediately.
+      createjs.Tween.get(ambientSound).to({volume: 0.0}, 1500).call -> ambientSound.stop()
     super()

   getLevelPlayCounts: ->
@@ -155,6 +159,19 @@
     resultingMarginX = (pageWidth - resultingWidth) / 2
     resultingMarginY = (pageHeight - resultingHeight) / 2
     @$el.find('.map').css(width: resultingWidth, height: resultingHeight, 'margin-left': resultingMarginX, 'margin-top': resultingMarginY)
+
+  playAmbientSound: ->
+    return if @ambientSound
+    terrain = 'Grass'
+    return unless file = {Dungeon: 'ambient-map-dungeon', Grass: 'ambient-map-grass'}[terrain]
+    src = "/file/interface/#{file}#{AudioPlayer.ext}"
+    unless AudioPlayer.getStatus(src)?.loaded
+      AudioPlayer.preloadSound src
+      Backbone.Mediator.subscribeOnce 'audio-player:loaded', @playAmbientSound, @
+      return
+    @ambientSound = createjs.Sound.play src, loop: -1, volume: 0.1
+    createjs.Tween.get(@ambientSound).to({volume: 1.0}, 1000)
+

 tutorials = [
   {


Added support for 'codeLanguage' when setting the 'favoriteLanguage'

--- app/views/user/MainUserView.coffee
+++ app/views/user/MainUserView.coffee
@@ -9,7 +9,7 @@
   model: LevelSession

   constructor: (userID) ->
-    @url = "/db/user/#{userID}/level.sessions?project=state.complete,levelID,levelName,changed,team,submittedCodeLanguage,totalScore&order=-1"
+    @url = "/db/user/#{userID}/level.sessions?project=state.complete,levelID,levelName,changed,team,codeLanguage,submittedCodeLanguage,totalScore&order=-1"
     super()

 module.exports = class MainUserView extends UserView
@@ -30,7 +30,9 @@
           multiPlayerSessions.push levelSession
         else
           singlePlayerSessions.push levelSession
-        languageCounts[levelSession.get 'submittedCodeLanguage'] = (languageCounts[levelSession.get 'submittedCodeLanguage'] or 0) + 1
+        language = levelSession.get('codeLanguage') or levelSession.get('submittedCodeLanguage')
+        if language
+          languageCounts[language] = (languageCounts[language] or 0) + 1
       mostUsedCount = 0
       favoriteLanguage = null
       for language, count of languageCounts


feat(service): add option for raw md5 hash to be passed as src

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/PeterDaveHello/angular-gravatar.git/'


Clean up deferred package activation

Clean up deferred package activation

- Eliminate @deferActivation ivar
- Remove activation event listeners when deactivating unactivated packages

--- src/app/atom-package.coffee
+++ src/app/atom-package.coffee
@@ -15,7 +15,6 @@
   mainModulePath: null
   resolvedMainModulePath: false
   mainModule: null
-  deferActivation: false

   load: ->
     try
@@ -24,7 +23,7 @@
       @loadStylesheets()
       @loadGrammars()
       @loadScopedProperties()
-      if @deferActivation = @metadata.activationEvents?
+      if @metadata.activationEvents?
         @registerDeferredDeserializers()
       else
         @requireMainModule()
@@ -38,7 +37,7 @@
     syntax.addGrammar(grammar) for grammar in @grammars
     syntax.addProperties(path, selector, properties) for [path, selector, properties] in @scopedProperties

-    if @deferActivation and not immediate
+    if @metadata.activationEvents? and not immediate
       @subscribeToActivationEvents()
     else
       @activateNow()
@@ -96,6 +95,7 @@
       console.error "Error serializing package '#{@name}'", e.stack

   deactivate: ->
+    @unsubscribeFromActivationEvents()
     syntax.removeGrammar(grammar) for grammar in @grammars
     syntax.removeProperties(path) for [path] in @scopedProperties
     keymap.remove(path) for [path] in @keymaps
@@ -123,25 +123,23 @@

   subscribeToActivationEvents: () ->
     return unless @metadata.activationEvents?
+    if _.isArray(@metadata.activationEvents)
+      rootView.command(event, @handleActivationEvent) for event in @metadata.activationEvents
+    else
+      rootView.command(event, selector, @handleActivationEvent) for event, selector of @metadata.activationEvents

-    activateHandler = (event) =>
-      bubblePathEventHandlers = @disableEventHandlersOnBubblePath(event)
-      @deferActivation = false
-      @activateNow()
-      $(event.target).trigger(event)
-      @restoreEventHandlersOnBubblePath(bubblePathEventHandlers)
-      @unsubscribeFromActivationEvents(activateHandler)
+  handleActivationEvent: (event) =>
+    bubblePathEventHandlers = @disableEventHandlersOnBubblePath(event)
+    @activateNow()
+    $(event.target).trigger(event)
+    @restoreEventHandlersOnBubblePath(bubblePathEventHandlers)
+    @unsubscribeFromActivationEvents()

+  unsubscribeFromActivationEvents: ->
     if _.isArray(@metadata.activationEvents)
-      rootView.command(event, activateHandler) for event in @metadata.activationEvents
+      rootView.off(event, @handleActivationEvent) for event in @metadata.activationEvents
     else
-      rootView.command(event, selector, activateHandler) for event, selector of @metadata.activationEvents
-
-  unsubscribeFromActivationEvents: (activateHandler) ->
-    if _.isArray(@metadata.activationEvents)
-      rootView.off(event, activateHandler) for event in @metadata.activationEvents
-    else
-      rootView.off(event, selector, activateHandler) for event, selector of @metadata.activationEvents
+      rootView.off(event, selector, @handleActivationEvent) for event, selector of @metadata.activationEvents

   disableEventHandlersOnBubblePath: (event) ->
     bubblePathEventHandlers = []


Don't respond to observe events when the editor value doesn't change

--- src/app/config-panel.coffee
+++ src/app/config-panel.coffee
@@ -37,6 +37,8 @@
         type = editor.attr('type')

         @observeConfig name, (value) ->
+          return if value?.toString() == editor.getText()
+          value ?= ""
           editor.setText(value.toString())

         editor.getBuffer().on 'contents-modified', ->


add error return msg

add error return msg


Prototype compiler

Prototype compiler

error: pathspec 'src/core/modules/data.coffee' did not match any file(s) known to git

--- src/core/modules/data.coffee
+++ src/core/modules/data.coffee
@@ -0,0 +1,23 @@
+
+#
+# Insane hack to compress large 2D data tables.
+#
+# http://jsperf.com/big-data-matrix
+# As of 31 Oct 2014, for a 10000 row, 100 column table in Chrome,
+#   retained memory sizes:
+# raw json: 31,165 KB
+# array of objects: 41,840 KB
+# array of arrays: 14,960  KB
+# array of prototyped instances: 4,160 KB
+
+_prototypeId = 0
+nextPrototypeName = -> "Dyna#{++_prototypeId}"
+createCompiledPrototype = (attrs) ->
+  params = ( "a#{i}" for attr, i in attrs )
+  inits = ( "this[#{JSON.stringify attr}]=a#{i};" for attr, i in attrs )
+
+  prototypeName = nextPrototypeName()
+  (new Function "function #{prototypeName}(#{params.join ','}){#{inits.join ''}} return #{prototypeName};")()
+
+Flow.Data =
+  createCompiledPrototype: createCompiledPrototype


indentation error

indentation error


bugfixes re: button state

bugfixes re: button state

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/bmedx/modulestore.git/'


Improve Documentation

Improve Documentation

--- src/fairy.coffee
+++ src/fairy.coffee
@@ -209,6 +209,8 @@
   #   to ensure sequential processing for all tasks of the same group (aka.
   #   first-come-first-serve). Current time is appended at the argument array
   #   for statistics. A callback is optional.
+  #
+  # **Usage:**
   #
   #     queue.enqueue 'param1', 'param2', -> console.log 'queued!'
   #     queue.enqueue 'param1', 'param2'
@@ -237,9 +239,9 @@

   # ### Poll New Task

-  # If any task presents in the `SOURCE` list, `lpop` from `SOURCE`
-  # (`rpush`) into `QUEUED`. The `lpop` and `rpush` are protected by a
-  # transaction.
+  # **Private** method. If any task presents in the `SOURCE` list, `lpop` from
+  # `SOURCE` (`rpush`) into `QUEUED`. The `lpop` and `rpush` are protected by
+  # a transaction.
   #
   # Since the task being popped and pushed should be known in prior of the
   # begin of the transaction (aka, the `multi` command), we need to get the
@@ -271,8 +273,8 @@

   # ### Process First Tasks of Each Group

-  # The real job is done by the passed in `handler` of `regist` method, when
-  # the job is:
+  # **Private** method. The real job is done by the passed in `handler` of
+  # `regist`ered method, when the job is:
   #
   #   * **successed**, pop the finished job from the group queue, and:
   #     + continue process task of the same group if there's pending job(s) in
@@ -348,7 +350,7 @@

   # ### Continue Process a Group

-  # **Private Method** Upon successful execution of a task, or skipping a
+  # **Private** method. Upon successful execution of a task, or skipping a
   # failed task:
   #
   #   1. `lpop` the current task from `QUEUED` list.
@@ -370,6 +372,12 @@

   # ### Re-Schedule Failed and Blocked Tasks

+  # Requeue the failed and blocked tasks into `SOURCE` list. Useful for failure
+  # recovery. **Usage:**
+  #
+  #     queue.reschedule () ->
+  #       console.log 'reschedule successed'
+  #
   #   1. Requeue tasks in the `FAILED` list into `SOURCE` list, and,
   #   2. Pop all blocked tasks (`QUEUED` lists listed in the `BLOCKED` set,
   #   without first task of each list, because that's the failed task
@@ -431,9 +439,7 @@
   # ### Get Recently Finished Tasks Asynchronously
   #
   # Recently finished tasks (up to a limited size) will be stored in the
-  # `RECENT` list in the reverse order of finished time.
-  #
-  # **Usage:**
+  # `RECENT` list in the reverse order of finished time. **Usage:**
   #
   #     queue.recently_finished_tasks (tasks) ->
   #       console.log "Recently finished tasks are: ", tasks
@@ -447,9 +453,7 @@

   # ### Get Failed Tasks Asynchronously
   #
-  # Failed tasks are stored in the `FAILED` list.
-  #
-  # **Usage:**
+  # Failed tasks are stored in the `FAILED` list. **Usage:**
   #
   #     queue.failed_tasks (tasks) ->
   #       console.log "#{tasks.length} tasks failed: ", tasks
@@ -462,9 +466,7 @@

   # ### Get Blocked Groups Asynchronously
   #
-  # Blocked groups' identifiers are stored in the `BLOCKED` set.
-  #
-  # **Usage:**
+  # Blocked groups' identifiers are stored in the `BLOCKED` set. **Usage:**
   #
   #     queue.blocked_groups (groups) ->
   #       console.log "#{groups.length} groups blocked: ", groups
@@ -478,9 +480,7 @@
   # ### Get Slowest Tasks Asynchronously
   #
   # Slowest tasks are tasks stored in the `SLOWEST` ordered set, which will be
-  # limited to a maximum size default to 10.
-  #
-  # **Usage:**
+  # limited to a maximum size default to 10. **Usage:**
   #
   #     queue.slowest_tasks (tasks) ->
   #       console.log "Slowest tasks are: ", tasks
@@ -497,9 +497,7 @@
   # ### Get Currently Processing Tasks Asynchronously
   #
   # Currently processing tasks are tasks in the `RECENT` list, which will be
-  # limited to a maximum size defaults to 10.
-  #
-  # **Usage:**
+  # limited to a maximum size defaults to 10. **Usage:**
   #
   #     queue.processing_tasks (tasks) ->
   #       console.log "#{tasks.length} tasks being processing: ", tasks


Re-ordering fairy.coffee components

Re-ordering fairy.coffee components

--- src/fairy.coffee
+++ src/fairy.coffee
@@ -29,6 +29,11 @@
 # Copyright 2012, Baoshan Sheng, Released under the MIT License

 # ## Fairy Explained
+
+# `Fairy` relies on `node-uuid` to generate unique identifiers for tasks and
+# `redis` driver, of course!
+uuid       = require 'node-uuid'
+redis      = require 'redis'

 # ### CommonJS Module Definition
 #
@@ -46,14 +51,9 @@
   client.auth options.password if options.password?
   new Fairy client

-# `Fairy` relies on `node-uuid` to generate unique identifiers for tasks and
-# `redis` driver, of course!
-#
 # Prefix `FAIRY` is applied to all Redis keys for safety and ease-of-management.
 #
 # `QUEUES` is a Redis set containing names of all registered queues.
-uuid       = require 'node-uuid'
-redis      = require 'redis'
 prefix     = 'FAIRY'
 key_queues = "#{prefix}:QUEUES"


ApiGenerator: use docGen to get description of methods, classes


ignoring year for blank album names

ignoring year for blank album names

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/Qbuer/groovebasin.git/'


remove cookie

remove cookie


No reset of scores when session resubmit

--- server/queues/scoring.coffee
+++ server/queues/scoring.coffee
@@ -292,7 +292,7 @@
     submitDate: new Date()
     meanStrength: 25
     standardDeviation: 25/3
-    totalScore: 10
+    #totalScore: 10 #this should be a fun experiment
     numberOfWinsAndTies: 0
     numberOfLosses: 0
     isRanking: true
@@ -495,7 +495,6 @@
 fetchLevelSession = (callback) ->
   findParameters =
     _id: @clientResponseObject.originalSessionID
-  console.log "Find parameters are",findParameters

   query = LevelSession
   .findOne(findParameters)
@@ -591,7 +590,6 @@
   opponentsArray = _.toArray opponentsClone
   currentMatchObject.opponents = opponentsArray
   LevelSession.findOne {"_id": sessionID}, (err, session) ->
-    console.log "Updated session #{sessionID}"
     session = session.toObject()
     currentMatchObject.playtime = session.playtime ? 0
     sessionUpdateObject =


OAuth: put fixed protocol for now, this going to be changed