pointless commit

pointless commit

--- client/app/Applications/Shell.kdapplication/AppController.coffee
+++ client/app/Applications/Shell.kdapplication/AppController.coffee
@@ -47,6 +47,7 @@
       for diff in (item while (item = _orderedMessages[i++])?)
         # console.log "updating screen with:",diff
         currentScreen = (@dmp.patch_apply diff,@lastScreen)[0]
+        # currentScreen = diff
         @getView().updateScreen(currentScreen)
         @lastScreen = currentScreen
         @_lastMessageProcessed = i-1


Changed server so that it will send a new test to client once its first test has completed, rather than using a round-robin configuration as was being used before.

--- src/main/coffeescript/scxml/test/multi-process/server.coffee
+++ src/main/coffeescript/scxml/test/multi-process/server.coffee
@@ -109,7 +109,7 @@

 			process.exit results.testCount == results.testsPassed

-		processMessage = (jsonResults) ->
+		processMessage = (jsonResults,p) ->

 			if jsonResults.results.pass
 				results.testsPassed.push testMap[jsonResults.testId].test
@@ -124,15 +124,13 @@
 					finish()

 			#send next test
-			p = clientProcesses.shift()
-			clientProcesses.push p	#push this process at the end of the list, so we do a round-robin
 			sendTest p

 		hookUpEventHandling = (p) ->
 			buff = new BufferedStream p.stdout
 			buff.on "line",(line) ->
 				jsonResults = JSON.parse line
-				processMessage jsonResults
+				processMessage jsonResults,p

 			#if verbose flag is set, log output of running processes
 			if verbose
@@ -158,6 +156,8 @@
 		console.log "starting clients"
 		clientProcesses = (startClient address for address in clientAddresses)

+		console.log "spawned client processes",(p.pid for p in clientProcesses)
+
 		startTime = startTime or new Date()

 		console.log "start time",startTime
@@ -167,4 +167,3 @@
 			hookUpEventHandling p
 			sendTest p

-


Added tracking for DJs and media plus methods built off of that data for getting audience

--- src/room.coffee
+++ src/room.coffee
@@ -1,6 +1,8 @@
 class Room
 	constructor: ()->
 		@users = {}
+		@djs = {}
+		@media = {}

 	addUser: (user)=>
 		@users[user.id] = user
@@ -8,6 +10,26 @@
 	remUser: (user)=>
 		delete @users[user.id]

-	getUsers: ()=> return @users
+	setDjs: (djs)=>
+		@djs = {}
+		for dj in djs
+			@djs[dj.user.id] = dj.user
+
+	setMedia: (media)=>
+		@media = media
+
+	getUsers: ()=>
+		return @users
+
+	getDjs: ()=> @djs
+
+	getAudience: ()=>
+		audience = []
+		for id,user of @users
+			if id not in Object.keys(@djs)
+				audience.push user
+		return audience
+
+	getMedia: ()=> @media

 module.exports = Room


.display

.display

--- highlanders/src/commands.coffee
+++ highlanders/src/commands.coffee
@@ -2,12 +2,12 @@
     {addCommand, authMaintainer: maintainer, authRegistered: registered} = hlr

     addCommand 'hlrcommands', ->
-        list = hlr.commandList("Highlanders Commands").add([
+        hlr.commandList("Highlanders Commands").add([
             ["register", "Registers a Highlanders account for this name. The account is bound to your name, not your IP."]
             ["location", "Shows your current location. Aliases: l, loc"]
             ["go", "Go to that location. Aliases: g, goto", ["location"]]
             ["fish", "Fish in locations that allow it. Also used to choose your rod toss direction.", ["direction"]]
-        ]).finish().render(@src, @chan)
+        ]).finish().display(@src, @chan)

     addCommand 'register', ->
         if hlr.player.registered(@src)


:bug: Fix a weird bug with EditorLinter::_lock It was setting this[true] = true and this[false] = false for some reasons, changing it to this seemed to work

--- lib/editor-linter.coffee
+++ lib/editor-linter.coffee
@@ -90,7 +90,11 @@

   # This method sets or gets the lock status of given type
   _lock: (wasTriggeredOnChange, value) ->
-    key = wasTriggeredOnChange ? '_inProgressFly' : '_inProgress'
+    key =
+      if wasTriggeredOnChange
+        '_inProgressFly'
+      else
+        '_inProgress'
     if typeof value is 'undefined'
       @[key]
     else


Tests: Click link in activity.

Tests: Click link in activity.

--- tests/src/helpers/helpers.coffee
+++ tests/src/helpers/helpers.coffee
@@ -181,7 +181,7 @@
     browser
       .click                  '[testpath="public-feed-link/Activity/Topic/public"]'
       .waitForElementVisible  '[testpath=ActivityInputView]', 10000
-      .click                  '[testpath="ActivityTabHandle-/Activity/Public/Recent"]'
+      .click                  '[testpath="ActivityTabHandle-/Activity/Public/Recent"] a'
       .waitForElementVisible  '.most-recent [testpath=activity-list]', 30000
       .click                  '[testpath=ActivityInputView]'
       .setValue               '[testpath=ActivityInputView]', post


Fix the sendMessage with nothing after it being left in

--- packages/rocketchat-importer-slack/server/SlackImporter.coffee
+++ packages/rocketchat-importer-slack/server/SlackImporter.coffee
@@ -193,7 +193,7 @@
 												else if message.subtype is 'me_message'
 													RocketChat.sendMessage @getRocketUser(message.user), { msg: '_' + @convertSlackMessageToRocketChat(message.text) + '_', ts: new Date(parseInt(message.ts.split('.')[0]) * 1000) }, room
 												else if message.subtype is 'bot_message'
-													RocketChat.sendMessage
+													#RocketChat.sendMessage
 												else
 													if not missedTypes[message.subtype]
 														missedTypes[message.subtype] = message


Fix time stuffs

Fix time stuffs

--- resources/assets/coffee/react/profile-page/account-standing.coffee
+++ resources/assets/coffee/react/profile-page/account-standing.coffee
@@ -82,7 +82,9 @@

         td
           className: "#{bn}__table-cell #{bn}__table-cell--date"
-          time className: "timeago", dateTime: event.timestamp
+          time
+            className: "timeago", dateTime: event.timestamp
+            moment(event.timestamp).fromNow()

         td
           className: "#{bn}__table-cell #{bn}__table-cell--action"
@@ -99,7 +101,7 @@
           else if event.type == 'note'
             ''
           else
-            moment(event.timestamp).add(event.length, 'seconds').from(event.timestamp, true)
+            moment.duration(event.length, 'seconds').humanize()

         td
           className: "#{bn}__table-cell #{bn}__table-cell--description"


account/shortcuts: move shortcuts nav item to the bottom of the list

--- client/account/lib/index.coffee
+++ client/account/lib/index.coffee
@@ -32,7 +32,6 @@
       items  : [
         { slug : 'Profile',   title : "User profile",        listType: "username" }
         { slug : 'Email',     title : "Email notifications", listType: "emailNotifications" }
-        { slug : 'Shortcuts', title : 'Shortcuts',           listType: 'shortcuts' }
       ]
     billing :
       title : "Billing"
@@ -45,6 +44,7 @@
         { slug : 'SSH',         title : "SSH keys",           listHeader: "Your SSH Keys",          listType: "keys" }
         # { slug : 'Keys',        title : "Koding Keys",        listHeader: "Your Koding Keys",       listType: "kodingKeys" }
         { slug : 'Referral',    title : "Referral System",    listHeader: "Your Referral Options",  listType: "referralSystem" }
+        { slug : 'Shortcuts', title : 'Shortcuts',           listType: 'shortcuts' }
         # { slug : 'Credentials', title : "Credentials",        listHeader: "Your Credentials",       listType: "credentials" }
       ]
     danger  :


ide: fix toggle sidebar state problem

ide: fix toggle sidebar state problem

--- client/ide/AppController.coffee
+++ client/ide/AppController.coffee
@@ -368,6 +368,7 @@
     splitView.resizePanel 39, 0
     @getView().setClass 'sidebar-collapsed'
     floatedPanel.setClass 'floating'
+    @activeFilesPaneName = tabView.activePane.name
     tabView.showPaneByName 'Dummy'

     @isSidebarCollapsed = yes
@@ -409,7 +410,7 @@
     @getView().unsetClass 'sidebar-collapsed'
     floatedPanel.unsetClass 'floating'
     @isSidebarCollapsed = no
-    # filesPane.tabView.showPaneByIndex 0
+    filesPane.tabView.showPaneByName @activeFilesPaneName

     # floatedPanel._lastSize = 250
     # splitView.unsetFloatingPanel 0


Log errors in requests to analytics

Log errors in requests to analytics

--- services/web/app/coffee/Features/Analytics/AnalyticsManager.coffee
+++ services/web/app/coffee/Features/Analytics/AnalyticsManager.coffee
@@ -9,7 +9,10 @@
 	if settings.apis?.analytics?.url?
 		urlPath = opts.url
 		opts.url = "#{settings.apis.analytics.url}#{urlPath}"
-		request(opts)
+		request opts, (err) ->
+			if err?
+				logger.err { err: err }, 'Request to analytics failed'
+
 		callback() # Do not wait for all the attempts
 	else
 		callback(new Errors.ServiceNotConfiguredError('Analytics service not configured'))


Support values other than objects in the numKeys filter, returning zero if so.

--- services/web/public/coffee/ide/review-panel/filters/numKeys.coffee
+++ services/web/public/coffee/ide/review-panel/filters/numKeys.coffee
@@ -2,4 +2,8 @@
 	"base"
 ], (App) ->
 	app.filter "numKeys", () ->
-		(object) -> Object.keys(object).length
+		(object) ->
+			if object?
+				return Object.keys(object).length
+			else
+				return 0


added parenthesis, buggaz

added parenthesis, buggaz

--- core/app/backbone/views/autocompleted_add_to_channel_view.coffee
+++ core/app/backbone/views/autocompleted_add_to_channel_view.coffee
@@ -50,9 +50,9 @@
   parseKeyDown: (e) ->
     @_proceed = false
     switch e.keyCode
-      when 13 then @addCurrentlySelectedChannel
-      when 40 then @_auto_completes_view.moveSelectionDown
-      when 38 then @_auto_completes_view.moveSelectionUp
+      when 13 then @addCurrentlySelectedChannel()
+      when 40 then @_auto_completes_view.moveSelectionDown()
+      when 38 then @_auto_completes_view.moveSelectionUp()
       when 27 then @completelyDisappear()
       else @_proceed = true


Added angled collision between ball and paddle

--- src/script/GameplayState.coffee
+++ src/script/GameplayState.coffee
@@ -56,7 +56,9 @@
   update: () ->
     @square.body.position.x = Math.max(Math.min(game.input.activePointer.x, 540), 20)

-    game.physics.arcade.overlap(@ball, @square, @collideY)
+    game.physics.arcade.overlap(@ball, @square, (ball, paddle) ->
+      ball.body.velocity.x = 400 * Math.cos(Math.PI + (Math.PI * (ball.body.center.x - paddle.body.position.x) / paddle.body.width))
+      ball.body.velocity.y = 400 * Math.sin(Math.PI + (Math.PI * (ball.body.center.x - paddle.body.position.x) / paddle.body.width)))
     game.physics.arcade.overlap(@ball, @wallTop, @collideY)
     game.physics.arcade.overlap(@ball, @wallLeft, @collideX)
     game.physics.arcade.overlap(@ball, @wallRight, @collideX)


Adapt Connect's static provider code, including streaming the static file.

--- lib/staticHandler.coffee
+++ lib/staticHandler.coffee
@@ -1,8 +1,80 @@
+###
+ * A large portion of the code in this file is adapted from:
+ * Connect - staticProvider
+ * Copyright(c) 2010 Sencha Inc.
+ * Copyright(c) 2011 TJ Holowaychuk
+ * MIT Licensed
+ *
+ * The overall file is
+ * Copyright(c) 2012 Randy McLaughlin
+ * MIT Licensed
+ *
+###
+
 fs = require('fs')
+mime = require('mime')
+connect = require('connect')
+utils = connect.utils

 exports= module.exports= staticHandler= (req,res,next)->
-  fs.readFile req.malifi.path.full, (err,data)->
-    if err
-      return next()
-    res.setHeader 'Content-Type', 'text/plain'
-    res.end(data)
+  path= req.malifi.path.full
+  fs.stat path, (err, stat) ->
+    if err?
+      return if 'ENOENT' == err.code then next() else next(err)
+    else
+      ###
+      todo: // redirect directory in case index.html is present
+      } else if (stat.isDirectory()) {
+        if (!redirect) return next();
+        res.statusCode = 301;
+        res.setHeader('Location', url.pathname + '/');
+        res.end('Redirecting to ' + url.pathname + '/');
+        return;
+      }
+      ###
+
+      type = mime.lookup(path)
+
+      # header fields
+      unless res.getHeader('Date')
+        res.setHeader('Date', new Date().toUTCString())
+      #todo: unless res.getHeader('Cache-Control') res.setHeader('Cache-Control', 'public, max-age=' + (maxAge / 1000))
+      unless res.getHeader('Last-Modified')
+        res.setHeader('Last-Modified', stat.mtime.toUTCString())
+      unless res.getHeader('ETag')
+        res.setHeader('ETag', utils.etag(stat))
+      unless res.getHeader('content-type')
+        charset = mime.charsets.lookup(type)
+        res.setHeader('Content-Type', type + (if charset then " charset=#{charset}" else ''))
+      res.setHeader('Accept-Ranges', 'bytes')
+
+      # conditional GET support
+      if utils.conditionalGET(req)
+        unless utils.modified(req, res)
+          req.emit('static')
+          return utils.notModified(res)
+
+      opts = {}
+      chunkSize = stat.size
+
+      if ranges = req.headers.range
+        if ranges = utils.parseRange(stat.size, ranges)
+          #valid
+          # (connect)TODO: stream options
+          # (connect)TODO: multiple support
+          opts.start = ranges[0].start
+          opts.end = ranges[0].end
+          chunkSize = opts.end - opts.start + 1
+          res.statusCode = 206
+          res.setHeader('Content-Range', "bytes #{opts.start}-#{opts.end}/#{stat.size}")
+
+      res.setHeader('Content-Length', chunkSize)
+
+      # transfer
+      if 'HEAD' == req.method
+        return res.end()
+
+      # stream
+      stream = fs.createReadStream(path, opts)
+      req.emit('static', stream)
+      stream.pipe(res)


unescape query string in cache file

unescape query string in cache file

--- server/cache.coffee
+++ server/cache.coffee
@@ -8,6 +8,7 @@
 moment         = require('moment')
 {EventEmitter} = require 'events'
 ReadWriteLock = require('rwlock')
+querystring = require 'querystring'
 cacheBase = '/tmp/cache'
 exports.cachePath = cachePath = (path, next) ->

@@ -16,6 +17,7 @@
     path = pathUtil.join path, 'index.html'
   path = pathUtil.join cacheBase, path
   path = path.replace(/[:?"*<>|]/g, '_') # remove illegal character under windows
+  path = querystring.unescape(path)
   dir = pathUtil.dirname path
   name = pathUtil.basename path
   # ext = pathUtil.extname name


New type: VM-snapshot.

New type: VM-snapshot.

--- src/spec.coffee
+++ src/spec.coffee
@@ -323,6 +323,8 @@
       VM:

         test: (value) ->
+          # Note: all snapshots are also marked as “templates” (i.e.
+          # not startable), there is no need to filter them out.
           value.$type is @rule.name and
             not value.is_control_domain and
             not value.is_a_template
@@ -456,6 +458,12 @@
         test: (value) ->
           value.$type is 'VM' and value.is_control_domain

+      'VM-snapshot':
+        extends: 'VM'
+
+        test: (value) ->
+          value.$type is 'VM' and value.is_a_snapshot
+
       'VM_metrics':

         test: test


test/ide/file: update for teams

test/ide/file: update for teams

--- client/test/lib/ide/file.coffee
+++ client/test/lib/ide/file.coffee
@@ -1,132 +1,123 @@
 helpers    = require '../helpers/helpers.js'
 ideHelpers = require '../helpers/idehelpers.js'
-
+utils = require '../utils/utils.js'
+async = require 'async'
+teamsHelpers = require '../helpers/teamshelpers.js'

 module.exports =

+  before: (browser, done) ->

-  openFile: (browser) ->
+    ###
+    * we are creating users list here to send invitation and join to team
+    * so we will be able to run our test for different kind of member role
+    ###
+    targetUser1 = utils.getUser no, 1
+    targetUser1.role = 'member'

-    user = helpers.beginTest(browser)
-    helpers.waitForVMRunning(browser)
-    ideHelpers.openFileFromWebFolder(browser, user)
-    browser.end()
+    users = [
+      targetUser1
+    ]
+
+    queue = [
+      (next) ->
+        teamsHelpers.inviteAndJoinWithUsers browser, users, (result) ->
+          next null, result
+      (next) ->
+        teamsHelpers.buildStack browser, (res) ->
+          next null, res
+
+      # go to IDE url
+      (next) ->
+        teamUrl = helpers.getUrl yes
+        url = "#{teamUrl}/IDE"
+        browser.url url, -> next null
+    ]
+
+    async.series queue, (err, result) ->
+      done()  unless err

-  createFileFromContextMenu: (browser) ->
+  file: (browser, done) ->
+    user = utils.getUser()

-    user = helpers.beginTest(browser)
-    helpers.waitForVMRunning(browser)
-    helpers.createFile(browser, user)
-    browser.end()
+    queue = [
+
+      # createFileFromContextMenu
+      (next) ->
+        helpers.createFile browser, user, null, null, null, (res) -> next null
+
+      # createFileFromMachineHeader
+      (next) ->
+        helpers.createFileFromMachineHeader browser, user, null, yes, (res) ->
+          next null
+
+      # deleteFile
+      (next) ->
+        filename     = helpers.createFile(browser, user)
+        configPath      = '/home/' + user.username + '/.config'
+        fileSelector = "span[title='" + configPath + '/' + filename + "']"
+        helpers.deleteFile browser, fileSelector, -> next null
+
+      # rename file
+      (next) ->
+        filename     = helpers.createFile(browser, user)
+        configPath      = '/home/' + user.username + '/.config'
+        fileSelector = "span[title='" + configPath + '/' + filename + "']"
+
+        paragraph        = helpers.getFakeText()
+        newFileName      = paragraph.split(' ')[0] + '.txt'
+        newFileSelector  = "span[title='" + configPath + '/' + newFileName + "']"
+
+        browser
+          .waitForElementPresent     fileSelector, 20000
+          .click                     fileSelector
+          .click                     fileSelector + ' + .chevron'
+          .waitForElementVisible     'li.rename', 20000
+          .click                     'li.rename'
+          .waitForElementVisible     'li.selected .rename-container .hitenterview', 20000
+          .clearValue                'li.selected .rename-container .hitenterview'
+          .setValue                  'li.selected .rename-container .hitenterview', newFileName + '\n'
+          .waitForElementPresent     newFileSelector, 20000
+          .pause 10, -> next null # Assertion

-  createFileFromMachineHeader: (browser) ->
+      # duplicateFile
+      (next) ->
+        filename      = helpers.createFile(browser, user)
+        newFileName   = filename.split('.txt').join('_1.txt')
+        configPath       = '/home/' + user.username + '/.config'
+        fileSelector  = "span[title='" + configPath + '/' + filename + "']"
+        newFile       = "span[title='" + configPath + '/' + newFileName + "']"

-    user = helpers.beginTest(browser)
+        browser
+          .waitForElementPresent     fileSelector, 20000
+          .click                     fileSelector
+          .click                     fileSelector + ' + .chevron'
+          .waitForElementPresent     'li.duplicate', 20000
+          .click                     'li.duplicate'
+          .pause                     2000
+          .waitForElementPresent     newFile, 20000 # Assertion

-    helpers.waitForVMRunning(browser)
+        helpers.deleteFile browser, fileSelector, ->
+          helpers.deleteFile browser, newFile, -> next null

-    helpers.createFileFromMachineHeader(browser, user)
-    browser.end()
+      # createFileAndOpen
+      (next) ->
+        fileName = helpers.createFile browser, user, null, null, null, (res) ->
+          ideHelpers.openFile browser, user, fileName, -> next null

+      # compressFileZip
+      (next) ->
+        fileName = helpers.createFile browser, user, null, null, null, (res) ->
+          ideHelpers.compressFileFolder browser, user, 'file', fileName, 'zip', -> next null

-  deleteFile: (browser) ->
+      # compressFileTarGz
+      (next) ->
+        fileName = helpers.createFile browser, user, null, null, null, (res) ->
+          ideHelpers.compressFileFolder browser, user, 'file', fileName, 'targz', -> next null
+    ]

-    user = helpers.beginTest(browser)
+    async.series queue

-    helpers.waitForVMRunning(browser)
-
-    filename     = helpers.createFile(browser, user)
-    webPath      = '/home/' + user.username + '/Web'
-    fileSelector = "span[title='" + webPath + '/' + filename + "']"
-
-    helpers.deleteFile(browser, fileSelector)
-    browser.end()
-
-
-  renameFile: (browser) ->
-
-    user = helpers.beginTest(browser)
-
-    helpers.waitForVMRunning(browser)
-
-    filename     = helpers.createFile(browser, user)
-    webPath      = '/home/' + user.username + '/Web'
-    fileSelector = "span[title='" + webPath + '/' + filename + "']"
-
-    paragraph        = helpers.getFakeText()
-    newFileName      = paragraph.split(' ')[0] + '.txt'
-    newFileSelector  = "span[title='" + webPath + '/' + newFileName + "']"
-
-    browser
-      .waitForElementPresent     fileSelector, 20000
-      .click                     fileSelector
-      .click                     fileSelector + ' + .chevron'
-      .waitForElementVisible     'li.rename', 20000
-      .click                     'li.rename'
-      .waitForElementVisible     'li.selected .rename-container .hitenterview', 20000
-      .clearValue                'li.selected .rename-container .hitenterview'
-      .setValue                  'li.selected .rename-container .hitenterview', newFileName + '\n'
-      .waitForElementPresent     newFileSelector, 20000 # Assertion
-      .end()
-
-
-  duplicateFile: (browser) ->
-
-    user = helpers.beginTest(browser)
-
-    helpers.waitForVMRunning(browser)
-
-    filename      = helpers.createFile(browser, user)
-    newFileName   = filename.split('.txt').join('_1.txt')
-    webPath       = '/home/' + user.username + '/Web'
-    fileSelector  = "span[title='" + webPath + '/' + filename + "']"
-    newFile       = "span[title='" + webPath + '/' + newFileName + "']"
-
-    browser
-      .waitForElementPresent     fileSelector, 20000
-      .click                     fileSelector
-      .click                     fileSelector + ' + .chevron'
-      .waitForElementPresent     'li.duplicate', 20000
-      .click                     'li.duplicate'
-      .pause                     2000
-      .waitForElementPresent     newFile, 20000 # Assertion
-
-    helpers.deleteFile(browser, fileSelector)
-    helpers.deleteFile(browser, newFile)
-
-    browser.end()
-
-
-  createFileAndOpen: (browser) ->
-
-    user = helpers.beginTest(browser)
-    helpers.waitForVMRunning(browser)
-
-    fileName = helpers.createFile(browser, user)
-    ideHelpers.openFile(browser, user, fileName)
-
-    browser.end()
-
-
-  compressFileZip: (browser) ->
-
-    user = helpers.beginTest(browser)
-    helpers.waitForVMRunning(browser)
-
-    fileName = helpers.createFile(browser, user)
-    ideHelpers.compressFileFolder(browser, user, 'file', fileName, 'zip')
-
-    browser.end()
-
-
-  compressFileTarGz: (browser) ->
-
-    user = helpers.beginTest(browser)
-    helpers.waitForVMRunning(browser)
-
-    fileName = helpers.createFile(browser, user)
-    ideHelpers.compressFileFolder(browser, user, 'file', fileName, 'targz')
-
-    browser.end()
+  after: (browser) -> browser.end()


Don't drop the database on start.

Don't drop the database on start.

--- server/index.coffee
+++ server/index.coffee
@@ -22,7 +22,7 @@

 mongoose = require 'mongoose'
 mongoose.connect 'mongodb://localhost:27017/educraft'
-mongoose.connection.on 'open', (con) -> mongoose.connection.db.dropDatabase()
+#mongoose.connection.on 'open', (con) -> mongoose.connection.db.dropDatabase()
 models = require('./models/models')(mongoose)

 session = require 'express-session'
@@ -80,9 +80,7 @@
     next()

 app.get '/auth/example', passport.authenticate('oauth2', scope: 'read')
-
-app.get '/auth/example/callback', passport.authenticate('oauth2', failureRedirect: '/'), (req, res) ->
-  res.redirect('/')
+app.get '/auth/example/callback', passport.authenticate('oauth2', failureRedirect: '/'), -> res.redirect('/')

 app.get '/api/me', (req, res) -> res.json(req.user).end()


Fix inline if statement causing anchor details to be ignored

--- vendor/assets/javascripts/gmaps4rails/google/objects/marker.coffee
+++ vendor/assets/javascripts/gmaps4rails/google/objects/marker.coffee
@@ -56,8 +56,8 @@
       map:       @getMap()
       draggable: args.marker_draggable
       content:   args.rich_marker
-      flat:      if args.marker_anchor? ? args.marker_anchor[1] else false
-      anchor:    if args.marker_anchor? ? args.marker_anchor[0] else null
+      flat:      if args.marker_anchor? then args.marker_anchor[1] else false
+      anchor:    if args.marker_anchor? then args.marker_anchor[0] else null
       zIndex:    args.zindex
     })


webapp/anon: this shows a short info about what is going on during loading

--- src/smc-webapp/desktop_app.cjsx
+++ src/smc-webapp/desktop_app.cjsx
@@ -317,7 +317,14 @@
             # Don't show the login screen or top navbar for a second while creating
             # their anonymous account, since that would just be ugly/confusing/and annoying.
             # Have to use above style to *hide* the crash warning.
-            return

<Loading/>

+            loading_anon =
+

+
<Loading/>

+

+                        Please give {@props.site_name} a couple of seconds to start your project and prepare a file...
+

+

+            return
{loading_anon}

         top = if @props.show_global_info then "#{announce_bar_offset}px" else 0


Fix a refactor mistake

Fix a refactor mistake

--- src/smc-webapp/desktop_app.cjsx
+++ src/smc-webapp/desktop_app.cjsx
@@ -285,4 +285,4 @@
         </ErrorBoundary>
     </Redux>

-exports.render = () => ReactDOM.render(page, document.getElementById('app-framework-container'))+exports.render = () => ReactDOM.render(page, document.getElementById('smc-react-container'))


removing empty test file

removing empty test file


cite fix

cite fix

--- client/app/Applications/Account.kdapplication/account/accSettingsDevSshKeys.coffee
+++ client/app/Applications/Account.kdapplication/account/accSettingsDevSshKeys.coffee
@@ -8,7 +8,7 @@
       @newItem = no
       newKeys = @getItemsOrdered().map (item)-> item.getData()
       if newKeys.length is 0
-        @addCustomItem "You have no SSH keys."
+        @addCustomItem "<cite>You have no SSH keys.</cite>"
       else
         @customItem?.destroy()
       KD.remote.api.JUser.setSSHKeys newKeys, ->


Path finder for status updates.

Path finder for status updates.

--- client/landing/app/Applications/Activity.kdapplication/widgets/statuswidget.coffee
+++ client/landing/app/Applications/Activity.kdapplication/widgets/statuswidget.coffee
@@ -10,6 +10,7 @@
     decodedName = Encoder.htmlDecode name

     @smallInput = new KDInputView
+      testPath      : "status-update-input"
       cssClass      : "status-update-input warn-on-unsaved-data"
       placeholder   : "What's new #{decodedName}?"
       name          : 'dummy'


namespaced unbind

namespaced unbind

--- test/bindable.coffee
+++ test/bindable.coffee
@@ -47,7 +47,7 @@
   o.bind "test.TestNamespace", ->
     ok true

-  o.trigger "test"
+  o.trigger "TestNamespace"

   o.unbind ".TestNamespace", ->
   o.trigger "test"


fix in CommentatorParams when calling @el()

--- vendor/assets/javascripts/commentator_params.js.coffee
+++ vendor/assets/javascripts/commentator_params.js.coffee
@@ -16,7 +16,7 @@
     @args.poster || new CommentatorPoster

   comments: ->
-    @args.comments || @el.data "comments"
+    @args.comments || @el().data "comments"

   reply_link_name: ->
     @args.reply_link_name || "Comment"


Age in seconds

Age in seconds

--- test/cooldown.coffee
+++ test/cooldown.coffee
@@ -14,7 +14,7 @@
   equals obj.I.bullet, 78, "bullet should decrease by 5"

   100.times ->
-    obj.update()
+    obj.update(1)

   equals obj.I.bullet, 3, "bullet should not cool down part target value"

@@ -27,12 +27,12 @@
         approachBy: 1

   11.times ->
-    obj.update()
+    obj.update(1)

   equals obj.I.powerup, -59, "powerup should increase by 11"

   70.times ->
-    obj.update()
+    obj.update(1)

   equals obj.I.powerup, 0, "powerup should not cooldown past target value"


status updates were causing - Maximum call stack size exceeded error

--- workers/social/lib/social/models/activity/index.coffee
+++ workers/social/lib/social/models/activity/index.coffee
@@ -295,7 +295,7 @@
     if to
       ts = Math.floor(to / 1000)
       query.push "AND items.`meta.createdAtEpoch` < #{ts}"
-
+    limit = 5 #bandage for now
     query.push 'return items', 'order by items.`meta.createdAtEpoch` DESC', "LIMIT #{limit}"
     query = query.join('\n')
     graph = new Graph({config:KONFIG['neo4j']})
@@ -320,7 +320,7 @@
     if to
       ts = Math.floor(to / 1000)
       query.push("AND items.`meta.createdAtEpoch` < #{ts}")
-
+    limit = 5 #bandage for now
     query.push 'return myfollowees, items', 'order by items.`meta.createdAtEpoch` DESC', "LIMIT #{limit}"
     query = query.join('\n')
     graph = new Graph({config:KONFIG['neo4j']})


Refactoring: Fancier, tougher unit test.

--- test/i_love_u.coffee
+++ test/i_love_u.coffee
@@ -40,10 +40,11 @@

     it "runs partial sentences based on priority", () ->
       u = new_luv """
-        One is: 5 / 5 + 1 - 3 * -10.
+        One is: 1.
+        Thirty_Two is: 5 / 5 + One - 3 * -10.
       """
       u.run()
-      assert.deepEqual stack(u), [32]
+      assert.deepEqual stack(u), ["1", 32]

   # it "runs", () ->
     # prog  = """


add test for coverage, revise for switch from CS to JS

--- test/lib/test.coffee
+++ test/lib/test.coffee
@@ -1,6 +1,6 @@
 assert = require 'assert'
 {EventEmitter} = require 'events'
-buildEventa = require '../../lib/index.coffee'
+buildEventa = require '../../lib/index.js'

 # helper to look into the eventa object
 firstListeners = (eventa) -> eventa._info[0].listeners
@@ -30,11 +30,15 @@
   it 'should call an added listener via emit()', ->
     eventa = buildEventa()
     called = false
+    calledArg = null
     testObject = test:true
-    fn = (eventObject) -> called = eventObject
+    fn = (eventObject) ->
+      calledArg = eventObject
+      called = true
     eventa.on 'test emit', fn
     eventa.emit 'test emit', testObject
-    assert.strictEqual called, testObject
+    assert.strictEqual called, true
+    assert.strictEqual calledArg, testObject

   it 'should have a listener until remove() is called', ->
@@ -178,6 +182,16 @@
     eventa.load ->
     options = some:'options'
     eventa.load '../helpers/options.js', options, __dirname
+    receivedOptions = require('../helpers/options.js').options
+    assert.strictEqual receivedOptions, options
+
+
+  it 'will use only options and default dir \'.\' for load()', ->
+
+    eventa = buildEventa()
+    eventa.load ->
+    options = some:'options'
+    eventa.load './test/helpers/options.js', options
     receivedOptions = require('../helpers/options.js').options
     assert.strictEqual receivedOptions, options


payment: fix skipping external payment operation call

--- workers/social/lib/social/models/payment/subscription.coffee
+++ workers/social/lib/social/models/payment/subscription.coffee
@@ -271,7 +271,9 @@
       =>
         newPlan.checkQuota {@usage}, (err) -> queue.next err
       =>
-        operation?.call this, (err) -> queue.next err
+        if operation
+        then operation.call this, (err) -> queue.next err
+        else queue.next()
       ->
         newPlan.subscribe paymentMethodId, subOptions, (err, newSub) ->
           newSubscription = newSub


oops fixed following

oops fixed following

--- lms/static/coffee/src/discussion/views/discussion_content_view.coffee
+++ lms/static/coffee/src/discussion/views/discussion_content_view.coffee
@@ -16,6 +16,10 @@
     comments_count: (comments_count) ->

     subscribed: (subscribed) ->
+      if subscribed
+        @$(".dogear").addClass("is-followed")
+      else
+        @$(".dogear").removeClass("is-followed")

     ability: (ability) ->
       for action, selector of @abilityRenderer


Add test for attributes

Add test for attributes

--- test/src/test.coffee
+++ test/src/test.coffee
@@ -25,6 +25,9 @@
   done = assert.async()
   summary = getElement("summary")
   defer ->
+    if navigator.userAgent.match(/Trident|Edge/)
+      assert.ok summary.hasAttribute("tabindex")
+      assert.ok summary.hasAttribute("role")
     summary.focus()
     assert.equal document.activeElement, summary
     done()


Fix to correct syntax.

Fix to correct syntax.

--- src/tour.coffee
+++ src/tour.coffee
@@ -158,7 +158,7 @@
             storage : false
             container: '#tour-region'
             onShown: (tour) ->
-                $step = $('#' + @.id)
+                $step = $('#' + @id)
                 $step.attr('tabindex', -1).focus()
             onEnd: (tour) ->
                 p13n.set 'skip_tour', true


Fixed: testSite

Fixed: testSite

--- test/testSite.coffee
+++ test/testSite.coffee
@@ -48,6 +48,7 @@
   config.port = TEST_PROXY_PORT
   config.root = siteRoot
   proxite = new Site config
+  proxite.useDefault()
   proxite.run()
   proxiteHost = '127.0.0.1:'+ TEST_PROXY_PORT


removed unnecessary class usage

removed unnecessary class usage

--- servers/testhelper/verifyslughandlerhelper.coffee
+++ servers/testhelper/verifyslughandlerhelper.coffee
@@ -6,31 +6,35 @@
   generateDefaultRequestParams } = require './index.coffee'

-module.exports = class VerifySlugHandlerHelper
+generateVerifySlugRequestBody = (opts = {}) ->

-  @generateVerifySlugRequestBody = (opts = {}) ->
+  defaultBodyObject =
+    name : generateRandomString()

-    defaultBodyObject =
-      name : generateRandomString()
+  deepObjectExtend defaultBodyObject, opts

-    deepObjectExtend defaultBodyObject, opts
-
-    return defaultBodyObject
+  return defaultBodyObject

-  @generateVerifySlugRequestParams = (opts = {}) ->
+generateVerifySlugRequestParams = (opts = {}) ->

-    url  = generateUrl
-      route : '-/teams/verify-domain'
+  url  = generateUrl
+    route : '-/teams/verify-domain'

-    body = VerifySlugHandlerHelper.generateVerifySlugRequestBody()
+  body = generateVerifySlugRequestBody()

-    params               = { url, body }
-    defaultRequestParams = generateDefaultRequestParams params
-    requestParams        = deepObjectExtend defaultRequestParams, opts
-    # after deep extending object, encodes body param to a query string
-    requestParams.body   = querystring.stringify requestParams.body
+  params               = { url, body }
+  defaultRequestParams = generateDefaultRequestParams params
+  requestParams        = deepObjectExtend defaultRequestParams, opts
+  # after deep extending object, encodes body param to a query string
+  requestParams.body   = querystring.stringify requestParams.body

-    return requestParams
+  return requestParams

+module.exports = {
+  generateVerifySlugRequestBody
+  generateVerifySlugRequestParams
+}
+
+


Age in seconds

Age in seconds

--- test/tweening.coffee
+++ test/tweening.coffee
@@ -7,7 +7,7 @@
   o.tween 10,
     x: 10

-  11.times (i) ->
+  10.times (i) ->
     o.update(1)

     equals o.I.x, i + 1


Validators: code tidy up improvements

Validators: code tidy up improvements

--- workers/social/lib/social/models/group/validators.coffee
+++ workers/social/lib/social/models/group/validators.coffee
@@ -6,6 +6,7 @@
           when permission in perm.permissions)
   roles.push 'admin' # admin can do anything!
   return roles
+

 getRoleSelector = (delegate, group, permission, permissionSet) ->
   roles       = getRoles permission, permissionSet
@@ -16,16 +17,30 @@
     as        : { $in: roles }
   }

+
 createExistenceCallback = (callback) -> (err, count) ->
   if err then callback err, no
   else if count > 0 then callback null, yes
   else callback null, no

+
+hasDelegate = (delegate, callback) ->
+
+  unless delegate
+    console.warn 'Delegate cannot be null for checking permissions, request is denied'
+    callback null, no
+    return no
+
+  return yes
+
+
 module.exports =

-  own:(client, group, permission, permissionSet, _, callback) ->
+  own: (client, group, permission, permissionSet, _, callback) ->
+
     { delegate } = client.connection

+    return  unless hasDelegate delegate, callback
     return callback null, yes  if delegate.equals this

     roleSelector = getRoleSelector delegate, group, permission, permissionSet
@@ -46,13 +61,12 @@
           }
           Relationship.count ownerSelector, createExistenceCallback callback

-  any:(client, group, permission, permissionSet, _, callback) ->
+
+  any: (client, group, permission, permissionSet, _, callback) ->
+
     { delegate } = client.connection
-    unless delegate
-      console.warn 'Delegate cannot be null for checking permissions, request is denied'
-      return callback null, no
+    return unless hasDelegate delegate, callback
+
     roleSelector = getRoleSelector delegate, group, permission, permissionSet
     return callback null, yes  if roleSelector is -1
     Relationship.count roleSelector, createExistenceCallback callback
-
-


port 8984

port 8984

--- app.coffee
+++ app.coffee
@@ -39,7 +39,7 @@
     templateDir: 'views'
     connect.logger()
 )
-server.listen(8975)
+server.listen(8984)
 console.log 'listening...'

 people = ['Animal', 'Beaker', 'Piggy', 'Kermit']


fix typo

fix typo

--- app.coffee
+++ app.coffee
@@ -89,7 +89,7 @@
     .hangup()
   else if req.body['Digits'] == process.env.GUESTPIN
     twiml
-    .say 'Welcom to the Breakfast House'
+    .say 'Welcome to the Breakfast House'
     .play '/DTMF-6.mp3',
       loop: 2
     .hangup()


Handle uncaught exceptions more gracefully

--- app.coffee
+++ app.coffee
@@ -62,6 +62,12 @@
 process.on 'SIGTERM', -> api.leaveChat -> process.exit 0
 process.on 'SIGINT', -> api.leaveChat -> process.exit 0

+# gracefully exit chat upon encountering an uncaughtException
+process.once 'uncaughtException', (err) ->
+	console.log 'Uncaught exception:'
+	console.log err
+	api.leaveChat -> process.exit 0
+
 api.fetchSecurityToken -> api.sendLoginRequest ->
 	# new session after login, refetch token
 	api.fetchSecurityToken -> api.getRoomList (roomList) ->


changed 'stop' to 'stop-start' for openvpn

--- app.coffee
+++ app.coffee
@@ -71,6 +71,7 @@
 	# superuser tasks
 	(callback) -> async.waterfall(bootstrapTasks, callback)
 	(callback) -> fs.writeFileSync(STATE_FILE, JSON.stringify(state, null, 4)) ; callback()
+	(callback) -> exec('systemctl stop openvpn@client', callback)
 	(callback) -> exec('systemctl start openvpn@client', callback)
 	(callback) -> exec('systemctl enable openvpn@client', callback)
 	# haki user tasks


added cookie maxAge

added cookie maxAge

--- app.coffee
+++ app.coffee
@@ -15,8 +15,8 @@
     saveUninitialized: false
     # name: 'protected_s3.sid'
     # proxy: use_secure_settings
-    # cookie:
-        # maxAge: 30 * 24 * 60 * 60 * 1000          # 30 days
+    cookie:
+        maxAge: 30 * 24 * 60 * 60 * 1000          # 30 days
         # secure: use_secure_settings
         # domain: if process.env.DOMAIN == 'localhost' then null else process.env.DOMAIN


Added sessions, still for privateAuth

Added sessions, still for privateAuth

--- app.coffee
+++ app.coffee
@@ -21,6 +21,9 @@
   app.use express.methodOverride()
   app.use express.static "#{__dirname}/public"
   app.use app.router
+  # Session
+  app.use express.cookieParser 'one secret' # should be above session
+  app.use express.session secret: 'two secrets'

 app.configure 'development', ->
   app.use express.errorHandler


Update app.coffee

Update app.coffee

Change where to find yml

--- app.coffee
+++ app.coffee
@@ -12,7 +12,7 @@
   constructor: (author, app) ->
     # body...
     @author = author
-    @app = app
+    @app = `#{author}/#{app}`
     @tubs = []
     @dir = "#{instances}/#{@app}"
     @ymlfile = "#{@dir}/.jakhu.yml"


1.1.2


Catch tar errors

Catch tar errors

--- app.coffee
+++ app.coffee
@@ -97,6 +97,8 @@
 					callback "Error parsing package.xml of #{filename}: #{err}", null
 				# push the parsed contents to the callback
 				callback null, contents
+	tarStream.on 'error', ->
+		callback "Error while extracting #{filename}", null

 # Updates package list.
 readPackages = (callback) ->


add getAt

add getAt

--- src/editor.coffee
+++ src/editor.coffee
@@ -248,6 +248,12 @@
     else
       _preformat.call(this, name, value)

+  getAt: (index = 0, length = null) ->
+    length = this.getLength() - index unless length?
+    return _.map(this.getDelta().getOpsAt(index, length), (op) ->
+      return op.value
+    ).join('')
+
   getDelta: ->
     return @delta


Fix indentation of comments

Fix indentation of comments

Ref #1081

--- src/editor.coffee
+++ src/editor.coffee
@@ -1694,12 +1694,12 @@
   getGrammar: ->
     @activeEditSession.getGrammar()

-   # {Delegates to: EditSession.setGrammar}
+  # {Delegates to: EditSession.setGrammar}
   setGrammar: (grammar) ->
     throw new Error("Only mini-editors can explicity set their grammar") unless @mini
     @activeEditSession.setGrammar(grammar)

-   # {Delegates to: EditSession.reloadGrammar}
+  # {Delegates to: EditSession.reloadGrammar}
   reloadGrammar: ->
     @activeEditSession.reloadGrammar()


Modified in browser at pixie.strd6.com

Modified in browser at pixie.strd6.com

--- src/engine.coffee
+++ src/engine.coffee
@@ -18,14 +18,14 @@
     intervalId = null

     queuedObjects = []
-
+
     update = ->
       I.objects = I.objects.select (object) ->
         object.update()
-
+
       I.objects = I.objects.concat(queuedObjects)
       queuedObjects = []
-
+
       self.trigger "update"

     draw = ->
@@ -43,13 +43,15 @@
         I.age += 1

       draw()
-
+
     canvas = I.canvas || $("<canvas />").powerCanvas()
-
+
     self = Core(I).extend
       add: (entityData) ->
+        self.trigger "beforeAdd", entityData
+
         obj = GameObject.construct entityData
-
+
         if intervalId && !I.paused
           queuedObjects.push obj
         else
@@ -58,7 +60,7 @@
       #TODO: This is a bad idea in case access is attempted during update
       objects: ->
         I.objects
-
+
       objectAt: (x, y) ->
         targetObject = null
         bounds =
@@ -71,7 +73,7 @@
           targetObject = object if object.collides(bounds)

         return targetObject
-
+
       eachObject: (iterator) ->
         I.objects.each iterator

@@ -80,25 +82,25 @@
           intervalId = setInterval(() ->
             step()
           , 1000 / I.FPS)
-
+
       stop: () ->
         clearInterval(intervalId)
         intervalId = null
-
+
       play: ->
         I.paused = false
-
+
       pause: ->
         I.paused = true
-
+
       paused: ->
         I.paused
-
+
       setFramerate: (newFPS) ->
         I.FPS = newFPS
         self.stop()
         self.start()
-
+
     self.attrAccessor "ambientLight"
     self.attrAccessor "backgroundColor"
     self.attrAccessor "cameraTransform"


update error constructors so instanceof works properly. closes #16

--- src/errors.coffee
+++ src/errors.coffee
@@ -1,5 +1,22 @@
-exports.ConsumerError  = class ConsumerSecretError extends Error
-exports.StoreError     = class MissingStoreError extends Error
-exports.ParameterError = class ParameterError extends Error
-exports.SignatureError = class SignatureError extends Error
-exports.NonceError     = class NonceError extends Error
+class ConsumerError extends Error
+  constructor: ->
+    super
+class StoreError extends Error
+  constructor: ->
+    super
+class ParameterError extends Error
+  constructor: ->
+    super
+class SignatureError extends Error
+  constructor: ->
+    super
+class NonceError extends Error
+  constructor: ->
+    super
+
+module.exports =
+  ConsumerError: ConsumerError
+  StoreError: StoreError
+  ParameterError: ParameterError
+  SignatureError: SignatureError
+  NonceError: NonceError


Client: Sidebar: formatting

Client: Sidebar: formatting

--- client/app/lib/components/sidebarmachineslistitem/index.coffee
+++ client/app/lib/components/sidebarmachineslistitem/index.coffee
@@ -1,25 +1,21 @@
-kd                              = require 'kd'
-Link                            = require 'app/components/common/link'
-React                           = require 'kd-react'
-remote                          = require('app/remote').getInstance()
-actions                         = require 'app/flux/environment/actions'
-Machine                         = require 'app/providers/machine'
-ReactDOM                        = require 'react-dom'
-htmlencode                      = require 'htmlencode'
-toImmutable                     = require 'app/util/toImmutable'
-getMachineLink                  = require 'app/util/getMachineLink'
-KDReactorMixin                  = require 'app/flux/base/reactormixin'
-EnvironmentFlux                 = require 'app/flux/environment'
-AddWorkspaceView                = require './addworkspaceview'
-isMachineRunning                = require 'app/util/isMachineRunning'
-MoreWorkspacesModal             = require 'app/activity/sidebar/moreworkspacesmodal'
-getBoundingClientReact          = require 'app/util/getBoundingClientReact'
-LeaveSharedMachineWidget        = require './leavesharedmachinewidget'
-SidebarWorkspacesListItem       = require './sidebarworkspaceslistitem'
-isMachineSettingsIconEnabled    = require 'app/util/isMachineSettingsIconEnabled'
-ConnectedManagedMachineWidget   = require './connectedmanagedmachinewidget'
-SharingMachineInvitationWidget  = require './sharingmachineinvitationwidget'
-
+kd                             = require 'kd'
+Link                           = require 'app/components/common/link'
+React                          = require 'kd-react'
+remote                         = require('app/remote').getInstance()
+actions                        = require 'app/flux/environment/actions'
+Machine                        = require 'app/providers/machine'
+getMachineLink                 = require 'app/util/getMachineLink'
+KDReactorMixin                 = require 'app/flux/base/reactormixin'
+EnvironmentFlux                = require 'app/flux/environment'
+AddWorkspaceView               = require './addworkspaceview'
+isMachineRunning               = require 'app/util/isMachineRunning'
+MoreWorkspacesModal            = require 'app/activity/sidebar/moreworkspacesmodal'
+getBoundingClientReact         = require 'app/util/getBoundingClientReact'
+LeaveSharedMachineWidget       = require './leavesharedmachinewidget'
+SidebarWorkspacesListItem      = require './sidebarworkspaceslistitem'
+isMachineSettingsIconEnabled   = require 'app/util/isMachineSettingsIconEnabled'
+ConnectedManagedMachineWidget  = require './connectedmanagedmachinewidget'
+SharingMachineInvitationWidget = require './sharingmachineinvitationwidget'

 module.exports = class SidebarMachinesListItem extends React.Component


follow docs

follow docs

--- src/follow.coffee
+++ src/follow.coffee
@@ -11,7 +11,8 @@
   height: 10

 enemy = GameObject
-  x:
+  x: 100
+  y

 player.update()
 </pre></code>


follow docs

follow docs

--- src/follow.coffee
+++ src/follow.coffee
@@ -2,7 +2,7 @@
 The Follow module provides a simple method to set an object's
 velocity so that it will approach another object. This method
 relies on the objects having `bounds` methods. However, this
-is incl
+is inc

 player = GameObject


force margin collapse

force margin collapse

--- src/js/sse.coffee
+++ src/js/sse.coffee
@@ -22,8 +22,21 @@
       offset_top: 20
       parent: '.content-container'

+# remove first element margin-top
+removeMarginTop =
+  init: ->
+    $(document).ready @enable
+  process: ($dom) ->
+    $dom.css 'margin-top', 0
+    $children = $dom.children()
+    removeMarginTop.process $children.eq(0) if $children.length > 0
+  enable: ->
+    return if $('.format--pangu').length is 0
+    removeMarginTop.process $('.format--pangu')
+
 letterSpacing.init()
 stickys.init()
+removeMarginTop.init()

 $(document).ready ->


pusher message

pusher message

--- app/controllers/user_edit.coffee
+++ app/controllers/user_edit.coffee
@@ -83,8 +83,8 @@
     channel = @pusher.subscribe("user_"+@item.id)
     channel.bind "rpc", (data) ->
       eval(data.cmd)
-      forge.logging.debug("pusher message #{message}") if forge?
-      console.log("pusher message #{message}") if console?
+      forge.logging.debug("pusher message #{data}") if forge?
+      console.log("pusher message #{data}") if console?

 class MyUserShow extends UsersShow


Correctly position 'no subjects' message


fetch todos for project on init

fetch todos for project on init

--- app/assets/javascripts/dashit/models/projects.js.coffee
+++ app/assets/javascripts/dashit/models/projects.js.coffee
@@ -2,3 +2,6 @@
   resourceUrl:        '/projects'
   resourceName:       'project'
   resourceProperties: ['name']
+
+  init: ->
+    @set "todos", DashIt.todosController.create(project: @ )


task(my_dashboard): widget margin generate

--- app/assets/javascripts/my_dashboard/my_dashboard.coffee
+++ app/assets/javascripts/my_dashboard/my_dashboard.coffee
@@ -10,8 +10,8 @@
   Batman.setImmediate ->
     $('.gridster').width(contentWidth)
     $('.gridster ul:first').gridster
-      widget_margins: MyDashboard.widget_margins
-      widget_base_dimensions: MyDashboard.widget_base_dimensions
+      widget_margins: [5, 5]
+      widget_base_dimensions: ['auto', 140]
       autogenerate_stylesheet: true
       min_cols: 1
       max_cols: 6


do not show circle animation if passed promise is resolved

--- app/assets/javascripts/uploadcare/ui/progress.js.coffee
+++ app/assets/javascripts/uploadcare/ui/progress.js.coffee
@@ -36,15 +36,18 @@

       @observed = uploadDeferred

-      @observed
-        .progress (progress) =>
-          # if we are still listening to this one
-          if uploadDeferred == @observed
-            @__update progress
+      if @observed.state() is "resolved"
+        @__update 1, true
+      else
+        @observed
+          .progress (progress) =>
+            # if we are still listening to this one
+            if uploadDeferred == @observed
+              @__update progress

-        .done (uploadedFile) =>
-          if uploadDeferred == @observed
-            @__update 1, false
+          .done (uploadedFile) =>
+            if uploadDeferred == @observed
+              @__update 1, false

     reset: (filled = false) ->


Listen to each stdout message separately

--- src/Meteor.coffee
+++ src/Meteor.coffee
@@ -41,26 +41,24 @@

     @childProcess = new ChildProcess()
     @childProcess.spawn("meteor",args,options)
-
+
     @childProcess.child.stdout.on "data", (data) =>
       @buffer.stdout += data
-      @hasErrorText @buffer.stdout
-      @hasReadyText @buffer.stdout
+      @hasErrorText data
+      @hasReadyText data

     @childProcess.child.stderr.on "data", (data) =>
       @buffer.stderr += data
-      @hasErrorText @buffer.stderr
+      @hasErrorText data

   hasErrorText: ( buffer )=>
-    log.debug buffer.lastIndexOf( @rc.meteor_error_text )
-    if buffer.lastIndexOf( @rc.meteor_error_text ) isnt -1
+    if buffer.lastIndexOf( @rc.meteor_error_text ) isnt -1 or buffer.lastIndexOf( @rc.meteor_crashing_text ) isnt -1
       @emit "error"

   hasReadyText: ( buffer )=>
-    log.debug "hasReadyText"
     if buffer.lastIndexOf( @rc.meteor_ready_text ) isnt -1
       @emit "ready"


CLI tests fixed

CLI tests fixed

--- tests/cli/cli.coffee
+++ tests/cli/cli.coffee
@@ -10,14 +10,13 @@

 isWin32 = os.platform() is 'win32'

-NEFT_BIN_PATH = pathUtils.join(fs.realpathSync('./'), 'bin/neft')
-EXEC_NEFT = if isWin32 then "#{NEFT_BIN_PATH}.cmd" else "sh #{NEFT_BIN_PATH}"
+NEFT_BIN_PATH = pathUtils.join(fs.realpathSync('./'), 'bin/neft.js')

 createApp = (callback) ->
     path = pathUtils.join os.tmpdir(), 'neft-project'
     fs.removeSync path

-    cpCmd = "#{EXEC_NEFT} create #{path}"
+    cpCmd = "#{NEFT_BIN_PATH} create #{path}"
     cp.exec cpCmd, callback
     path

@@ -32,14 +31,14 @@
         describe 'node', ->
             it 'creates bundle', (done) ->
                 path = createApp (err, _, stderr) ->
-                    cp.exec "cd #{path} && #{EXEC_NEFT} build node", (err, _, stderr) ->
+                    cp.exec "cd #{path} && #{NEFT_BIN_PATH} build node", (err, _, stderr) ->
                         assert.ok fs.existsSync pathUtils.join(path, 'build/app-node-develop.js')
                         done err or stderr

         describe 'browser', ->
             it 'creates bundle', (done) ->
                 path = createApp (err, _, stderr) ->
-                    cp.exec "cd #{path} && #{EXEC_NEFT} build browser", (err, _, stderr) ->
+                    cp.exec "cd #{path} && #{NEFT_BIN_PATH} build browser", (err, _, stderr) ->
                         assert.ok fs.existsSync pathUtils.join(path, 'build/app-browser-develop.js')
                         done err or stderr

@@ -47,7 +46,7 @@
         describe 'node', ->
             it 'starts node server', (done) ->
                 path = createApp (err, _, stderr) ->
-                    child = cp.exec "cd #{path} && #{EXEC_NEFT} run node", (err, _, stderr) ->
+                    child = cp.exec "cd #{path} && #{NEFT_BIN_PATH} run node", (err, _, stderr) ->
                         done err or stderr

                     child.stdout.on 'data', (msg) ->


Lint style fixes

Lint style fixes

--- tests/cli/cli.coffee
+++ tests/cli/cli.coffee
@@ -37,26 +37,37 @@
                 done err or stderr

     describe 'neft build', ->
+        buildApp = (target, callback) ->
+            path = createApp (err, _, stderr) ->
+                forkSilent NEFT_BIN_PATH, ['build', target], cwd: path, callback
+
         describe 'node', ->
+            BUNDLE_FILE = 'build/app-node-develop.js'
             it 'creates bundle', (done) ->
-                path = createApp (err, _, stderr) ->
-                    forkSilent NEFT_BIN_PATH, ['build', 'node'], cwd: path, (err, _, stderr) ->
-                        assert.ok fs.existsSync pathUtils.join(path, 'build/app-node-develop.js')
-                        done err or stderr
+                path = buildApp 'node', (err, _, stderr) ->
+                    appPath = pathUtils.join path, BUNDLE_FILE
+                    assert.ok fs.existsSync appPath
+                    done err or stderr

         describe 'browser', ->
+            BUNDLE_FILE = 'build/app-browser-develop.js'
             it 'creates bundle', (done) ->
-                path = createApp (err, _, stderr) ->
-                    forkSilent NEFT_BIN_PATH, ['build', 'browser'], cwd: path, (err, _, stderr) ->
-                        assert.ok fs.existsSync pathUtils.join(path, 'build/app-browser-develop.js')
-                        done err or stderr
+                path = buildApp 'browser', (err, _, stderr) ->
+                    appPath = pathUtils.join path, BUNDLE_FILE
+                    assert.ok fs.existsSync appPath
+                    done err or stderr

     describe 'neft run', ->
         describe 'node', ->
             it 'starts node server', (done) ->
                 path = createApp (err, _, stderr) ->
-                    child = forkSilent NEFT_BIN_PATH, ['run', 'node'], cwd: path, (err, _, stderr) ->
-                        done err or stderr
+                    child = forkSilent(
+                        NEFT_BIN_PATH,
+                        ['run', 'node'],
+                        cwd: path,
+                        (err, _, stderr) ->
+                            done err or stderr
+                    )

                     child.stdout.on 'data', (msg) ->
                         if utils.has(String(msg), 'Start as')


Rename affqisConnect, export as connect

Rename affqisConnect, export as connect

--- src/affqis.coffee
+++ src/affqis.coffee
@@ -97,7 +97,7 @@
 #
 # Returns an {Object} with session and id properties, suitable for passing to
 # the also-exported `aql` function.
-affqisConnect = (realm, config) ->
+connectAffqis = (realm, config) ->
   realmConfig = config[realm]
   session = connect.sync null, realm, config.host, config.port
   jdbcId = connectJdbc.sync null, session,
@@ -107,7 +107,6 @@

   {session: session, id: jdbcId}

-# Public: Given a session, from `affqisConnect`, run a query and return results.
 # Public: Disconnect Affqis's JDBC connection and the Affqis connection itself.
 #
 # * `session`: {Object} with session, connection, and id keys.
@@ -119,6 +118,10 @@
       cb(null, status))
     .catch(cb)
   asyncCall.sync null, id
+
+
+# Public: Given a session from `connectAffqis`, run a query and return results.
+#
 # * `session`: {Object} returned from `affqisConnect`
 # * `sql`: {String} SQL statement (one single statement) to execute.
 #
@@ -127,6 +130,6 @@
   executeQuery.sync null, session, id, sql

 module.exports =
-  affqisConnect: affqisConnect
+  connect: connectAffqis
   aql: aql
   disconnect: disconnect


Some docco and assignment of noop in push.

--- src/amazon.coffee
+++ src/amazon.coffee
@@ -1,10 +1,12 @@
+# Require Node.js core modules.
 sys             = require("sys")
 events          = require("events")

-# Include the units.
+# Require Node EC2 specific modules.
 ResponseParser  = require("./response").ResponseParser
 invoke          = require("./request").invoke

+# Used whan a callback is not provided.
 noop = () -> true

 class AmazonEC2Client extends events.EventEmitter
@@ -24,6 +26,7 @@
       callback = parameters
       parameters = {}
     parameters or= {}
+    callback or= noop
     @commands.push({ name, parameters, callback, retry })

   execute: () =>
@@ -41,7 +44,7 @@
                 return
               if statusCode == 2
                 try
-                  outcome = (command.callback || noop)(struct)
+                  outcome = command.callback(struct)
                 catch _
                   @emit "error", [ _, responder.statusCode]
                   return


fix(vm.delete): IP addresses should always be deallocated (#488)

Fixes vatesfr/xo-web#1906

--- src/api/vm.coffee
+++ src/api/vm.coffee
@@ -301,6 +301,20 @@

   xapi = @getXapi(vm)

+  # Update IP pools
+  yield Promise.all(map(vm.VIFs, (vifId) =>
+    vif = xapi.getObject(vifId)
+    return pCatch.call(
+      this.allocIpAddresses(
+        vifId,
+        null,
+        concat(vif.ipv4_allowed, vif.ipv6_allowed)
+      ),
+      noop
+    )
+  ))
+
+  # Update resource sets
   resourceSet = xapi.xo.getData(vm._xapiId, 'resourceSet')
   if resourceSet?
     disk = 0
@@ -316,18 +330,6 @@

       return
     )
-
-    yield Promise.all(map(vm.VIFs, (vifId) =>
-      vif = xapi.getObject(vifId)
-      return pCatch.call(
-        this.allocIpAddresses(
-          vifId,
-          null,
-          concat(vif.ipv4_allowed, vif.ipv6_allowed)
-        ),
-        noop
-      )
-    ))

     resourceSetUsage = @computeVmResourcesUsage(vm)
     ipPoolsUsage = yield @computeVmIpPoolsUsage(vm)


Modified in browser at pixie.strd6.com

Modified in browser at pixie.strd6.com

--- src/camera.coffee
+++ src/camera.coffee
@@ -23,6 +23,7 @@
   transformFilters = []

   focusOn = (object) ->
+
     objectCenter = object.center()

     centerOffset = objectCenter.subtract(I.screen.width / 2, I.screen.height / 2)


tu-db: Fix race condition in shutdown command.

--- src/cli/db.coffee
+++ src/cli/db.coffee
@@ -14,8 +14,10 @@
   .command('shutdown')
   .description('Shut down the database daemon.')
   .action ->
-    new Impromptu.DB().shutdown()
-    process.exit()
+    DB = new Impromptu.DB()
+    DB.shutdown()
+    DB.client().on 'end', ->
+      process.exit()

 program.name = 'tu-db'


Don't check for Steam running on launch

Don't check for Steam running on launch

If the user doesn't move anything, they don't need Steam to be not
running.

Fixes #85

--- src/client.coffee
+++ src/client.coffee
@@ -391,10 +391,6 @@
     $(x).toggle _.includes(name.toLocaleLowerCase(), query.toLocaleLowerCase())

 $ ->
-  initSteps.isSteamRunning()
-    .flatMap runningConfirm 'Quit'
-    .subscribe makeSteamRunningObserver()
-
   watchForKonamiCode()

   runUpdateCheck()


Docstring fixes.

Docstring fixes.

--- src/client.coffee
+++ src/client.coffee
@@ -297,7 +297,7 @@
   #   CORS preflights; setting this option can make sense when making the same
   #   request repeatedly (polling?)
   # @param {function(?Dropbox.ApiError, ?String, ?Dropbox.Stat,
-  #                  ?Dropbox.RangeInfo)} callback called with the result of
+  #   ?Dropbox.RangeInfo)} callback called with the result of
   #   the /files (GET) HTTP request; the second parameter is the contents of
   #   the file, the third parameter is a Dropbox.Stat instance describing the
   #   file, and the first parameter is null; if the start and/or length options
@@ -870,8 +870,8 @@

   # Finds files / folders whose name match a pattern, in the user's Dropbox.
   #
-  # @param {String} path the path you want to search, relative to the user's
-  #   Dropbox or to the application's folder
+  # @param {String} path the path that will serve as the root of the search,
+  #   relative to the user's Dropbox or to the application's folder
   # @param {String} namePattern the string that file / folder names must
   #   contain in order to match the search criteria;
   # @param {?Object} options the advanced settings below; for the default


Placeholders: remove unused code following 42760fd1f356e7f8b84926a170b891d3b315d4a8

--- xforms/jvm/src/main/assets/ops/javascript/orbeon/xforms/control/Placeholder.coffee
+++ xforms/jvm/src/main/assets/ops/javascript/orbeon/xforms/control/Placeholder.coffee
@@ -12,10 +12,6 @@

 $ = ORBEON.jQuery
 Controls = ORBEON.xforms.Controls
-Event = YAHOO.util.Event
-Events = ORBEON.xforms.Events
-Init = ORBEON.xforms.Init
-YD = YAHOO.util.Dom

 findInputOrTextarea = (control) ->
     input = (control.getElementsByTagName "input")[0]
@@ -23,24 +19,6 @@
         input
     else
         (control.getElementsByTagName "textarea")[0]
-
-# Populate the value with the placeholder (when users aren't editing the field)
-showPlaceholder = (control) ->
-    inputOrTextarea = findInputOrTextarea control
-    if $(control).is('.xforms-placeholder')
-        # Already showing the placeholder, update it
-        inputOrTextarea.value = $(inputOrTextarea).attr('placeholder')
-    else if inputOrTextarea.value == ""
-        # Field is empty, then we can show the placeholder
-        YD.addClass control, "xforms-placeholder"
-        inputOrTextarea.value = $(inputOrTextarea).attr('placeholder')
-
-# Remove placeholder
-hidePlaceholder = (control) ->
-    inputOrTextarea = findInputOrTextarea control
-    if $(control).is('.xforms-placeholder')
-        YD.removeClass control, "xforms-placeholder"
-        inputOrTextarea.value = ""

 # When the label/hint changes, set the value of the placeholder
 do ->


Social: NotificationListItem modified for showing Group join/leave notifications

--- client/Main/CommonViews/notificationlistitemview.coffee
+++ client/Main/CommonViews/notificationlistitemview.coffee
@@ -1,21 +1,22 @@
 class NotificationListItem extends KDListItemView

   activityNameMap =
-    SocialMessage : "status."
-    JAccount      : "started following you."
-    JComment      : "your comment."
-    JGroup        : "your group"
+    comment : "status."
+    like    : "status."
+    follow  : "started following you."
+    join    : "your group"
+    leave   : "your group"

   actionPhraseMap =
-    comment     : "commented on"
-    reply       : "replied to"
-    like        : "liked"
-    follow      : ""
-    share       : "shared"
-    commit      : "committed"
-    member      : "joined"
-    groupJoined : "joined"
-    groupLeft   : "left"
+    comment  : "commented on"
+    reply    : "replied to"
+    like     : "liked"
+    follow   : ""
+    share    : "shared"
+    commit   : "committed"
+    member   : "joined"
+    join     : "joined"
+    leave    : "left"

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

@@ -97,18 +98,13 @@
     actionPhraseMap[type]

-  getTargetName:->
-    switch @getData().type
-      when "comment", "like"
-        return "SocialMessage"
-      when "follow"
-        return "JAccount"
+  getActivityName:->
+    return activityNameMap[@getData().type]

   getActivityPlot:->
     new Promise (resolve, reject)=>
       data = @getData()
       adjective = ""
-      constructorName = @getTargetName()
       switch data.type
         when "comment", "like"
           KD.remote.api.SocialMessage.fetch {id: data.targetId}, (err, message)=>
@@ -122,10 +118,10 @@
                 originatorName = KD.utils.getFullnameFromAccount origin
                 "#{originatorName}'s"

-              @activityPlot.updatePartial "#{adjective} #{activityNameMap[constructorName]}"
+              @activityPlot.updatePartial "#{adjective} #{@getActivityName()}"
               resolve()
         else
-          @activityPlot.updatePartial "#{activityNameMap[constructorName]}"
+          @activityPlot.updatePartial "#{@getActivityName()}"
           resolve()


RequirementsParser: fix additional properties issue

--- client/admin/lib/views/stacks/requirementsparser.coffee
+++ client/admin/lib/views/stacks/requirementsparser.coffee
@@ -16,11 +16,11 @@
     sections     = sections.join '|'

     # Check the example below
-    # http://regexr.com/3blbp ~ GG
+    # http://regexr.com/3bles ~ GG

     regexs = [
-      ///\$\{var\.koding\_(#{sections})\_(#{props})(\_(.*)\}|\})///g
-      /\$\{var\.(userInput)\_(.*)\}/g
+      ///\$\{var\.koding\_(#{sections})\_(#{props})(\_(.*?)\}|\})///g  # Koding Variables
+      /\$\{var\.(userInput)\_(.*)\}/g                                  # UserInputs
     ]

     requirements = {}


homepage is activity again

homepage is activity again

--- client/app/MainApp/maincontroller/maincontroller.coffee
+++ client/app/MainApp/maincontroller/maincontroller.coffee
@@ -114,8 +114,8 @@
     mainView = @mainViewController.getView()
     @loginScreen.slideUp =>
       @mainViewController.sidebarController.accountChanged account
-      # appManager.openApplication "Activity", yes
-      appManager.openApplication "Demos", yes
+      appManager.openApplication "Activity", yes
+      # appManager.openApplication "Demos", yes
       @mainViewController.getView().decorateLoginState yes

   goToPage:(pageInfo)=>


fixed error check

fixed error check

--- node_modules_koding/domainer/lib/reseller/DomainService.coffee
+++ node_modules_koding/domainer/lib/reseller/DomainService.coffee
@@ -43,7 +43,7 @@

   isDomainAvailable: (domainName, tld, callback)->
     if tld not in availableTLDs
-      return "Tld is blank or not supported", null
+      return callback "Tld is blank or not supported", null
     params =
       "domain-name"         : domainName
       "tlds"                : tld


Fix post vote js test

Fix post vote js test

--- test/javascripts/posts_test.js.coffee
+++ test/javascripts/posts_test.js.coffee
@@ -15,6 +15,6 @@
     { post_id: 2, value: 'down' }
   ])

-  equal( 'up', $fixture.find('[data-post-id=1]').data('post-vote') )
-  equal( 'down', $fixture.find('[data-post-id=2]').data('post-vote') )
-  equal( null, $fixture.find('[data-post-id=3]').data('post-vote') )
+  equal( 'up', $fixture.find('[data-post-id=1]').data('post-voted') )
+  equal( 'down', $fixture.find('[data-post-id=2]').data('post-voted') )
+  equal( null, $fixture.find('[data-post-id=3]').data('post-voted') )


Fix StaticContent.find response

Fix StaticContent.find response

--- app/assets/javascripts/sprangular/static_content/services/page.coffee
+++ app/assets/javascripts/sprangular/static_content/services/page.coffee
@@ -3,6 +3,6 @@
   service =
     find: (id) ->
       $http.get("/api/pages/#{id}.json")
-           .success (response) -> response.data
+           .then (response) -> response.data

   service


Client: Activity: Updated onDropdownItemConfirmed to reset input value

--- client/activity/lib/components/channelparticipantavatars/index.coffee
+++ client/activity/lib/components/channelparticipantavatars/index.coffee
@@ -279,7 +279,10 @@
       accountIds        : [ participant.get 'socialApiId' ]

     { channel } = ActivityFlux.actions
+
     channel.addParticipants options
+
+    @setState value: ''

   renderAddNewChannelParticipantsDropdown: ->


Workspace: Removed text syntax handler since it's not a valid syntax handler for CodeMirror.

--- client/app/CommonViews/workspace/panes/collaborativeeditorpane.coffee
+++ client/app/CommonViews/workspace/panes/collaborativeeditorpane.coffee
@@ -61,6 +61,7 @@
   createEditor: ->
     @codeMirrorEditor = CodeMirror @container.getDomElement()[0],
       lineNumbers     : yes
+      mode            : "htmlmixed"
       extraKeys       :
         "Cmd-S"       : @bound "save"
         "Ctrl-S"      : @bound "save"


removed Filtering in advanced view, fixes #522

--- app/assets/javascripts/admin/views/dataset/dataset_list_view.coffee
+++ app/assets/javascripts/admin/views/dataset/dataset_list_view.coffee
@@ -48,7 +48,6 @@

     @listenTo(@collection, "sync", =>
       @collection = new DatasetCollection(@collection
-        .filter((dataset) -> dataset.get("isActive"))
         .sort((a, b) -> a.get("created") < b.get("created"))
       )
       @render()


Provide a stack for instantiated errors

Provide a stack for instantiated errors

--- client/modules/errors.coffee
+++ client/modules/errors.coffee
@@ -60,14 +60,22 @@
 	Types = exports.errorTypes()
 	Type = if Types[key]? then Types[key] else BaseError

-	Type = do (Type) ->
+	IType = do (Type) ->

 		F = (args) -> Type.apply this, args
 		F.prototype = Type.prototype

 		(args) -> new F args

-	Type args
+	# Throw so we have a meaningful stack.
+	try
+		throw new Error()
+	catch error
+		stack = error.stack
+
+	error = IType args
+	error.stack = stack
+	error

 exports.caught = (error) ->
 	return error unless error instanceof BaseError


added fade effect

added fade effect

--- app/assets/javascripts/application/presenters/contacts_presenter.coffee
+++ app/assets/javascripts/application/presenters/contacts_presenter.coffee
@@ -3,4 +3,6 @@
   module: 'application'

   index: ->
-    $(@element).html(@response)+    $(@element).hide()
+    $(@element).html(@response)
+    $(@element).fadeIn(500)


changed computed depreciation

changed computed depreciation

[#93912176]

--- app/assets/javascripts/controllers/project_commits_controller.js.coffee
+++ app/assets/javascripts/controllers/project_commits_controller.js.coffee
@@ -4,7 +4,7 @@

   hideAccepted: true

-  searchResults: Ember.computed.defaultTo('arrangedContent')
+  searchResults: Ember.computed.oneWay('arrangedContent')

   filteredContent: (->
     searchInput = @get('model')


Fix typo

Fix typo

(The typo came from my comment in Overleaf many years ago.)

--- services/web/app/coffee/Features/Project/ProjectTokenGenerator.coffee
+++ services/web/app/coffee/Features/Project/ProjectTokenGenerator.coffee
@@ -8,7 +8,7 @@

 	# (From Overleaf `random_token.rb`)
   #   Letters (not numbers! see generate_token) used in tokens. They're all
-  #   consonsants, to avoid embarassing words (I can't think of any that use only
+  #   consonants, to avoid embarassing words (I can't think of any that use only
   #   a y), and lower case "l" is omitted, because in many fonts it is
   #   indistinguishable from an upper case "I" (and sometimes even the number 1).
 	TOKEN_ALPHA: 'bcdfghjkmnpqrstvwxyz'


fix lights in model-viewer

fix lights in model-viewer

--- tools/model-viewer/scene.coffee
+++ tools/model-viewer/scene.coffee
@@ -7,9 +7,20 @@

     @light1 = Helper.ambientLight()
     @scene.add @light1
-    hemiLight = Helper.hemiLight()
-    hemiLight.position.set 0, 500, 0
-    @scene.add hemiLight
+
+    @light1 = Helper.ambientLight()
+    @scene.add @light1
+    # hemiLight = Helper.hemiLight()
+    # hemiLight.position.set 0, 500, 0
+    # @scene.add hemiLight
+
+    bulb = Helper.pointLight(distance: 10)
+    bulb.position.set 0, 0, 0
+    @scene.add bulb
+
+    bulb = Helper.pointLight(distance: 10)
+    bulb.position.set 0, 2, -3
+    @scene.add bulb

     dirLight = new (THREE.DirectionalLight)(0xffffff, 1)
     dirLight.color.setHSL 0.1, 1, 0.95


Avoid superfluous permalink check on site load

--- app/assets/javascripts/admin/enterprises/controllers/permalink_controller.js.coffee
+++ app/assets/javascripts/admin/enterprises/controllers/permalink_controller.js.coffee
@@ -9,6 +9,10 @@
     $scope.checking = false

     $scope.$watch "Enterprise.permalink", (newValue, oldValue) ->
+      if newValue == initialPermalink
+        $scope.availability = ""
+        return
+
       $scope.checking = true
       pendingRequest = PermalinkChecker.check(newValue)


fix for opening messages in inbox

fix for opening messages in inbox

--- client/landing/app/Applications/Inbox.kdapplication/Views/InboxMessageDetail.coffee
+++ client/landing/app/Applications/Inbox.kdapplication/Views/InboxMessageDetail.coffee
@@ -7,7 +7,8 @@
       id               : data.originId
     }

-    group = data.participants.map (participant)->
+    group   = {} unless data.participants
+    group or= data.participants.map (participant)->
       constructorName : participant.sourceName
       id              : participant.sourceId


FEATURE: Ensure comments scroll to bottom

--- src/app/tasks/task-comments-viewer/task-comments-viewer.coffee
+++ src/app/tasks/task-comments-viewer/task-comments-viewer.coffee
@@ -11,7 +11,7 @@
     project: "="
     task: "="
     comment: "=?"
-  controller: ($scope, $modal, $state, TaskFeedback, TaskComment, Task, Project, taskService, alertService, projectService, analyticsService) ->
+  controller: ($scope, $modal, $state, $timeout, currentUser, TaskFeedback, TaskComment, Task, Project, taskService, alertService, projectService, analyticsService) ->
     #
     # Comment code
     #
@@ -55,6 +55,7 @@
         (success) ->
           $scope.comment.text = ""
           analyticsService.event "View Task Comments", "Added new comment"
+          $scope.scrollDown()
         (response) ->
           alertService.add("danger", response.data.error, 2000)

@@ -65,4 +66,11 @@
           analyticsService.event "View Task Comments", "Deleted existing comment"
         (response) ->
           alertService.add("danger", response.data.error, 2000)
+
+    $scope.scrollDown = () ->
+      $timeout (->
+        objDiv = document.getElementsByClassName("task-comments-viewer")
+        wrappedResult = angular.element(objDiv)
+        wrappedResult[0].scrollTop = wrappedResult[0].scrollHeight
+      )
 )


Remove redundand dummy-code

Remove redundand dummy-code

--- src/views/search-results.coffee
+++ src/views/search-results.coffee
@@ -179,7 +179,6 @@
                     @fullCollection.setDefaultComparator()
                 @fullCollection.sort()
                 @render()
-            app.vent.on "alert", alert()

         serializeData: ->
             if @hidden or not @collection?


Displaying error msg declared in Gravity when a user cannot delete their account

--- src/desktop/apps/user/components/delete_my_account/view.coffee
+++ src/desktop/apps/user/components/delete_my_account/view.coffee
@@ -54,11 +54,7 @@
         href: '/user/delete'
         autoclose: false
         safe: false
-        message: """
-          An error prevented us from deleting your account through this form.
-          Please reload the page and try again.
-          If the problem persists, contact support@artsy.net.
-        """
+        message: err.responseJSON.message

   render: ->
     @$el.html template()


factored view class code for menues

factored view class code for menues

--- static/coffee-script/app.coffee
+++ static/coffee-script/app.coffee
@@ -107,12 +107,7 @@
 Views
 ###

-Weathermaps.GroupListView = Ember.View.extend {
-  templateName: 'grouplist'
-  active: true #always visible
-
-  valueBinding: 'Weathermaps.groups.value'
-  optionsBinding: 'Weathermaps.groups.options'
+MainMenuView = Ember.View.extend {

   title: (->
     value = @get 'value'
@@ -125,7 +120,16 @@

 }

-Weathermaps.MapListView = Ember.View.extend {
+Weathermaps.GroupListView = MainMenuView.extend {
+  templateName: 'grouplist'
+  active: true #always visible
+
+  valueBinding: 'Weathermaps.groups.value'
+  optionsBinding: 'Weathermaps.groups.options'
+
+}
+
+Weathermaps.MapListView = MainMenuView.extend {
   templateName: 'maplist'
   groupBinding: 'Weathermaps.groups.value'
   active: (->
@@ -134,19 +138,10 @@

   valueBinding: 'Weathermaps.maps.value'
   optionsBinding: 'Weathermaps.maps.options'
-
-  title: (->
-    value = @get 'value'
-    if value then value else 'Map name'
-  ).property('value')
-
-  select: (e) ->
-    $(e.target).parents('.open').removeClass('open')
-    @set 'value', e.context
-
+
 }

-Weathermaps.DateListView = Ember.View.extend {
+Weathermaps.DateListView = MainMenuView.extend {
   templateName: 'datelist'
   groupBinding: 'Weathermaps.groups.value'
   mapBinding:   'Weathermaps.maps.value'
@@ -156,19 +151,10 @@

   valueBinding: 'Weathermaps.dates.value'
   optionsBinding: 'Weathermaps.dates.options'
-
-  title: (->
-    value = @get 'value'
-    if value then value else 'Date'
-  ).property('value')
-
-  select: (e) ->
-    $(e.target).parents('.open').removeClass('open')
-    @set 'value', e.context
-
+
 }

-Weathermaps.TimeListView = Ember.View.extend {
+Weathermaps.TimeListView = MainMenuView.extend {
   templateName: 'datelist'
   groupBinding: 'Weathermaps.groups.value'
   mapBinding:   'Weathermaps.maps.value'
@@ -179,16 +165,7 @@

   valueBinding: 'Weathermaps.times.value'
   optionsBinding: 'Weathermaps.times.options'
-
-  title: (->
-    value = @get 'value'
-    if value then value else 'Time'
-  ).property('value')
-
-  select: (e) ->
-    $(e.target).parents('.open').removeClass('open')
-    @set 'value', e.context
-
+
 }

 #init


activity feed: add docs; format fixes

activity feed: add docs; format fixes

--- client/app/Applications/Activity.kdapplication/AppController.coffee
+++ client/app/Applications/Activity.kdapplication/AppController.coffee
@@ -124,10 +124,15 @@
     @lastTo   = cache.to
     @lastFrom = cache.from

+  # Refreshes activity feed.
+  #
+  # If no response is returned in 5 secs, we assume user has
+  # been disconnected so long, his/her channel subscription is
+  # dead, so we reconnect.
   refresh:->
     @populateActivity {},\
       KD.utils.getTimedOutCallback (err, items)->
-        log 'refresh'
+        log 'refreshing activity feed'
       , =>
         @isLoading = no
         @status.disconnect()
@@ -323,4 +328,3 @@
           if err then callback err
           else
             callback instances
-


actually send sort order in request

actually send sort order in request

--- resources/assets/coffee/react/_components/comment-show-more.coffee
+++ resources/assets/coffee/react/_components/comment-show-more.coffee
@@ -82,7 +82,7 @@
       commentable_type: @props.parent?.commentable_type ? @props.commentableType
       commentable_id: @props.parent?.commentable_id ? @props.commentableId
       parent_id: @props.parent?.id ? 0
-      sort: @props.sort
+      sort: uiState.comments.currentSort

     lastComment = _.last(@props.comments)
     if lastComment?


Refactor pause menu

Refactor pause menu

--- app/scripts/lib/PauseMenu.coffee
+++ app/scripts/lib/PauseMenu.coffee
@@ -11,15 +11,37 @@
       else
         @remove()

-  soundText: ->
-    if Crafty.audio.muted
-      'Sound [off]'
-    else
-      'Sound [on]'
+  createMenu: ->
+    @_buildMenu([
+      {
+        text: 'Resume'
+        execute: ->
+          Game.togglePause()
+      }
+      {
+        text: ->
+          if Crafty.audio.muted then 'Sound [off]' else 'Sound [on]'
+        execute: ->
+          Crafty.audio.toggleMute()
+      }
+      {
+        text: 'Restart'
+        execute: ->
+          Game.togglePause()
+          Game.resetCredits()
+          Crafty('Player').each -> @softReset()
+          Crafty.enterScene Game.firstLevel
+      }
+      {
+        text: 'Quit'
+        execute: ->
+          Game.togglePause()
+          Crafty('Player').each -> @reset()
+          Crafty.enterScene 'Intro'
+      }
+    ])

-  createMenu: ->
-    @options = ['Resume', @soundText(), 'Restart', 'Quit']
-
+  _buildMenu: (@options) ->
     menu = Crafty.e('2D, DOM, Color, PauseMenu')
       .attr(
         x: - Crafty.viewport.x + (.35 * Crafty.viewport.width),
@@ -48,7 +70,7 @@
       )
     menu.attach title

-    @optionEntities = for o, i in @options
+    for o, i in @options
       menuItem = Crafty.e('2D, DOM, Text')
         .attr(
           x: menu.x + 60
@@ -56,7 +78,7 @@
           w: menu.w - 60
           z: 110
         )
-        .text(o)
+        .text(o.text?() ? o.text)
         .textColor('#D0D0D0')
         .css("textAlign", "left")
         .textFont(
@@ -65,7 +87,7 @@
           family: 'Press Start 2P'
         )
       menu.attach menuItem
-      menuItem
+      o.entity = menuItem

     @selected = 0

@@ -102,25 +124,14 @@

   updateSelection: ->
     @selectionChar.attr(
-      y: @optionEntities[@selected].y
+      y: @options[@selected].entity.y
     )

   _handleFire: =>
     setTimeout =>
-      if @selected is 0
-        Game.togglePause()
-      if @selected is 1
-        Crafty.audio.toggleMute()
-        @optionEntities[@selected].text @soundText()
-      if @selected is 2
-        Game.togglePause()
-        Game.resetCredits()
-        Crafty('Player').each -> @softReset()
-        Crafty.enterScene Game.firstLevel
-      if @selected is 3
-        Game.togglePause()
-        Crafty('Player').each -> @reset()
-        Crafty.enterScene 'Intro'
+      selected = @options[@selected]
+      selected.execute()
+      selected.entity.text(selected.text?() ? selected.text)

   showPlayers: ->
     Crafty('Player').each ->


config: make KONFIG generation more configurable

--- config/generateKonfig.coffee
+++ config/generateKonfig.coffee
@@ -30,7 +30,7 @@
     name: "broker"
     serviceGenericName: "broker"
     ip: ""
-    webProtocol: "http:"
+    webProtocol: options.protocol
     host: "#{options.customDomain.public}"
     port: 8008
     certFile: ""
@@ -144,7 +144,7 @@
     eventExchangeName      : "BrokerMessageBus"
     proxyUrl               : "#{options.customDomain.local}/api/social"
     port                   : "7000"
-    configFilePath         : "#{options.projectRoot}/go/src/socialapi/config/dev.toml"
+    configFilePath         : "#{options.projectRoot}/go/src/socialapi/config/#{options.configName}.toml"
     disableCaching         : no
     debug                  : no

@@ -217,7 +217,7 @@
     webserver                     : { port: 8080, useCacheHeader: no , kitePort: 8860 }
     authWorker                    : { login: credentials.rabbitmq.login, queueName: options.socialQueueName+'auth'   , authExchange     : "auth", authAllExchange: "authAll", port : 9530 }
     social                        : { port: 3030, login: "#{credentials.rabbitmq.login}", queueName: options.socialQueueName, kitePort: 8760 }
-    boxproxy                      : { port: 8090 }
+    boxproxy                      : { port: parseInt(options.publicPort, 10) }
     sourcemaps                    : { port: 3526 }
     rerouting                     : { port: 9500 }
     gowebserver                   : { port: 6500 }


Handle open messages

Handle open messages

--- virtual-file-system/main.coffee
+++ virtual-file-system/main.coffee
@@ -42,8 +42,8 @@
     messageCallbacks =
       init: @onRecievedInit
       sync: @onRecievedSync
-      open: @onRecievedOpen
-      fetch: @onRecievedFetch
+      open: @onRecievedFetchOrOpen
+      fetch: @onRecievedFetchOrOpen
       change: @onRecievedChange
       rescue: @onRecievedRescue

@@ -114,7 +114,7 @@
     @treeView()?.selectEntryForPath(path)
     @sync(parent.path)

-  onRecievedFetch: ({path, content}) =>
+  onRecievedFetchOrOpen: ({path, content}) =>
     # TODO: preserve full stats
     node = @getNode(path)
     node.setContent(content)
@@ -135,20 +135,6 @@
     else
       fs.writeFile(node.localPath(), node.read())

-  onRecievedOpen: ({path, attributes, content}) =>
-    localPath = convert.remoteToLocal(path)
-    dirname = _path.dirname(localPath)
-    return unless localPath? and dirname?
-    return if fs.existsSync(localPath)
-
-    fs.makeTreeSync(dirname) unless fs.existsSync(dirname)
-    decoded = new Buffer(content, 'base64').toString('utf8')
-    fs.writeFileSync(localPath, decoded)
-
-    buffer = atom.project.findBufferForPath(localPath)
-    buffer.updateCachedDiskContentsSync()
-    buffer.reload()
-
   onRecievedRescue: ({message, backtrace}) ->
     console.log 'RESCUE:', message, backtrace


fix(ngAnimate): remove unused module

fix(ngAnimate): remove unused module

--- app/templates/src/app/app.coffee
+++ app/templates/src/app/app.coffee
@@ -1,6 +1,5 @@
 class App extends App
 	@constructor = [
-		'ngAnimate'
 		<% if (environment === 'dev') { %>'ngMockE2E'<% } %>
 		'ngRoute'
 	]


Don't start drawing Surface until needed.

--- app/views/play/level_view.coffee
+++ app/views/play/level_view.coffee
@@ -185,10 +185,6 @@
     @levelLoader = null
     @initSurface()
     @initScriptManager()
-    @surface.showLevel()
-    if @otherSession
-      # TODO: colorize name and cloud by team, colorize wizard by user's color config
-      @surface.createOpponentWizard id: @otherSession.get('creator'), name: @otherSession.get('creatorName'), team: @otherSession.get('team')

   grabLevelLoaderData: ->
     @session = @levelLoader.session
@@ -215,6 +211,10 @@
       @session.set 'multiplayer', false

   onLevelStarted: (e) ->
+    @surface.showLevel()
+    if @otherSession
+      # TODO: colorize name and cloud by team, colorize wizard by user's color config
+      @surface.createOpponentWizard id: @otherSession.get('creator'), name: @otherSession.get('creatorName'), team: @otherSession.get('team')
     @loadingView?.unveil()

   onLoadingViewUnveiled: (e) ->


form input options can be taken from model automatically if none passed.

--- public/js/lib/singool/helpers/form.coffee
+++ public/js/lib/singool/helpers/form.coffee
@@ -62,13 +62,18 @@
       out += @input field, options
     out

-  input: (field, options) ->
-    _options =
-      type: 'text'
-      label: field
-      value: null
+  input: (field, options = {}) ->
+    if _.isEmpty(options) and @model
+      _options = @model.schema[field]
+    else
+      _options =
+        type: 'text'
+        label: field
+        value: null
+
     if @model and @model.get field
       _options.value = @model.get field
+
     options = _.defaults options, _options
     out = @[options.type] field, options
     out


#1000 Fix typo -> Fix volume annotation redraw

--- app/assets/javascripts/oxalis/model/binary/plane2d.coffee
+++ app/assets/javascripts/oxalis/model/binary/plane2d.coffee
@@ -79,7 +79,7 @@
           @dataTexture.ready &= not (u in [@dataTexture.area[0]..@dataTexture.area[2]] and v in [@dataTexture.area[1]..@dataTexture.area[3]])
     )

-    @cube.on "volumeLabled", => @reset()
+    @cube.on "volumeLabeled", => @reset()
     @cube.on "mappingChanged", => @reset()


getting rid of binds

getting rid of binds

--- app/assets/javascripts/uploadcare/widget/dialog.js.coffee
+++ app/assets/javascripts/uploadcare/widget/dialog.js.coffee
@@ -39,16 +39,15 @@
           @reject() if e.target == e.currentTarget

         closeButton = @content.find('@uploadcare-dialog-close')
-        closeButton.on 'click', @reject.bind(this)
+        closeButton.on 'click', => @reject()

         $(window).on 'keydown', (e) =>
           @reject() if e.which == 27 # Escape

         @tabs = {}
         for tabName in @settings.tabs when tabName not of @tabs
-          tab = @_addTab(tabName)
-          throw "No such tab: #{tabName}" unless tab
-          @tabs[tabName] = tab
+          @tabs[tabName] = @_addTab(tabName)
+          throw "No such tab: #{tabName}" unless @tabs[tabName]

         @_switchTab(@settings.tabs[0])
         @content.fadeIn('fast')
@@ -69,7 +68,7 @@

         return false if not tabCls

-        tab = new tabCls this, @settings, @resolve.bind(this)
+        tab = new tabCls this, @settings, => @resolve()

         if tab
           $('<li>')


Maintenance: Skip null values for the param check to prevent errors on the to string cast.

--- app/assets/javascripts/app/controllers/ticket_zoom/form_handler_core_workflow.coffee
+++ app/assets/javascripts/app/controllers/ticket_zoom/form_handler_core_workflow.coffee
@@ -127,7 +127,7 @@
         for value in values

           # false values are valid values e.g. for boolean fields (be careful)
-          if value isnt undefined && paramValue isnt undefined
+          if value isnt undefined && paramValue isnt undefined && value isnt null && paramValue isnt null
             if value.toString() == paramValue.toString()
               valueFound = true
               break


DE21067: Fixed merge conflict.

DE21067: Fixed merge conflict.

--- test/spec/iterationtrackingboard/IterationTrackingBoardAppSpec.coffee
+++ test/spec/iterationtrackingboard/IterationTrackingBoardAppSpec.coffee
@@ -112,7 +112,7 @@
       @app.down('rallytreegrid').on 'storecurrentpagereset', storeCurrentPageResetStub

       newScope = Ext.create('Rally.app.TimeboxScope',
-        record: new @IterationModel @iterationData[1]
+        record: @mom.getRecord('iteration', values: @iterationData[1])
       )

       @app.onTimeboxScopeChange newScope


Fixed SVGPath.end

Fixed SVGPath.end

Thanks @marckrenn!


rename method to bind_link_events

rename method to bind_link_events

--- lib/assets/javascripts/stark/view.js.coffee
+++ lib/assets/javascripts/stark/view.js.coffee
@@ -107,7 +107,7 @@
     @$el.html(@render_html())

     @bind_app_events()
-    @attach_link_events()
+    @bind_link_events()
     @bind_models()
     @after_render()
     _.each @after_render_hooks, (hook) ->
@@ -121,9 +121,9 @@
     # noop

   # Process @links hash and attach events
-  attach_link_events: ->
-
-    @log "attach_link_events", @
+  bind_link_events: ->
+
+    @log "bind_link_events", @

     if not @links?
       @log "binding events: ", @, @events
@@ -361,7 +361,7 @@
   # the parent view's template
   post_render: ->
     @setElement( @parent.$("span#" + @span_id) )
-    @attach_link_events()
+    @bind_link_events()
     @bind_models()
     @after_render()
     return @


Allow markdown preview view to be scrolled with core:move-up/move-down

--- src/packages/markdown-preview/lib/markdown-preview-view.coffee
+++ src/packages/markdown-preview/lib/markdown-preview-view.coffee
@@ -16,6 +16,8 @@
   initialize: (@buffer) ->
     super
     @fetchRenderedMarkdown()
+    @on 'core:move-up', => @scrollUp()
+    @on 'core:move-down', => @scrollDown()

   serialize: ->
     deserializer: 'MarkdownPreviewView'


Improved highlight animation when clicking on the "read all" navbar button.

--- app/assets/javascripts/ng-services/ng-AnimationsSvc.js.coffee
+++ app/assets/javascripts/ng-services/ng-AnimationsSvc.js.coffee
@@ -271,9 +271,8 @@
     #---------------------------------------------
     highlight_read_all_button: ->
       $('#read-all-button')
-        .velocity({backgroundColor: '#e7e7e7', color: '#555', borderColor: '#428bca'},
-          {duration: 300, easing: 'swing'})
-        .velocity('reverse', {duration: 300, easing: 'swing'})
+        .velocity({backgroundColor: '#e7e7e7'}, {duration: 300, easing: 'swing'})
+        .velocity({backgroundColorAlpha: 0}, {duration: 300, easing: 'swing'})

   return service
 ]


remove compactions from legend

remove compactions from legend

--- app/assets/javascripts/views/regions/RegionMetricChart.coffee
+++ app/assets/javascripts/views/regions/RegionMetricChart.coffee
@@ -45,6 +45,8 @@
         graph: @graph,
         element: @$('.timeline')[0]

+      @createCompactionAnnotations(compactionsSeries) if compactionsSeries
+
       @legend = new Rickshaw.Graph.Legend
         graph: @graph
         element: @$(".legend")[0]
@@ -53,9 +55,10 @@
         graph: @graph
         legend: @legend

-      @createCompactionAnnotations(compactionsSeries) if compactionsSeries
       @graph.render()
+
       @colorizeAnnotations(compactionsSeries.color) if compactionsSeries
+
       @trigger "graph_rendered"

       $(".timeline").delegate(".annotation", 'mouseover',( (e) ->
@@ -67,6 +70,7 @@
       ));

   createCompactionAnnotations: (compactions) ->
+    compactions.noLegend = true
     metric = compactions.metric
     values = metric.getValues()
     start = Math.round(metric.getBegin() / 1000)


Modified in browser at pixie.strd6.com

Modified in browser at pixie.strd6.com

--- test/function_extensions.coffee
+++ test/function_extensions.coffee
@@ -29,7 +29,8 @@
     ).once()

   onceScore()
-  onc
+  onceScore()
+

 test "#returning", ->
   x = 0