Activity: data method parameter is renamed as post for SettingsView

--- client/Social/Activity/views/settingsview.coffee
+++ client/Social/Activity/views/settingsview.coffee
@@ -19,18 +19,19 @@
       new KDCustomHTMLView tagName : 'span', cssClass : 'hidden'

-  settingsMenu:(data)->
+  settingsMenu:(post)->

     account        = KD.whoami()

-    if data.originId is account.getId()
+    if post.originId is account.getId()
       menu =
         'Edit'     :
-          callback : ->
-            KD.getSingleton("appManager").tell "Activity", "editActivity", data
+          callback : =>
+            @emit 'ActivityEditIsClicked'
+            # KD.getSingleton("appManager").tell "Activity", "editActivity", post
         'Delete'   :
           callback : =>
-            @confirmDeletePost data
+            @confirmDeletePost post

       return menu

@@ -39,26 +40,26 @@
         menu =
           'Unmark User as Troll' :
             callback             : ->
-              activityController.emit "ActivityItemUnMarkUserAsTrollClicked", data
+              activityController.emit "ActivityItemUnMarkUserAsTrollClicked", post
       else
         menu =
           'Mark User as Troll' :
             callback           : ->
-              activityController.emit "ActivityItemMarkUserAsTrollClicked", data
+              activityController.emit "ActivityItemMarkUserAsTrollClicked", post

       menu['Delete Post'] =
         callback : =>
-          @confirmDeletePost data
+          @confirmDeletePost post

       menu['Block User'] =
         callback : ->
-          activityController.emit "ActivityItemBlockUserClicked", data.originId
+          activityController.emit "ActivityItemBlockUserClicked", post.originId

       return menu

   viewAppended: -> @addSubView @settings

-  confirmDeletePost:(data)->
+  confirmDeletePost:(post)->

     modal = new KDModalView
       title          : "Delete post"
@@ -73,13 +74,13 @@
             diameter : 16
           callback   : =>

-            if data.fake
+            if post.fake
               @emit 'ActivityIsDeleted'
               modal.buttons.Delete.hideLoader()
               modal.destroy()
               return

-            data.delete (err)=>
+            post.delete (err)=>
               modal.buttons.Delete.hideLoader()
               modal.destroy()
               unless err then @emit 'ActivityIsDeleted'


client: rename AMEX to AMERICAN_EXPRESS

client: rename AMEX to AMERICAN_EXPRESS

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

--- client/component-lab/CreditCard/constants.coffee
+++ client/component-lab/CreditCard/constants.coffee
@@ -1,15 +1,17 @@
+DOT = '•'
+
 Placeholder =
-  NUMBER: '•••• •••• •••• ••••'
+  NAME: '••••• •••••'
   EXP_MONTH: 'MM'
   EXP_YEAR: 'YY'
+  NUMBER: '•••• •••• •••• ••••'
   CVC: '•••'
-  NUMBER_AMEX: '•••• •••••• •••••'
-  CVC_AMEX: '••••'
-  NAME: '••••• •••••'
+  NUMBER_AMERICAN_EXPRESS: '•••• •••••• •••••'
+  CVC_AMERICAN_EXPRESS: '••••'

 NumberPattern =
   DEFAULT: [4, 4, 4, 4]
-  AMEX: [4, 6, 5]
+  AMERICAN_EXPRESS: [4, 6, 5]

 Brand =
   JCB: 'jcb'
@@ -21,7 +23,6 @@
   VISA: 'visa'
   DEFAULT: 'default'

-DOT = '•'

 module.exports = {
   Placeholder, NumberPattern, Brand, DOT


Update Opera 17 prefixes

Update Opera 17 prefixes


Fattable

Fattable

--- fattable.coffee
+++ fattable.coffee
@@ -484,8 +484,6 @@
             else
                 orig_j = @firstVisibleColumn + @nbColsVisible - dj + offset_j
                 dest_j = j + offset_j
-                if dest_j >= @nbColsVisible
-                    break
             col_x = @columnOffset[dest_j] + "px"
             col_width = @columnWidths[dest_j] + "px"


if we're in the staging env, don't use live box servers

we absolutely should consider putting plans.json in the DB

--- server/code/model/box.coffee
+++ server/code/model/box.coffee
@@ -168,6 +168,8 @@
     Math.floor(Math.random() * (max - min + 1)) + min

   @listServers: ->
+    if /staging/.test process.env.NODE_ENV
+      return [process.env.CU_BOX_SERVER]
     obj.boxServer for plan, obj of plans


add missing attribute 'n' to contact model

--- server/models/contact.coffee
+++ server/models/contact.coffee
@@ -4,6 +4,7 @@
 module.exports = americano.getModel 'Contact',
     id : String
     fn : String
+    n : String
     datapoints : [Object]
     note : String
     _attachments : Object


Update php.coffee

Update php.coffee

--- data/tags/php.coffee
+++ data/tags/php.coffee
@@ -4,4 +4,5 @@
 desc: "生产环境中最常用的服务端编程语言。"
 reference:
   "PHP 中文手册": "http://www.php.net/manual/zh/"
-  "PHP 安全编码": "http://fe.baidu.com/doc/websafe/websafeCriterion/php.html"+  "PHP 安全编码": "http://fe.baidu.com/doc/websafe/websafeCriterion/php.html"
+  "PHP 最佳实践": "http://youngsterxyf.github.io/2013/06/01/php-best-practices/"


Fix fireAgent

Fix fireAgent

--- assets/game_state.coffee
+++ assets/game_state.coffee
@@ -12,10 +12,12 @@
   agentSpawner: AgentSpawner()

   addAgent: (agent) ->
-    @agents.append(agent)
+    @agents.push(agent)

   fireAgent: (agent) ->
-    @agents.pop(agent)
+    @agents.filter((item) ->
+      item != agent
+    )

   calculateReputation: ->
     totalWorth = 0


StackTemplateHelper: generateStackMachineData helper

--- workers/social/testhelper/models/computeproviders/stacktemplatehelper.coffee
+++ workers/social/testhelper/models/computeproviders/stacktemplatehelper.coffee
@@ -5,6 +5,20 @@

 JStackTemplate = require  \
   '../../../../social/lib/social/models/computeproviders/stacktemplate'
+
+
+generateStackMachineData = (count = 1) ->
+
+  machines = []
+  for i in [1..count]
+    machines.push
+      label         : "testvm-#{i}"
+      region        : 'us-east-1'
+      provider      : 'aws'
+      source_ami    : 'ami-a6926dce'
+      instance_type : 't2.nano'
+
+  return machines

 generateStackTemplateData = (client, data) ->
@@ -60,6 +74,7 @@

 module.exports = {
   createStackTemplate
+  generateStackMachineData
   generateStackTemplateData
   withConvertedUserAndStackTemplate
 }


Correctly respond to tickles. Sorta.

Correctly respond to tickles. Sorta.

--- src/pushbullet.coffee
+++ src/pushbullet.coffee
@@ -24,21 +24,24 @@
 pushbullet = new PushBullet apiKey

 module.exports = (robot) ->
+
+  latestPush =
+    limit: 1
+    modified_after: 0
+
   if process.env.HUBOT_PUSHBULLET_STREAM
     console.log "Pushbullet streaming is #{if process.env.HUBOT_PUSHBULLET_STREAM then 'on' else 'off'}"
     pbStream = pushbullet.stream()
-    pbStream.on 'push', (push) ->
-      console.log "got a push: #{push.title}"
     pbStream.on 'tickle', (type) ->
-      console.log "PB: tickle! (#{type})"
+      lastPush = pushbullet
+      pushbullet.history lastPush, (err, res) ->
+        if not err
+          console.log "Got a tickle. Here's the last push's title: #{res.pushes[0].title}"
     pbStream.connect()

   robot.respond /(?:pb|pushbullet) last/, (msg) ->
-    options =
-      limit: 1,
-      modified_after: 0

-    pushbullet.history options, (err, res) ->
+    pushbullet.history latestPush, (err, res) ->
       if not err
         push = res.pushes[0]
         msg.send "Last push was \"#{push.title}\" from #{push.sender_name}"


Make report page fetch page association

Make report page fetch page association

--- server/routes/reports.coffee
+++ server/routes/reports.coffee
@@ -16,7 +16,12 @@
       return res.render(500, "Could not retrieve report")

     if report?
-      res.render "reports/show", reportData: JSON.stringify report
+      report.toObjectWithNestedPage().then( (reportObject) ->
+        res.render "reports/show", reportData: JSON.stringify reportObject
+      ).fail( (err) ->
+        console.error err
+        res.render(500)
+      )
     else
       res.render(404)
   )


Allow guess credit card to accept hyphenated numbers

--- _source/lib/lib/regex.coffee
+++ _source/lib/lib/regex.coffee
@@ -45,6 +45,8 @@

   guessCardType: (number) ->

+    number = number.replace /-/g, ''
+
     for cardType in Apollos.validate.acceptedCardTypes

       if Apollos.validate["isStartOf#{cardType}"] number
@@ -54,6 +56,8 @@

   getCardType: (number) ->
+
+    number = number.replace /-/g, ''

     for cardType in Apollos.validate.acceptedCardTypes


Add fallback to avatar file

Add fallback to avatar file

--- server/startup/avatar.coffee
+++ server/startup/avatar.coffee
@@ -114,7 +114,7 @@
 		res.setHeader 'Cache-Control', 'public, max-age=0'
 		res.setHeader 'Expires', '-1'
 		res.setHeader 'Last-Modified', file.uploadDate?.toUTCString() or new Date().toUTCString()
-		res.setHeader 'Content-Type', file.contentType
+		res.setHeader 'Content-Type', file.contentType or 'image/jpeg'
 		res.setHeader 'Content-Length', file.length

 		file.readStream.pipe res


Add getTweet

Add getTweet

--- src/Carrot.coffee
+++ src/Carrot.coffee
@@ -119,7 +119,6 @@
       {'value': score}, @callbackHandler(callback))

   postAction: (actionId, objectInstanceId, actionProperties, objectProperties, callback) ->
-    # TODO: Error checking for required properties
     actionProperties = if typeof actionProperties is "string" then actionProperties else JSON.stringify(actionProperties || {})
     objectProperties = if typeof objectProperties is "string" then objectProperties else JSON.stringify(objectProperties || {})
     params = {
@@ -130,7 +129,25 @@
     params['object_instance_id'] = objectInstanceId if objectInstanceId
     @postSignedRequest("/me/actions.json", params, @callbackHandler(callback))

+  getTweet: (actionId, objectInstanceId, actionProperties, objectProperties, callback) ->
+    actionProperties = if typeof actionProperties is "string" then actionProperties else JSON.stringify(actionProperties || {})
+    objectProperties = if typeof objectProperties is "string" then objectProperties else JSON.stringify(objectProperties || {})
+    params = {
+      'action_id': actionId,
+      'action_properties': actionProperties,
+      'object_properties': objectProperties
+    }
+    params['object_instance_id'] = objectInstanceId if objectInstanceId
+    @getSignedRequest("/me/tweet.json", params, (jqXHR) -> callback(jqXHR.responseJSON) if callback)
+
+  getSignedRequest: (endpoint, query_params, callback) ->
+    query_params['_method'] = "GET"
+    @doSignedRequest(endpoint, query_params, callback)
+
   postSignedRequest: (endpoint, query_params, callback) ->
+    @doSignedRequest(endpoint, query_params, callback)
+
+  doSignedRequest: (endpoint, query_params, callback) ->
     url_params = {
       'api_key': @udid,
       'game_id': @appId,


Refactored: better code organization

Refactored: better code organization

--- fixtures.coffee
+++ fixtures.coffee
@@ -7,243 +7,193 @@

 # Connection to the data system
 client = new Client "http://localhost:9101/"
+dataCollection = []
+
+###
+TODO: making the tool more generic (loading data fixtures from other files)
+###
+
+# Agenda meta doctype document
+dataCollection.push
+    docType: "metaDoctype"
+    related: "Alarm" # what doctype this document describes
+    displayName: "Alarme"
+    identificationField: "description"
+    fields: [
+        "action":
+            displayName: "Action"
+            description: "Représente le canal de diffusion de l'alarme dans le format iCal (DISPLAY, EMAIL, AUDIO)"
+        "trigg":
+            displayName: "Date de déclenchement"
+            description: "Date à laquelle l'alarme doit être déclenchée"
+        "related":
+            displayName: "En relation"
+            description: "Si cette alarme a été créée en relation avec un autre document, ce champ permet de spécifier l'identifiant de ce document."
+    ]
+
+# Agenda documents
+dataCollection.push
+    docType: "Alarm"
+    action: "DISPLAY"
+    trigg: "Tue Jul 08 2013 14:30:00"
+    description: "Réunion scopyleft"
+    related: null
+
+dataCollection.push
+    docType: "Alarm"
+    action: "DISPLAY"
+    trigg: "Tue Jul 19 2013 09:00:00"
+    description: "Réunion MesInfos"
+    related: null
+
+dataCollection.push
+    docType: "Alarm"
+    action: "DISPLAY"
+    trigg: "Tue Jul 02 2013 16:00:00"
+    description: "Réunion review scopyleft"
+    related: null
+
+# Contact meta doctype document
+dataCollection.push
+    docType: "metaDoctype"
+    related: "Contact" # what doctype this document describes
+    displayName: "Contact"
+    identificationField: "fn"
+    fields: [
+        "fn":
+            displayName: "Nom complet"
+            description: "Le nom complet du contact."
+        "datapoints":
+            displayName: "Données complémentaires"
+            description: "Tabeau contenant des données complémentaires sur le contact."
+        "note":
+            displayName: "Note"
+            description: "Une note sur le contact."
+    ]
+
+# Contact documents
+dataCollection.push
+    docType: "Contact"
+    fn: "Joseph Silvestre"
+    datapoints: [
+        {
+            name: "about"
+            type: "birthday"
+            value: "02/02/1990"
+            id: 1
+        },
+        {
+            name: "tel"
+            type: "main"
+            value: "+33 12 34 56 78"
+            id: 2
+        }
+    ]
+    note: "Données complémentaires sur le contact."
+
+dataCollection.push
+    docType: "Contact"
+    fn: "David Larlet"
+    datapoints: [
+        {
+            name: "about"
+            type: "birthday"
+            value: "02/02/1980"
+            id: 1
+        },
+        {
+            name: "tel"
+            type: "main"
+            value: "+33 12 34 56 78"
+            id: 2
+        }
+    ]
+    note: "Données complémentaires sur le contact."
+
+# Task meta doctype document
+dataCollection.push
+    docType: "metaDoctype"
+    related: "Task" # what doctype this document describes
+    displayName: "Tâche"
+    identificationField: "description"
+    fields: [
+        "description":
+            displayName: "Description"
+            description: "Le contenu de la tâche."
+        "done":
+            displayName: "Fait?"
+            description: "Indique si la tâche a été réalisée ou pas."
+        "creationDate":
+            displayName: "Date de création"
+            description: "Date à laquelle la tâche a été créée."
+        "completionDate":
+            displayName: "Date de complétion"
+            description: "Date à laquelle la tâche a été marquée comme faite."
+        "previousTask":
+            displayName: "Tâche précédente"
+            description: "Une référence à la tâche précédente dans la liste."
+        "nextTask":
+            displayName: "Tâche suivante"
+            description: "Une référence à la tâche suivante dans la liste."
+        "list":
+            displayName: "Liste"
+            description: "Une référence à la liste à laquelle appartient la tâche."
+        "tags":
+            displayName: "Tags"
+            description: "Les tags liés à la tâche."
+    ]
+
+# Task documents
+dataCollection.push
+    docType: "Task"
+    id: "29aba0e2c27d5406dcc05bc919001d4d"
+    description: "Ma super todo à faire"
+    done: false
+    completionDate: null
+    creationDate: "1373360685861"
+    previousTask: "29aba0e2c27d5406dcc05bc919001b1b"
+    nextTask: null
+    list: "29aba0e2c27d5406dcc05bc919001b1b"
+    tags: []
+
+dataCollection.push
+    docType: "Task"
+    id: "29aba0e2c27d5406dcc05bc919002138"
+    description: "Une autre #super tâche"
+    done: false
+    completionDate: null
+    creationDate: "1373360689162"
+    previousTask: "29aba0e2c27d5406dcc05bc9190027c2"
+    nextTask: "29aba0e2c27d5406dcc05bc919001d4d"
+    list: "29aba0e2c27d5406dcc05bc919001b1b"
+    tags: ["super"]
+
+dataCollection.push
+    docType: "Task"
+    id: "29aba0e2c27d5406dcc05bc9190027c2"
+    description: "Encore une #super tâche"
+    done: false
+    completionDate: null
+    creationDate: "1373360693530"
+    previousTask: null
+    nextTask: "29aba0e2c27d5406dcc05bc919002138"
+    list: "29aba0e2c27d5406dcc05bc919001b1b"
+    tags: ["super"]
+
+# Request factory
+# Data are wrapped inside async requests.
+requestFactory = (doc) ->
+    return (callback) ->
+        client.post 'data/', doc, (err, res, body) ->
+            if err?
+                callback("#{res.statusCode} - #{err}", null)
+            else
+               callback(null, 'OK')
+
+# We prepare the requests
 requests = []
-
-
-# Data are wrapped inside async requests. Current state: dirty.
-# TODO: refactoring to separate properly the data from the code
-
-# Agenda meta doctype document
-requests.push (callback) ->
-    doc =
-        docType: "metaDoctype"
-        related: "Alarm" # what doctype this document describes
-        displayName: "Alarme"
-        identificationField: "description"
-        fields: [
-            "action":
-                displayName: "Action"
-                description: "Représente le canal de diffusion de l'alarme dans le format iCal (DISPLAY, EMAIL, AUDIO)"
-            "trigg":
-                displayName: "Date de déclenchement"
-                description: "Date à laquelle l'alarme doit être déclenchée"
-            "related":
-                displayName: "En relation"
-                description: "Si cette alarme a été créée en relation avec un autre document, ce champ permet de spécifier l'identifiant de ce document."
-        ]
-    client.post 'data/', doc, (err, res, body) ->
-        if err?
-            callback("#{res.statusCode} - #{err}", null)
-        else
-           callback(null, 'OK')
-
-# Agenda documents
-requests.push (callback) ->
-    doc =
-        docType: "Alarm"
-        action: "DISPLAY"
-        trigg: "Tue Jul 08 2013 14:30:00"
-        description: "Réunion scopyleft"
-        related: null
-    client.post 'data/', doc, (err, res, body) ->
-        if err?
-            callback("#{res.statusCode} - #{err}", null)
-        else
-           callback(null, 'OK')
-requests.push (callback) ->
-    doc =
-        docType: "Alarm"
-        action: "DISPLAY"
-        trigg: "Tue Jul 19 2013 09:00:00"
-        description: "Réunion MesInfos"
-        related: null
-    client.post 'data/', doc, (err, res, body) ->
-        if err?
-            callback("#{res.statusCode} - #{err}", null)
-        else
-           callback(null, 'OK')
-requests.push (callback) ->
-    doc =
-        docType: "Alarm"
-        action: "DISPLAY"
-        trigg: "Tue Jul 02 2013 16:00:00"
-        description: "Réunion review scopyleft"
-        related: null
-    client.post 'data/', doc, (err, res, body) ->
-        if err?
-            callback("#{res.statusCode} - #{err}", null)
-        else
-           callback(null, 'OK')
-
-# Contact meta doctype document
-requests.push (callback) ->
-    doc =
-        docType: "metaDoctype"
-        related: "Contact" # what doctype this document describes
-        displayName: "Contact"
-        identificationField: "fn"
-        fields: [
-            "fn":
-                displayName: "Nom complet"
-                description: "Le nom complet du contact."
-            "datapoints":
-                displayName: "Données complémentaires"
-                description: "Tabeau contenant des données complémentaires sur le contact."
-            "note":
-                displayName: "Note"
-                description: "Une note sur le contact."
-        ]
-    client.post 'data/', doc, (err, res, body) ->
-        if err?
-            callback("#{res.statusCode} - #{err}", null)
-        else
-           callback(null, 'OK')
-
-# Contact documents
-requests.push (callback) ->
-    doc =
-        docType: "Contact"
-        fn: "Joseph Silvestre"
-        datapoints: [
-            {
-                name: "about"
-                type: "birthday"
-                value: "02/02/1990"
-                id: 1
-            },
-            {
-                name: "tel"
-                type: "main"
-                value: "+33 12 34 56 78"
-                id: 2
-            }
-        ]
-        note: "Données complémentaires sur le contact."
-    client.post 'data/', doc, (err, res, body) ->
-        if err?
-            callback("#{res.statusCode} - #{err}", null)
-        else
-           callback(null, 'OK')
-
-requests.push (callback) ->
-    doc =
-        docType: "Contact"
-        fn: "David Larlet"
-        datapoints: [
-            {
-                name: "about"
-                type: "birthday"
-                value: "02/02/1980"
-                id: 1
-            },
-            {
-                name: "tel"
-                type: "main"
-                value: "+33 12 34 56 78"
-                id: 2
-            }
-        ]
-        note: "Données complémentaires sur le contact."
-    client.post 'data/', doc, (err, res, body) ->
-        if err?
-            callback("#{res.statusCode} - #{err}", null)
-        else
-           callback(null, 'OK')
-
-
-# Task meta doctype document
-requests.push (callback) ->
-    doc =
-        docType: "metaDoctype"
-        related: "Task" # what doctype this document describes
-        displayName: "Tâche"
-        identificationField: "description"
-        fields: [
-            "description":
-                displayName: "Description"
-                description: "Le contenu de la tâche."
-            "done":
-                displayName: "Fait?"
-                description: "Indique si la tâche a été réalisée ou pas."
-            "creationDate":
-                displayName: "Date de création"
-                description: "Date à laquelle la tâche a été créée."
-            "completionDate":
-                displayName: "Date de complétion"
-                description: "Date à laquelle la tâche a été marquée comme faite."
-            "previousTask":
-                displayName: "Tâche précédente"
-                description: "Une référence à la tâche précédente dans la liste."
-            "nextTask":
-                displayName: "Tâche suivante"
-                description: "Une référence à la tâche suivante dans la liste."
-            "list":
-                displayName: "Liste"
-                description: "Une référence à la liste à laquelle appartient la tâche."
-            "tags":
-                displayName: "Tags"
-                description: "Les tags liés à la tâche."
-        ]
-    client.post 'data/', doc, (err, res, body) ->
-        if err?
-            callback("#{res.statusCode} - #{err}", null)
-        else
-           callback(null, 'OK')
-
-# Task documents
-requests.push (callback) ->
-    doc =
-        docType: "Task"
-        id: "29aba0e2c27d5406dcc05bc919001d4d"
-        description: "Ma super todo à faire"
-        done: false
-        completionDate: null
-        creationDate: "1373360685861"
-        previousTask: "29aba0e2c27d5406dcc05bc919001b1b"
-        nextTask: null
-        list: "29aba0e2c27d5406dcc05bc919001b1b"
-        tags: []
-    client.post 'data/', doc, (err, res, body) ->
-        if err?
-            callback("#{res.statusCode} - #{err}", null)
-        else
-           callback(null, 'OK')
-
-requests.push (callback) ->
-    doc =
-        docType: "Task"
-        id: "29aba0e2c27d5406dcc05bc919002138"
-        description: "Une autre #super tâche"
-        done: false
-        completionDate: null
-        creationDate: "1373360689162"
-        previousTask: "29aba0e2c27d5406dcc05bc9190027c2"
-        nextTask: "29aba0e2c27d5406dcc05bc919001d4d"
-        list: "29aba0e2c27d5406dcc05bc919001b1b"
-        tags: ["super"]
-    client.post 'data/', doc, (err, res, body) ->
-        if err?
-            callback("#{res.statusCode} - #{err}", null)
-        else
-           callback(null, 'OK')
-
-requests.push (callback) ->
-    doc =
-        docType: "Task"
-        id: "29aba0e2c27d5406dcc05bc9190027c2"
-        description: "Encore une #super tâche"
-        done: false
-        completionDate: null
-        creationDate: "1373360693530"
-        previousTask: null
-        nextTask: "29aba0e2c27d5406dcc05bc919002138"
-        list: "29aba0e2c27d5406dcc05bc919001b1b"
-        tags: ["super"]
-    client.post 'data/', doc, (err, res, body) ->
-        if err?
-            callback("#{res.statusCode} - #{err}", null)
-        else
-           callback(null, 'OK')
+for doc in dataCollection
+    requests.push requestFactory(doc)

 # We remove the old data
@@ -259,11 +209,15 @@
         callback(err, body)

 # We run the request with async (parallel execution, wait for all the callbacks)
-console.log "Adding #{requests.length} new document to the data system..."
+console.log "Cleaning the database..."
 async.parallel setupRequests, (err, results) ->
-    console.log err if err?
-    async.parallel requests, (err, results) ->
-       if err?
-            console.log err if err?
-        else
-            console.log "#{results.length} documents have successfully added to the data system."+    if err?
+        console.log err
+    else
+        console.log "Database cleaned.."
+        console.log "Adding #{requests.length} new document to the data system..."
+        async.parallel requests, (err, results) ->
+           if err?
+                console.log err if err?
+            else
+                console.log "#{results.length} documents have successfully added to the data system."


Updated atom config

Updated atom config

--- atom.symlink/config.cson
+++ atom.symlink/config.cson
@@ -1,15 +1,15 @@
 "*":
   editor:
     fontFamily: "Menlo"
-    fontSize: 11
     autoIndentOnPaste: false
     invisibles: {}
+    fontSize: 11
   core:
+    projectHome: "/u/work"
     themes: [
       "beacon-ui"
       "base16-tomorrow-dark-theme"
     ]
-    projectHome: "/u/work"
   "exception-reporting":
     userId: "425745cb-d16a-d29f-21a2-e71c5efc21ec"
   welcome:
@@ -23,6 +23,8 @@
   react: {}
   jshint:
     supportLintingJsx: true
+  docblockr:
+    newline_after_block: true
 ".php.source.wordpress":
   editor:
     tabLength: 4


disable whitespace

disable whitespace

--- atom.symlink/config.cson
+++ atom.symlink/config.cson
@@ -42,6 +42,9 @@
   core:
     audioBeep: false
     closeDeletedFileTabs: true
+    disabledPackages: [
+      "whitespace"
+    ]
     excludeVcsIgnoredPaths: false
     ignoredNames: [
       ".git"


Atom: keymap reopen closed item

Atom: keymap reopen closed item

--- atom.symlink/keymap.cson
+++ atom.symlink/keymap.cson
@@ -47,6 +47,7 @@
 'atom-workspace atom-text-editor:not([mini])':
   'ctrl-shift-up': 'editor:move-line-up'
   'ctrl-shift-down': 'editor:move-line-down'
+  'ctrl-shift-t': 'pane:reopen-closed-item'

 '.editor':
   'ctrl-home': 'core:move-to-top'


Returned function that was removed by mistake

--- server/cron/downloadSubmits.coffee
+++ server/cron/downloadSubmits.coffee
@@ -259,6 +259,9 @@
     (page, submitsPerPage) ->
         "http://informatics.mccme.ru/moodle/ajax/ajax.php?problem_id=#{problemId}&group_id=0&user_id=#{userId}&lang_id=-1&status_id=-1&statement_id=0&objectName=submits&count=#{submitsPerPage}&with_comment=&page=#{page}&action=getHTMLTable"

+userUrl = (userId) ->
+    (page, submitsPerPage) ->
+        "http://informatics.mccme.ru/moodle/ajax/ajax.php?problem_id=0&group_id=0&user_id=#{userId}&lang_id=-1&status_id=-1&statement_id=0&objectName=submits&count=#{submitsPerPage}&with_comment=&page=#{page}&action=getHTMLTable"

 url = (group) -> (page, submitsPerPage) ->
         "http://informatics.mccme.ru/moodle/ajax/ajax.php?problem_id=0&group_id=#{group}&user_id=0&lang_id=-1&status_id=-1&statement_id=0&objectName=submits&count=#{submitsPerPage}&with_comment=&page=#{page}&action=getHTMLTable"
@@ -267,7 +270,7 @@
 for group, infGroup of groups.GROUPS
     urls[group] = url(infGroup)

-
+
 running = false

 wrapRunning = (callable) ->


windows is yet to need a public key

windows is yet to need a public key

--- app/assets/javascripts/uploadcare/widget/adapters/instagram-adapter.js.coffee
+++ app/assets/javascripts/uploadcare/widget/adapters/instagram-adapter.js.coffee
@@ -27,7 +27,7 @@

           @createWatcher()

-          src = "#{@widget.settings.socialBase}/window/instagram?window_id=#{@window_id}&pub_key=#{@widget.settings.pub_key}"
+          src = "#{@widget.settings.socialBase}/window/instagram?window_id=#{@window_id}"
           @iframe = jQuery('<iframe>')
                       .attr('src', src)
                       .css


we need to prepend 'atom-' when dealing with our string literals, because the literal could be __proto__.  Revisit and fix when we support ES6 Maps.


PUBDEV-2597 Append description to CM output

--- src/ext/components/model-output.coffee
+++ src/ext/components/model-output.coffee
@@ -169,7 +169,7 @@
       rows.push tr cells

     _plots.push
-      title: title
+      title: title + if cm.description then " #{cm.description}" else ''
       plot: signal Flow.HTML.render 'div', table tbody rows
       frame: signal null
       controls: signal null


Fix linting error

Fix linting error

--- lib/operator.coffee
+++ lib/operator.coffee
@@ -616,7 +616,7 @@

     if @editor.autoIndentOnPaste
       neededIndent = @editor.suggestedIndentForBufferRow(newRange.start.row)
-      actualIndent = getIndentLevelForBufferRow(@editor, newRange.start.row);
+      actualIndent = getIndentLevelForBufferRow(@editor, newRange.start.row)
       indentDelta = neededIndent - actualIndent

       if indentDelta > 0


call cb if package is already installed

call cb if package is already installed


NEW: auto mipmap support in BitmapElement

--- source/Art/Engine/Elements/Shapes/BitmapElement.coffee
+++ source/Art/Engine/Elements/Shapes/BitmapElement.coffee
@@ -104,7 +104,11 @@
     aspectRatio:  default: null,      validate:   (v) -> !v? || isNumber v

   @drawLayoutProperty
-    bitmap:       default: null,      validate:   (v) -> !v || v instanceof BitmapBase
+    bitmap:
+      default:    null
+      validate:   (v) -> !v || v instanceof BitmapBase
+      postSetter: (newV, oldV) ->
+        @_mipmaps = null if newV != oldV

   @virtualProperty
     mode: setter: (mode) ->
@@ -163,10 +167,14 @@

   _prepareDrawOptions: (drawOptions, compositeMode, opacity)->
     super
+    drawOptions.mipmaps     = @_mipmaps ? true
     drawOptions.focus       = @_focus
     drawOptions.layout      = @getLayout()
     drawOptions.targetSize  = @getSizeForChildren()
     drawOptions.aspectRatio = @getAspectRatio()

+  _drawBitmapElement: (target, elementToTargetMatrix, options) ->
+    @_mipmaps = target.drawBitmapWithLayout elementToTargetMatrix, @getCurrentBitmap(), options
+
   fillShape: (target, elementToTargetMatrix, options) ->
-    target.drawBitmapWithLayout elementToTargetMatrix, @getCurrentBitmap(), options
+    @_drawBitmapElement target, elementToTargetMatrix, options


Modified in browser at pixie.strd6.com

Modified in browser at pixie.strd6.com

--- src/active_bounds.coffee
+++ src/active_bounds.coffee
@@ -14,8 +14,5 @@
   log I.activeBounds

   self.bind 'update', ->
-    log I.activeBounds
-    log I.x
-    log I.y
     self.destroy() unless I.activeBounds.x <= I.x <= I.activeBounds.x + I.activeBounds.width
     self.destroy() unless I.activeBounds.y <= I.y <= I.activeBounds.y + I.activeBounds.height


Modified in browser at pixie.strd6.com

Modified in browser at pixie.strd6.com

--- src/active_bounds.coffee
+++ src/active_bounds.coffee
@@ -12,7 +12,7 @@

     bullet.include ActiveBounds

-    # => Now the bullet will be re
+    # => Now the bullet will be removed when it

 ActiveBounds module
 @name ActiveBounds


Оптимизировал код работы с тумбнейлами

Оптимизировал код работы с тумбнейлами

--- src/chocolate.coffee
+++ src/chocolate.coffee
@@ -308,27 +308,21 @@
     if not @dimensions.thumbnail
       @dimensions.thumbnail = toInt after.outerWidth true

-    width = @dimensions.thumbnail
-    left  = after.get(0).offsetLeft
-
-    range = (left, width) -> left: left, right: left + width
-
-    container = range @thumbnails.scrollLeft(), @thumbnails.width()
-    element   = range left, width
+    width     = @thumbnails.width()
+    element   = after.get(0).offsetLeft
+    thumbnail = @dimensions.thumbnail
+    container = @thumbnails.scrollLeft()

     if before
-      if @current > before
-        offset = container.left + width
-      else
-        offset = container.left - width
+      offset = if @current > before then container + thumbnail else container - thumbnail
     else
-      offset = element.left - (@thumbnails.width() / 2) + (width / 2)
-
-    future = range offset, @thumbnails.width()
-
-    if future.right < element.left
-      offset = width + left
-    else if future.left > element.left
+      offset = element - (width / 2) + (thumbnail / 2)
+
+    right = offset + width
+
+    if right < element
+      offset = thumbnail + left
+    else if offset > element
       offset = 0

     @thumbnails.scrollLeft offset


Add class if indicators are active

Add class if indicators are active

--- lib/form.coffee
+++ lib/form.coffee
@@ -217,6 +217,8 @@
       valid: @context.statuses[@props.name]
       focus: @props.name is @context.focused
       showIndicators: @context.showIndicators
+      className: cx
+        "form-input-with-indicator": @context.showIndicators
     , @state.options.inputOptions

 Message = React.createClass


fix'd pikkukartan piirto

fix'd pikkukartan piirto

--- js/views/map.coffee
+++ js/views/map.coffee
@@ -30,21 +30,19 @@
         utils.detailMap = new Map(@mapElement)

     initLayers: ->
-      unless(@routeLayer)
-        @routeLayer = new OpenLayers.Layer.Vector("Route")
+      @routeLayer = new OpenLayers.Layer.Vector("Route")
       @addLayer(@routeLayer)
-      unless(@poiLayer)
-        @poiLayer = new OpenLayers.Layer.Vector("POIs", {styleMap: utils.poiStyleMap})
-        if(@mapElement == "map")
-          selectControl = new OpenLayers.Control.SelectFeature(
+      @poiLayer = new OpenLayers.Layer.Vector("POIs", {styleMap: utils.poiStyleMap})
+      if(@mapElement == "map")
+        selectControl = new OpenLayers.Control.SelectFeature(
                 @poiLayer,
                 {
                   id: 'poi-select-control'
                   onSelect: @showPOIDetails
                 }
                 )
-          utils.map.instance.addControl(selectControl)
-          selectControl.activate()
+        utils.map.instance.addControl(selectControl)
+        selectControl.activate()
       @addLayer(@poiLayer)


Add `paper-menu` snippet

Add `paper-menu` snippet

--- snippets/paper-elements.cson
+++ snippets/paper-elements.cson
@@ -58,6 +58,14 @@
       $2
     </paper-material>
     """
+  "paper menu":
+    "prefix": "paper-menu"
+    "body": """
+    <paper-menu${1: multi}>
+      <paper-item>${2:Item 1}</paper-item>
+      <paper-item>${3:Item 2}</paper-item>
+    </paper-menu>
+    """
   "paper scroll header panel":
     "prefix": "paper-scroll-header-panel"
     "body": """


Forgot to set `spawn: false`

Forgot to set `spawn: false`

--- grunt/contrib-watch.coffee
+++ grunt/contrib-watch.coffee
@@ -10,6 +10,7 @@
       ]
       options:
         livereload: true
+        spawn: false
     compass:
       files: [
         '<%= compass.dev.options.sassDir %>/**/*.sass'


Update test suite, now it works properly

--- spec/jquery.turbolinks_spec.coffee
+++ spec/jquery.turbolinks_spec.coffee
@@ -1,24 +1,52 @@
+jsdom = require('jsdom').jsdom
+
+global.document = jsdom()
+global.window   = document.createWindow()
+
 require('../src/jquery.turbolinks.coffee')

 chai      = require('chai')
 sinon     = require('sinon')
 sinonChai = require('sinon-chai')
-jQuery    = require('jquery')
+$         = require('jquery')

 chai.should()
 chai.use(sinonChai)

-describe 'jQuery Turbolinks', ->
+describe '$ Turbolinks', ->
+
+  callback1 = callback2 = null
+
+  beforeEach ->
+     $(callback1 = sinon.spy())
+     $(callback2 = sinon.spy())

   it '''
        should trigger callbacks passed to
-       `jQuery()` and `jQuery.ready()` when page:change
+       `$()` and `$.ready()` when page:load
        event fired
      ''', ->
-       jQuery(callback1 = sinon.spy())
-       jQuery(callback2 = sinon.spy())
+       $(document).trigger('page:load')

-       jQuery(document).trigger('page:change')
+       callback1.should.have.been.calledOnce
+       callback2.should.have.been.calledOnce

-       callback1.should.have.been.calledTwice
-       callback2.should.have.been.calledTwice
+  describe '$.bindReady', ->
+
+    it 'should unbind default (page:load) event', ->
+       $.bindReady('random_event_name')
+
+       $(document).trigger('page:load')
+
+       callback1.should.have.not.been.called
+       callback2.should.have.not.been.called
+
+    it 'should bind ready to passed function', ->
+       $.bindReady('page:change')
+
+       $(document)
+         .trigger('page:load')
+         .trigger('page:change')
+
+       callback1.should.have.been.calledOnce
+       callback2.should.have.been.calledOnce


Reorganized set function layout to resemble the help(set) and added iand, ior for set

--- src/builtin/set.coffee
+++ src/builtin/set.coffee
@@ -4,25 +4,16 @@
     for item in iterable
       @value.__setitem__(item) = true

-  __contains__: (other) ->
-    return other in @value
+  __and__: (other) ->
+    intersect = List()
+    intersect.append(item) for item in @value when other.__contains__(item)
+    return new Set(intersect)

   __cmp__: (set) ->
     (new TypeError "cannot compare sets using cmp()").raise()

-  # Checks to see if this is a proper subset of set, meaning this is a subset and not equal to set
-  __lt__: (set) ->
-    if @__eq__(set)
-      return false
-    for item in @value
-      if not set.__contains__(item) return false
-    return true
-
-  # Checks to see if this is a subset of set
-  __le__: (set) ->
-    for item in @value
-      if not set.__contains__(item) return false
-    return true
+  __contains__: (other) ->
+    return other in @value

   # Checks to see if this is equivalent to set
   __eq__: (set) ->
@@ -32,9 +23,13 @@
       if not set.__contains__(item) return false
     return true

-  # Checks to see if this is not equivalent to set
-  __ne__: (set) ->
-    return not @__eq__(set)
+  # Checks to see if this is a superset of set
+  __ge__: (set) ->
+    for item in set
+      if not @__contains__(item) return false
+    return true
+
+  __getattribute__: ->

   # Checks to see if this is a proper superset of set
   __gt__: (set) ->
@@ -43,13 +38,48 @@
     for item in set
       if not @__contains__(item) return false
     return true
-
-  # Checks to see if this is a superset of set
-  __ge__: (set) ->
+
+  # Inplace and operation. x.__iand__(y) changes x
+  __iand__: (set) ->
+    deletedKeys = List()
+    for item in @value
+      if not set.__contains__(item)
+        deletedKeys.append(item)
+    for deletedKey in deletedKeys
+      @value.pop(deletedKey)
+
+  __init__: ->
+
+  __ior__: (set) ->
     for item in set
-      if not @__contains__(item) return false
+      @add(item)
+  # Checks to see if this is a subset of set
+  __le__: (set) ->
+    for item in @value
+      if not set.__contains__(item) return false
     return true

+  __len__: ->
+    return @value.__len__()
+
+  # Checks to see if this is a proper subset of set, meaning this is a subset and not equal to set
+  __lt__: (set) ->
+    if @__eq__(set)
+      return false
+    for item in @value
+      if not set.__contains__(item) return false
+    return true
+
+  # Checks to see if this is not equivalent to set
+  __ne__: (set) ->
+    return not @__eq__(set)
+
+  __or__: (set) ->
+    union = List()
+    union.append(item) for item in @value
+    union.append(item) for item in set
+    return new Set(union)
+
   # Checks to see if this and set are disjoint, meaning this intersected with set is the empty set
   isdisjoint: (set) ->
     return @__and__(set).__len__() == 0
@@ -59,6 +89,3 @@

   issuperset: (set) ->
     return @__ge__(set)
-
-  __len__: ->
-    return @value.__len__()


Fix react-bootstrap bugs in song select dropdown

--- public/scripts/MarkatoNav.cjsx
+++ public/scripts/MarkatoNav.cjsx
@@ -13,15 +13,15 @@

   songListItems: ->
     _.map @props.getSongNames(), (song, index) =>
-      classes = "active" if @props.currentSongIndex is index
-
{song}

+      classes = 'active' if @props.currentSongIndex is index
+      <MenuItem className={classes} key={index} onClick={@props.handleSongSelect index}>{song}</MenuItem>

   songList: ->
     if @props.currentUser
-      <NavDropdown title="Select Song">
+      <NavDropdown title="Select Song" id="select-song">
         {@songListItems()}
-

-        <NavItem href="#" onClick={@props.newSong}>New Song</NavItem>
+        <MenuItem role="separator" className="divider" />
+        <MenuItem onClick={@props.newSong}>New Song</MenuItem>
       </NavDropdown>

   logout: ->


Show a notification if user already liked

--- client/landing/app/Applications/Activity.kdapplication/ActivityActions.coffee
+++ client/landing/app/Applications/Activity.kdapplication/ActivityActions.coffee
@@ -55,7 +55,12 @@
         if KD.isLoggedIn()
           # oldCount = @likeCount.data.meta.likes
           activity.like (err)=>
-            log arguments, 'you like me!'
+            # log arguments, 'you like me!'
+            if err
+              new KDNotificationView
+                title     : "You already liked this!"
+                duration  : 1300
+            # FIXME Implement Unlike behaviour
             ###
             newCount = @likeCount.data.meta.likes
             if oldCount < newCount then @likeLink.updatePartial("Unlike")


add setting to control console panel

add setting to control console panel

--- lib/main.coffee
+++ lib/main.coffee
@@ -17,11 +17,18 @@
       type: "string"
       default: ""
       order: 0
-    showBuildNotifications:
-      title: "Show Build Notifications"
+    alwaysShowOutput:
+      title: "Always Show Output"
+      description: "Displays compiler output in console panel. When deactivated, it will only show on errors"
       type: "boolean"
       default: true
       order: 1
+    showBuildNotifications:
+      title: "Show Build Notifications"
+      description: "Displays color-coded notifications that close automatically after 5 seconds"
+      type: "boolean"
+      default: true
+      order: 2
   subscriptions: null

   activate: (state) ->
@@ -63,7 +70,7 @@
       iscc = spawn pathToISCC, [script]

       iscc.stdout.on 'data', ( data ) ->
-        consolePanel.log(data.toString())
+        consolePanel.log(data.toString()) if atom.config.get('language-innosetup.alwaysShowOutput')

       iscc.stderr.on 'data', ( data ) ->
         consolePanel.error(data.toString())


fix semantics

fix semantics

--- lib/main.coffee
+++ lib/main.coffee
@@ -58,7 +58,7 @@
             dismissable: true
           atom.notifications.addFatalError("Uncaught #{error.stack.split('\n')[0]}", options)

-    @addNotificaionLogSubscriptions() if @notificationsLog?
+    @addNotificaionsLogSubscriptions() if @notificationsLog?
     @subscriptions.add atom.workspace.addOpener (uri) => @createLog() if uri is NotificationsLog::getURI()
     @subscriptions.add atom.commands.add 'atom-workspace', 'notifications:toggle-log', -> atom.workspace.toggle(NotificationsLog::getURI())

@@ -85,12 +85,12 @@

     @isInitialized = true

-  createLog: (serialized) ->
-    @notificationsLog = new NotificationsLog @duplicateTimeDelay, serialized?.typesHidden
-    @addNotificaionLogSubscriptions() if @subscriptions?
+  createLog: (state) ->
+    @notificationsLog = new NotificationsLog @duplicateTimeDelay, state?.typesHidden
+    @addNotificaionsLogSubscriptions() if @subscriptions?
     @notificationsLog

-  addNotificaionLogSubscriptions: ->
+  addNotificaionsLogSubscriptions: ->
     @subscriptions.add @notificationsLog.onDidDestroy => @notificationsLog = null
     @subscriptions.add @notificationsLog.onItemClick (notification) =>
       view = atom.views.getView(notification)


:art: minor refactor

:art: minor refactor

--- lib/main.coffee
+++ lib/main.coffee
@@ -7,9 +7,9 @@
 Flasher    = null
 settings   = require './settings'

-delay = (ms, func) ->
+delay = (ms, fun) ->
   setTimeout ->
-    func()
+    fun()
   , ms

 debug = (msg) ->
@@ -43,7 +43,7 @@
       'cursor-history:prev':  => @jump('Prev')
       'cursor-history:clear': => @history.clear()
       'cursor-history:dump':  => @dump()
-      'cursor-history:toggle-debug': => settings.toggle 'debug', log: true
+      'cursor-history:toggle-debug': -> settings.toggle 'debug', log: true

     @subscriptions.add @observeModalPanel()
     @subscriptions.add @observeTextEditors()
@@ -80,7 +80,7 @@
               @history.add oldEditor, oldPoint, oldEditor.getURI(), dumpMessage: "[Cursor moved] save history"
             @unLock()

-      @subscriptions.add panel.onDidDestroy =>
+      @subscriptions.add panel.onDidDestroy ->
         panelSubscription.dispose()

     symbolsViewHandlers =
@@ -114,7 +114,7 @@
             point  = @getPosition editor
             {editor, point}

-    atom.workspace.panelContainers['modal'].onDidAddPanel ({panel, index}) =>
+    atom.workspace.panelContainers['modal'].onDidAddPanel ({panel, index}) ->
       # [CAUTION] Simply checking constructor name is not enough.
       # e.g. ProjectView is also used in `fuzzy-finder`.
       item = panel.getItem()
@@ -177,12 +177,12 @@
       @lastEditor.set item
       debug "set LastEditor #{path.basename(item.getURI())}"

-    atom.workspace.observeActivePaneItem (item) =>
+    atom.workspace.observeActivePaneItem (item) ->
       if item instanceof TextEditor and item.getURI()
         handlePaneItemChanged item

   observeOnWillDestroyPaneItem: ->
-    atom.workspace.onWillDestroyPaneItem ({item}) =>
+    atom.workspace.onWillDestroyPaneItem ({item}) ->
       if item instanceof TextEditor and item.getURI()
         LastEditor.saveDestroyedEditor item


Fix incorrect variable name

Fix incorrect variable name

--- server/controllers/deploy.coffee
+++ server/controllers/deploy.coffee
@@ -15,10 +15,10 @@
   console.log "Forking #{process.cwd()}/bin/deploy.coffee"

   deployProcess = cp.fork("#{process.cwd()}/bin/deploy.coffee")
-  theProcess.stdout.on('data', (data) ->
+  deployProcess.stdout.on('data', (data) ->
     console.log(data.toString())
   )
-  theProcess.stderr.on('data', (data) ->
+  deployProcess.stderr.on('data', (data) ->
     console.log("Error: #{data.toString()}")
   )


Remove status icon classes before path check

--- src/status-bar.coffee
+++ src/status-bar.coffee
@@ -71,10 +71,10 @@

   updateStatusText: ->
     path = @editor.getPath()
-    @gitStatusIcon.empty()
+    @gitStatusIcon.removeClass()
     return unless path

-    @gitStatusIcon.removeClass().addClass('git-status octicons')
+    @gitStatusIcon.addClass('git-status octicons')
     git = @buffer.getRepo()
     if git?.isPathModified(path)
       @gitStatusIcon.addClass('modified-status-icon')


fix(app): allow project to be overwritten

--- src/clabot-sample.coffee
+++ src/clabot-sample.coffee
@@ -23,7 +23,7 @@
 app.get '/form/:project/:kind?', (req, res) ->
   project = req.params.project
   # Makes no sense, yet. Extensible in the future.
-  if project isnt 'clabot' then project = 'clabot'
+  project ?= 'clabot'
   kind    = req.params.kind?.toLowerCase()
   kind    = kind.charAt(0).toUpperCase() + kind.slice 1 if kind
   if kind isnt 'Entity' then kind = 'Individual'


Fix level switch

Fix level switch

--- app/scripts/lib/Level.coffee
+++ app/scripts/lib/Level.coffee
@@ -367,6 +367,8 @@
     candidates[Math.floor(Math.random() * candidates.length)]

   _seedPreceedingGeometry: ->
+    currentGenerator = @levelDefinition[@generationDefinition]
+    return unless currentGenerator?.type is 'autofill'
     blockType = "#{@namespace}.#{@currentScenery}"
     blockKlass = @generator.buildingBlocks[blockType]
     if next = blockKlass::autoNext


persist filters on collection

persist filters on collection

--- app/assets/javascripts/backbone/entities/prop.coffee
+++ app/assets/javascripts/backbone/entities/prop.coffee
@@ -19,7 +19,7 @@
     comparator: (model) ->
       - moment(model.get('created_at')).format('X')
     url: ->
-      Routes.api_props_path()
+      Routes.api_props_path(@filters)

     parseRecords: (resp) ->
       resp.props
@@ -32,10 +32,10 @@
       }

   API =
-    getProps: (filters) ->
+    getProps: (filters = {}) ->
       props = new Entities.Props
-      props.fetch
-        data: filters if filters
+      props.filters = filters
+      props.fetch()
       props

     newProp: ->


Fix tags controller name

Fix tags controller name

--- app/assets/javascripts/controllers/tags/index.coffee
+++ app/assets/javascripts/controllers/tags/index.coffee
@@ -1,4 +1,4 @@
-Dashboard.TagsFilterController = Ember.ArrayController.extend
+Dashboard.TagsTabController = Ember.ArrayController.extend
   actions:
     destroy: (item)->
       if window.confirm(Ember.I18n.t('words.are_you_sure_to_delete'))


Don't add the text to buttons there

Don't add the text to buttons there

--- app/assets/javascripts/incidents/batch_export.coffee
+++ app/assets/javascripts/incidents/batch_export.coffee
@@ -26,8 +26,6 @@
   $('.batch-hastus-export #main-button').hide()
   $('.batch-hastus-export #xml-button').show()
   $('.batch-hastus-export #csv-button').show()
-  $('.batch-hastus-export #xml-button').text 'Select incidents to export...'
-  $('.batch-hastus-export #csv-button').text 'Select incidents to export...'
   $('.batch-hastus-export #select-all').show()
   setSelectAllText()


remove transitionDuration from the tree view on disable

--- lib/autohide-tree-view.coffee
+++ lib/autohide-tree-view.coffee
@@ -139,6 +139,7 @@
     treeViewEl.classList.remove 'autohide', 'autohide-hover-events', 'autohide-unfolded'
     # reset the inline css rules
     treeViewEl.style.transitionDelay = ''
+    treeViewEl.style.transitionDuration = ''
     treeViewEl.style.width = treeViewEl.querySelector('.tree-view').clientWidth
     treeViewEl.parentNode.style.width = ''


OX-422 fixed resizing bug

OX-422 fixed resizing bug

--- app/assets/javascripts/oxalis/view/plane_view.coffee
+++ app/assets/javascripts/oxalis/view/plane_view.coffee
@@ -153,9 +153,9 @@
   #Call this after the canvas was resized to fix the viewport
   resize : ->
     #FIXME: Is really the window's width or rather the DIV's?
-    container = $("#render")
-    WIDTH = (container.width()-20)/2
-    HEIGHT = (container.height()-20)/2
+    canvas = $("#render > canvas")
+    WIDTH = (canvas.width()-20)/2
+    HEIGHT = (canvas.height()-20)/2

     @renderer.setSize( 2*WIDTH+20, 2*HEIGHT+20)
     for i in [PLANE_XY, PLANE_YZ, PLANE_XZ, VIEW_3D]
@@ -168,9 +168,9 @@
     if (@scaleFactor+delta > 0.65) and (@scaleFactor+delta < 2)
       @scaleFactor += Number(delta)
       @curWidth = WIDTH = HEIGHT = @scaleFactor * 380
-      container = $("#render")
-      container.width(2 * WIDTH + 20)
-      container.height(2 * HEIGHT + 20)
+      canvas = $("#render > canvas")
+      canvas.width(2 * WIDTH + 20)
+      canvas.height(2 * HEIGHT + 20)

       divs = $(".inputcatcher")
       for div in divs


Remove unused instance variable

Remove unused instance variable

--- app/assets/javascripts/search_autocomplete.js.coffee
+++ app/assets/javascripts/search_autocomplete.js.coffee
@@ -35,7 +35,6 @@
     @createAutocomplete()

     @searchInput.addClass('disabled')
-    @autocomplete = false

     @bindEvents()

@@ -60,10 +59,6 @@
   getData: (term, callback) ->
     _this = @

-    # Ensure this is not called when autocomplete is disabled because
-    # this method still will be called because `GitLabDropdownFilter` is triggering this on keyup
-    return if @autocomplete is false
-
     # Do not trigger request if input is empty
     return if @searchInput.val() is ''

@@ -118,15 +113,12 @@
     @clearInput.on 'click', @onRemoveLocationClick

   enableAutocomplete: ->
-    return if @autocomplete
-
     dropdownMenu = @dropdown.find('.dropdown-menu')
     _this = @
     @loadingSuggestions = false

     @dropdown.addClass('open')
     @searchInput.removeClass('disabled')
-    @autocomplete = true

   onDropdownOpen: (e) =>
     @dropdown.dropdown('toggle')
@@ -239,12 +231,9 @@
     @wrap.removeClass('has-location-badge')

   disableAutocomplete: ->
-    if @autocomplete
-      @searchInput.addClass('disabled')
-      @dropdown.removeClass('open')
-      @restoreMenu()
-
-    @autocomplete = false
+    @searchInput.addClass('disabled')
+    @dropdown.removeClass('open')
+    @restoreMenu()

   restoreMenu: ->
     html = "<ul>


restore overlay on products filters submission

--- app/assets/javascripts/stall/products-filters.coffee
+++ app/assets/javascripts/stall/products-filters.coffee
@@ -2,6 +2,7 @@
   events:
     'change [data-filter-submission="change"]': 'filterChanged'
     'slideStop [data-filter-submission="slide"]': 'filterChanged'
+    'submit': 'setSubmitted'

   filterChanged: (e) ->
     @submit()


Fixed undefined var

Fixed undefined var

--- app/assets/javascripts/surveys/modules/Survey.coffee
+++ app/assets/javascripts/surveys/modules/Survey.coffee
@@ -311,13 +311,12 @@
   initConditionals: ->
     $('[data-conditional-question]').each (i, question) =>
       $(question).addClass 'hidden'
-      conditiona_string = $(question).data 'conditional-question'
       {
         question_id
         operator
         value
         multi
-      } = Utils.parseConditionalString conditional_string
+      } = Utils.parseConditionalString $(question).data 'conditional-question'

       if @survey_conditionals[question_id]?
         @survey_conditionals[question_id].children.push question


Add in .iced extensions to the main program

--- src/coffee-script.coffee
+++ src/coffee-script.coffee
@@ -11,9 +11,10 @@
 {parser}      = require './parser'
 helpers       = require './helpers'
 SourceMap     = require './sourcemap'
+iced          = require './iced'

 # The current CoffeeScript version number.
-exports.VERSION = '1.6.2'
+exports.VERSION = '1.6.2a'

 # Expose helpers for testing.
 exports.helpers = helpers
@@ -33,7 +34,7 @@
   if options.sourceMap
     map = new SourceMap

-  fragments = (parser.parse lexer.tokenize(code, options)).compileToFragments options
+  fragments = (iced.transform parser.parse lexer.tokenize(code, options)).compileToFragments options

   currentLine = 0
   currentLine += 1 if options.header
@@ -76,9 +77,9 @@
 # or traverse it by using `.traverseChildren()` with a callback.
 exports.nodes = (source, options) ->
   if typeof source is 'string'
-    parser.parse lexer.tokenize source, options
-  else
-    parser.parse source
+    iced.transform parser.parse lexer.tokenize source, options
+  else
+    iced.transform parser.parse source

 # Compile and execute a string of CoffeeScript (on the server), correctly
 # setting `__filename`, `__dirname`, and relative `require()`.
@@ -151,7 +152,7 @@
 # If the installed version of Node supports `require.extensions`, register
 # CoffeeScript as an extension.
 if require.extensions
-  for ext in ['.coffee', '.litcoffee', '.coffee.md']
+  for ext in ['.coffee', '.litcoffee', '.coffee.md', '.iced']
     require.extensions[ext] = loadFile

 # If we're on Node, patch `child_process.fork` so that Coffee scripts are able
@@ -190,6 +191,9 @@
 # Make all the AST nodes visible to the parser.
 parser.yy = require './nodes'

+# Export the iced runtime as 'iced'
+exports.iced = iced.runtime
+
 # Override Jison's default error handling function.
 parser.yy.parseError = (message, {token}) ->
   # Disregard Jison's message, it contains redundant line numer information.


Manually reverted the changes to coffee-script.coffee introduced in 40ee30ecde201c205f76783f18d10eccd8c33a26. The 'TRY COFEESCRIPT' demo in index.html appears to work again after regenerating extras/coffee-script.js by running 'MINIFY=false bin/cake build:browser'.

--- src/coffee-script.coffee
+++ src/coffee-script.coffee
@@ -8,8 +8,12 @@

 fs               = require 'fs'
 path             = require 'path'
-{Script}         = require 'vm'
-Module           = require 'module'
+
+# REVERT 40ee30ecde201c205f76783f18d10eccd8c33a26
+vm               = require 'vm'
+#{Script}         = require 'vm'
+#Module           = require 'module'
+
 {Lexer,RESERVED} = require './lexer'
 {parser}         = require './parser'

@@ -81,30 +85,49 @@
 # The CoffeeScript REPL uses this to run the input.
 exports.eval = (code, options = {}) ->
   return unless code = code.trim()
-  sandbox = Script.createContext()
-  sandbox.global = sandbox.root = sandbox.GLOBAL = sandbox
-  if options.sandbox?
-    if options.sandbox instanceof sandbox.constructor
-      sandbox = options.sandbox
-    else
-      sandbox[k] = v for own k, v of options.sandbox
+
+# REVERT 40ee30ecde201c205f76783f18d10eccd8c33a26
+  sandbox = options.sandbox
+  unless sandbox
+    sandbox =
+      require: require
+      module : { exports: {} }
+    sandbox[g] = global[g] for g in Object.getOwnPropertyNames global
+    sandbox.global = sandbox
+    sandbox.global.global = sandbox.global.root = sandbox.global.GLOBAL = sandbox
+#  sandbox = Script.createContext()
+#  sandbox.global = sandbox.root = sandbox.GLOBAL = sandbox
+#  if options.sandbox?
+#    if options.sandbox instanceof sandbox.constructor
+#      sandbox = options.sandbox
+#    else
+#      sandbox[k] = v for own k, v of options.sandbox
+
   sandbox.__filename = options.filename || 'eval'
   sandbox.__dirname  = path.dirname sandbox.__filename
-  # define module/require only if they chose not to specify their own
-  unless sandbox.module or sandbox.require
-    Module = require 'module'
-    sandbox.module  = _module  = new Module(options.modulename || 'eval')
-    sandbox.require = _require = (path) -> Module._load path, _module
-    _module.filename = sandbox.__filename
-    _require[r] = require[r] for r in Object.getOwnPropertyNames require
-    # use the same hack node currently uses for their own REPL
-    _require.paths = _module.paths = Module._nodeModulePaths process.cwd()
-    _require.resolve = (request) -> Module._resolveFilename request, _module
-  o = {}
-  o[k] = v for own k, v of options
+
+# REVERT 40ee30ecde201c205f76783f18d10eccd8c33a26
+  o = {}; o[k] = v for k, v of options
+#  # define module/require only if they chose not to specify their own
+#  unless sandbox.module or sandbox.require
+#    Module = require 'module'
+#    sandbox.module  = _module  = new Module(options.modulename || 'eval')
+#    sandbox.require = _require = (path) -> Module._load path, _module
+#    _module.filename = sandbox.__filename
+#    _require[r] = require[r] for r in Object.getOwnPropertyNames require
+#    # use the same hack node currently uses for their own REPL
+#    _require.paths = _module.paths = Module._nodeModulePaths process.cwd()
+#    _require.resolve = (request) -> Module._resolveFilename request, _module
+#  o = {}
+#  o[k] = v for own k, v of options
+
   o.bare = on # ensure return value
-  js = compile code, o
-  Script.runInContext js, sandbox
+
+# REVERT 40ee30ecde201c205f76783f18d10eccd8c33a26
+  js = compile "_=(#{code}\n)", o
+  vm.runInNewContext js, sandbox, sandbox.__filename
+#  js = compile code, o
+#  Script.runInContext js, sandbox

 # Instantiate a Lexer for our use here.
 lexer = new Lexer


make scale actually scale

make scale actually scale

--- src/coffee/geomap.coffee
+++ src/coffee/geomap.coffee
@@ -12,7 +12,7 @@
             svg: null

         # Dependant properties must be set after initialization.
-        @properties.scale = @properties.width / @properties.height * 90
+        @properties.scale = @properties.width / 5.8
         @properties.translate = [@properties.width / 2, @properties.height / 2]

         # Setup methods to access properties.


Updated cohtml-parser (extractScope)

Updated cohtml-parser (extractScope)

--- src/cohtml-parser.coffee
+++ src/cohtml-parser.coffee
@@ -60,6 +60,14 @@
     else
       @throwError 'Inconsistent Indent.'

+  ###
+    Extraction
+  ###

+  extractScope: (indentLevel = 0, parentNode = null)->
+    scope = []
+    while node = @extractStatement indentLevel, parentNode
+      scope.push node
+    return scope

 @CohtmlParser = CohtmlParser


to done

to done

--- lib/connection/process.coffee
+++ lib/connection/process.coffee
@@ -125,8 +125,6 @@
   onStdout: (f) -> @emitter.on 'stdout', f
   onStderr: (f) -> @emitter.on 'stderr', f

-  # TODO: make 'kill' try to exit gracefully first
-
   require: (f) ->
     if not @proc
       atom.notifications.addError "There's no Julia process running.",


whitespace

whitespace

--- lib/connection/process.coffee
+++ lib/connection/process.coffee
@@ -101,24 +101,24 @@
     client.booting()

     @checkPath(@jlpath())
-    .then =>
-      @spawnJulia port, =>
-        @proc.on 'exit', (code, signal) =>
-          @emitter.emit 'stderr', "Julia has stopped"
-          if not @useWrapper then @emitter.emit 'stderr', ": #{code}, #{signal}"
-          @proc = null
-          client.cancelBoot()
-        @proc.stdout.on 'data', (data) =>
-          text = data.toString()
-          if text then @emitter.emit 'stdout', text
-          if text and @pipeConsole then console.log text
-        @proc.stderr.on 'data', (data) =>
-          text = data.toString()
-          if text then @emitter.emit 'stderr', text
-          if text and @pipeConsole then console.info text
-    .catch =>
-      @jlNotFound @jlpath()
-      client.cancelBoot()
+      .then =>
+        @spawnJulia port, =>
+          @proc.on 'exit', (code, signal) =>
+            @emitter.emit 'stderr', "Julia has stopped"
+            if not @useWrapper then @emitter.emit 'stderr', ": #{code}, #{signal}"
+            @proc = null
+            client.cancelBoot()
+          @proc.stdout.on 'data', (data) =>
+            text = data.toString()
+            if text then @emitter.emit 'stdout', text
+            if text and @pipeConsole then console.log text
+          @proc.stderr.on 'data', (data) =>
+            text = data.toString()
+            if text then @emitter.emit 'stderr', text
+            if text and @pipeConsole then console.info text
+      .catch =>
+        @jlNotFound @jlpath()
+        client.cancelBoot()

   spawnJulia: (port, fn) ->
     if process.platform is 'win32' and atom.config.get("julia-client.enablePowershellWrapper")


Match field and directive names case-insensitively


Update FilterValue comments

Update FilterValue comments

--- lib/hacks/filter-value.coffee
+++ lib/hacks/filter-value.coffee
@@ -17,7 +17,7 @@
     super
     @name = 'filter' if name == 'filter-function'

-  # Use prefixed and unprefixed filter for WebKit transition
+  # Use prefixed and unprefixed filter for WebKit
   replace: (value, prefix) ->
     if prefix == '-webkit-'  && value.indexOf('filter(') == -1
       if value.indexOf('-webkit-filter') == -1
@@ -27,7 +27,7 @@
     else
       super

-  # Clean -webkit-filter from transitioins
+  # Clean -webkit-filter
   old: (prefix) ->
     new OldFilterValue(@name, prefix + @name)


Update gulpfile

Update gulpfile

--- gulpfile.coffee
+++ gulpfile.coffee
@@ -6,7 +6,10 @@
 del        = require 'del'
 preprocess = require 'gulp-preprocess'

-require('./node_modules/preprocess/lib/regexrules').coffee.include = "^(.*?)#+[ \t]*\%include(?!-)[ \t]+(.*?)[ \t]*$"
+try
+  require('./gulp-preprocess/node_modules/preprocess/lib/regexrules').coffee.include = "^(.*?)#+[ \t]*\%include(?!-)[ \t]+(.*?)[ \t]*$"
+catch
+  require('./node_modules/preprocess/lib/regexrules').coffee.include = "^(.*?)#+[ \t]*\%include(?!-)[ \t]+(.*?)[ \t]*$"

 gulp.task 'default', ['build'], ->


of course, let's point the server at the right directory while doing so

--- gulpfile.coffee
+++ gulpfile.coffee
@@ -27,7 +27,7 @@

 gulp.task 'server', ->
   connect.server
-    root: ['public'],
+    root: ['dist'],
     port: process.env.PORT || 9999
     middleware: -> [cors()]


Log output from check-coverage.

Log output from check-coverage.

--- gulpfile.coffee
+++ gulpfile.coffee
@@ -81,7 +81,7 @@

 gulp.task 'check-coverage', ->
   options =
-    silent: true
+    silent: false
     coverage: require('./.coverage.json')

   onCoverageError = (errors) ->


Create controls

Create controls

--- src/config/layout.coffee
+++ src/config/layout.coffee
@@ -32,7 +32,7 @@
           {x: middle - margin, y: middle}
       }
       _CHILDREN: [
-        "play"
+        ">", ">>", "||","<>", "|<"
       ]
     }
   ]


commonPath should return -1 for the parent object.

--- src/types/json.coffee
+++ src/types/json.coffee
@@ -195,7 +195,7 @@
 	p2.unshift('data')
 	p1 = p1[...p1.length-1]
 	p2 = p2[...p2.length-1]
-	return 0 if p2.length == 0
+	return -1 if p2.length == 0
 	i = 0
 	while p1[i] == p2[i] && i < p1.length
 		i++


update

update

--- test/async.coffee
+++ test/async.coffee
@@ -184,8 +184,8 @@
                 func2 = eval "(#{data})"
                 func2().should.to.equal 'func'
                 cbk()
-            # (cbk)->
-            #     fs.unlink file, cbk
+            (cbk)->
+                fs.unlink file, cbk
             ->
                 fs.rmdir dir, done
         ]


fix fact wording

fix fact wording


:gift: now when sequential execution, concatenate undo history! undoJoin

--- lib/move-selected-text.coffee
+++ lib/move-selected-text.coffee
@@ -10,19 +10,38 @@
 swrap = requireFrom('vim-mode-plus', 'selection-wrapper')

 CommandPrefix = 'vim-mode-plus-user'
+stateByEditor = new Map
+checkPointByEditor = new Map
 # -------------------------
-class MoveSelectedTextUp extends TransformString
+class MoveSelectedText extends TransformString
+  getSelectedTexts: ->
+    @editor.getSelections().map((selection) -> selection.getText()).join('')
+
+  withUndoJoin: (fn) ->
+    unless (isSequential = stateByEditor.get(@editor) is @getSelectedTexts())
+      checkPointByEditor.set(@editor, @editor.createCheckpoint())
+
+    fn()
+
+    stateByEditor.set(@editor, @getSelectedTexts())
+    if isSequential and checkPointByEditor.has(@editor)
+      @editor.groupChangesSinceCheckpoint(checkPointByEditor.get(@editor))
+
+class MoveSelectedTextUp extends MoveSelectedText
   @commandPrefix: CommandPrefix
   direction: 'up'
   flashTarget: false
+
   execute: ->
     return unless @isMode('visual')
     return unless @selectTarget()
-    selections = @editor.getSelectionsOrderedByBufferPosition()
-    selections.reverse() if @direction is 'down'
-    @editor.transact =>
-      for selection in selections
-        @mutate(selection)
+
+    @withUndoJoin =>
+      selections = @editor.getSelectionsOrderedByBufferPosition()
+      selections.reverse() if @direction is 'down'
+      @editor.transact =>
+        for selection in selections
+          @mutate(selection)

   mutate: (selection) ->
     switch @vimState.submode
@@ -100,15 +119,16 @@
   direction: 'down'

 # -------------------------
-class MoveSelectedTextRight extends TransformString
+class MoveSelectedTextRight extends MoveSelectedText
   @commandPrefix: CommandPrefix
   direction: 'right'
   flashTarget: false

   execute: ->
     return unless @isMode('visual')
-    @eachSelection (selection) =>
-      @mutate(selection)
+    @withUndoJoin =>
+      @eachSelection (selection) =>
+        @mutate(selection)

   mutate: (selection) ->
     switch @vimState.submode


OX-156 Bug fix

OX-156 Bug fix

--- app/assets/javascripts/libs/flycam2.coffee
+++ app/assets/javascripts/libs/flycam2.coffee
@@ -103,7 +103,7 @@
   getSceneScalingArray : ->
     rScale = @model.Route.scale
     rMin   = Math.min.apply(null, rScale)
-    [rScale[0] / rMin, rScale[1] / rMin, rScale[2] / rMin]
+    [rMin / rScale[0], rMin / rScale[1], rMin / rScale[2]]

   getDirection : ->
     @direction


BF-168 Bug fix 2

BF-168 Bug fix 2

--- app/assets/javascripts/libs/flycam2.coffee
+++ app/assets/javascripts/libs/flycam2.coffee
@@ -135,10 +135,8 @@

   getOffsets : (planeID) ->
     ind = @getIndices planeID
-    f   = @getPlaneScalingFactor planeID
-    #if @needsUpdate(planeID) then return [buffer[planeID], buffer[planeID]]
-    [ (@globalPosition[ind[0]] - @texturePosition[planeID][ind[0]]) + @buffer[planeID],
-      (@globalPosition[ind[1]] - @texturePosition[planeID][ind[1]]) + @buffer[planeID]]
+    [ (@globalPosition[ind[0]] - @texturePosition[planeID][ind[0]])/Math.pow(2, @getZoomStep planeID) + @buffer[planeID],
+      (@globalPosition[ind[1]] - @texturePosition[planeID][ind[1]])/Math.pow(2, @getZoomStep planeID) + @buffer[planeID]]

   #notifyNewTextureXY : ->
   #  @texturePositionXY = @globalPosition.slice()    #copy that position


add a function to disable all buttons and call prior to ajax req

--- app/assets/javascripts/workflows.js.coffee
+++ app/assets/javascripts/workflows.js.coffee
@@ -4,12 +4,12 @@

 @update_display = (id) ->
   request_job_data(id)
-  update_copy_button(id)
   update_destroy_button(id)

 @request_job_data = (id) ->
   if id?
     show_job_panel()
+    disable_all_buttons()
     $.ajax
       type: 'GET'
       url: Routes.workflow_path(id)
@@ -22,6 +22,7 @@
         update_job_details_panel(data)
         update_open_dir_button(data.fs_root)
         update_edit_button(id)
+        update_copy_button(id)
         update_submit_button(id, data.status.char)
         update_stop_button(id, data.status.char)
         update_template_button(id)
@@ -34,14 +35,19 @@
           update_submit_button()
           update_copy_button()
   else
-    update_job_details_panel()
-    update_open_dir_button()
-    update_edit_button()
-    update_terminal_button()
-    update_submit_button()
-    update_stop_button()
-    update_template_button()
-    list_folder_contents()
+    disable_all_buttons()
+
+@disable_all_buttons = ->
+  update_job_details_panel()
+  update_open_dir_button()
+  update_edit_button()
+  update_terminal_button()
+  update_submit_button()
+  update_stop_button()
+  update_template_button()
+  update_copy_button()
+  update_destroy_button()
+  list_folder_contents()

 @show_job_panel = (show) ->
   if show?


Modified in browser at pixie.strd6.com

Modified in browser at pixie.strd6.com

--- src/core_object.coffee
+++ src/core_object.coffee
@@ -43,8 +43,6 @@
       @fieldOf Core#
       ###
       I: I
-
-      includedModules: []

       ###*
       Generates a public jQuery style getter / setter method for each


fix reverse mu needed calculations #17 (#19)

--- src/cycle-times.coffee
+++ src/cycle-times.coffee
@@ -86,7 +86,7 @@
     ourScore = checkpointsDone * ours
     theirScore = checkpointsDone * theirs
     difference = theirScore - ourScore
-    difference = 0 if difference < 1
+    difference = -difference if difference < 1
     difference + 1

 getMuNeededNow = (ours, theirs) ->


Remove wrong channel route

Remove wrong channel route

See https://github.com/loafoe/hubot-matteruser/issues/32

--- src/client.coffee
+++ src/client.coffee
@@ -265,7 +265,7 @@
     createDirectChannel: (userID) ->
         postData =
             user_id: userID
-        @_apiCall 'POST', @channelRoute('/create_direct'), postData, (data, headers) =>
+        @_apiCall 'POST', @channelRoute('create_direct'), postData, (data, headers) =>
             @logger.debug 'Created Direct Channel.'
             return data


Remove some cruft

Remove some cruft

--- src/client.coffee
+++ src/client.coffee
@@ -256,12 +256,12 @@
                 # These are personal messages
                 @emit message.event, message
             when 'new_user'
-                @_apiCall 'GET', @teamRoute() + '/users/0/1000', null, @_onProfiles
+                # TODO: fetch enough detail for new user
                 @emit 'new_user', message
             else
                 # Check for `pong` response
                 if message.data?.text? and message.data.text == "pong"
-                    @logger.info 'ACK ping'
+                    @logger.info 'ACK ping (2)'
                     @_lastPong = Date.now()
                     @emit 'ping', message
                 else


Emit an event when a user object is changed or added

--- src/client.coffee
+++ src/client.coffee
@@ -384,6 +384,7 @@

       when "team_join", "user_change"
         u = message.user
+        @emit 'userChange', u
         @users[u.id] = new User @, u

       when "channel_joined"


Added jquery check on homepage to prevent routing with empty search terms.  Fully fixed with error pages in #18

--- app/assets/transit/lib/views/splash.coffee
+++ app/assets/transit/lib/views/splash.coffee
@@ -15,10 +15,19 @@

   go_to_plan: =>
     event.preventDefault()
-    @remove()
     from = @$('#from_query').val()
     to = @$('#to_query').val()
-    Transit.router.navigate "plan/#{from}/#{to}", trigger: true
+    if (to == null || to.length <= 3)
+        @$('#to-location').addClass('btn-danger')
+    else
+        @$('#to-location').removeClass('btn-danger')
+    if (from == null || from.length <=3)
+        @$('#from-location').addClass('btn-danger')
+    else
+        @$('#from-location').removeClass('btn-danger')
+    if (to? and from? and to.length > 3 and from.length > 3)
+        @remove()
+        Transit.router.navigate "plan/#{from}/#{to}", trigger: true

   from_current_location: =>
     Transit.plan.current_location @$('#from_query'), 'from'


If the brewer cancels their bounty let them brew.

--- src/coffee.coffee
+++ src/coffee.coffee
@@ -212,7 +212,6 @@
     if bounty.reward > 0 and barista is bounty.issuer
       msg.send "Hey @#{bounty.issuer} you can't collect your own bounty! **Your bounty has been cancelled.** #{statusEmoji.random('failure')}"
       clearBounty
-      return

     brewing =
       barista: barista


Don't detach unless view has parent

Don't detach unless view has parent

--- src/packages/jump-to-line/lib/jump-to-line-view.coffee
+++ src/packages/jump-to-line/lib/jump-to-line-view.coffee
@@ -14,9 +14,9 @@
       @div class: 'message', outlet: 'message'

   initialize: (@rootView) ->
-    @miniEditor.on 'focusout', => @detach() if @hasParent()
+    @miniEditor.on 'focusout', => @detach()
     @on 'core:confirm', => @confirm()
-    @on 'core:cancel', => @detach() if @hasParent()
+    @on 'core:cancel', => @detach()

     @miniEditor.preempt 'textInput', (e) =>
       false unless e.originalEvent.data.match(/[0-9]/)
@@ -28,6 +28,8 @@
       @attach()

   detach: ->
+    return unless @hasParent()
+
     @miniEditor.setText('')
     @previouslyFocusedElement?.focus()


Fixing indentation (tabs 2 spaces)

Fixing indentation (tabs 2 spaces)

--- cli/templates/app_skel/src/app/views/app_view.coffee
+++ cli/templates/app_skel/src/app/views/app_view.coffee
@@ -3,11 +3,10 @@
 exports.module = class AppView extends View

   set_triggers: ->
-		super()
+    super()

-		# automagically route links starting with "/"
-		@el.find( 'a[href*="/"]' ).each ( index, item ) =>
-			$( item ).click ( event ) =>
-				@navigate $( event.target ).attr 'href'
-
-				return off
+    # automagically route links starting with "/"
+    @el.find( 'a[href*="/"]' ).each ( index, item ) =>
+      $( item ).click ( event ) =>
+        @navigate $( event.target ).attr 'href'
+        return off


MainView: minor whitespace

MainView: minor whitespace

--- client/Main/maincontroller/mainviews/mainview.coffee
+++ client/Main/maincontroller/mainviews/mainview.coffee
@@ -218,7 +218,7 @@
   openVMModal: (vm, item) ->

     bounds   = item.getBounds()
-    position =
+    position =
       top    : Math.max bounds.y - 80, 0
       left   : bounds.x + bounds.w + 30


Client: Activity: Using foreach instead of while

--- client/activity/lib/components/chatpane/index.coffee
+++ client/activity/lib/components/chatpane/index.coffee
@@ -47,30 +47,27 @@

     return  unless scrollTop and offsetHeight

-    filter  = Array.prototype.filter
-    markers = document.querySelectorAll '.DateMarker'
+    filter   = Array.prototype.filter
+    chatList = ReactDOM.findDOMNode @refs.ChatList
+    markers  = chatList.querySelectorAll '.DateMarker'

     filtered = filter.call markers, (node) ->
-      return node.className.indexOf('fixedDateMarker') is -1
+      return node.className.indexOf('DateMarker-fixed') is -1

-    i = 0
+    filtered.forEach (dateMarker) ->

-    while i < filtered.length
-
-      { offsetTop, offsetWidth } = filtered[i]
-      fixedDateMarker = filtered[i].querySelector '.fixedDateMarker'
+      { offsetTop, offsetWidth } = dateMarker
+      fixedMarker = dateMarker.querySelector '.DateMarker-fixed'

       if offsetTop >= scrollTop

-        fixedDateMarker.style.display = 'none'
+        fixedMarker.style.display = 'none'

       else if scrollTop > offsetTop

-        fixedDateMarker.style.left    = "#{left}px"
-        fixedDateMarker.style.width   = "#{offsetWidth}px"
-        fixedDateMarker.style.display = 'block'
-
-      i++
+        fixedMarker.style.left    = "#{left}px"
+        fixedMarker.style.width   = "#{offsetWidth}px"
+        fixedMarker.style.display = 'block'

   componentWillUnmount: ->


client: add announcement type to util

client: add announcement type to util

--- client/activity/lib/util/getChannelTypeByName.coffee
+++ client/activity/lib/util/getChannelTypeByName.coffee
@@ -4,4 +4,8 @@
   # have channelName from router, this was the only (probably the easiest) way
   # that came to my mind to determine a type for a channel by its name. - US

-  if name is 'public' then 'group' else 'topic'
+  switch name
+    when 'public' then 'group'
+    when 'changelog' then 'announcement'
+    else 'topic'
+


ace: Make macKey param optional for addKeyCombo method.

--- client/app/Applications/Ace.kdapplication/ace.coffee
+++ client/app/Applications/Ace.kdapplication/ace.coffee
@@ -54,17 +54,17 @@
     @editor.getSession().selection.on 'changeCursor', (cursor)=>
       @emit "ace.change.cursor", @editor.getSession().getSelection().getCursor()

-    @addKeyCombo "save", "Ctrl-S", "Command-S", @bound "requestSave"
-
-    @addKeyCombo "saveAs", "Ctrl-Shift-S", "Command-Shift-S", @bound "requestSaveAs"
-
-    @addKeyCombo "find", "Ctrl-F", "Command-F", => @showFindReplaceView no
-
-    @addKeyCombo "replace", "Ctrl-Shift-F", "Command-Shift-F", => @showFindReplaceView yes
-
-    @addKeyCombo "compileAndRun", "Ctrl-Shift-C", "Command-Shift-C", => @getDelegate().compileAndRun()
-
-    @addKeyCombo "preview", "Ctrl-Shift-P", "Command-Shift-P", => @getDelegate().preview()
+    @addKeyCombo "save", "Ctrl-S", @bound "requestSave"
+
+    @addKeyCombo "saveAs", "Ctrl-Shift-S", @bound "requestSaveAs"
+
+    @addKeyCombo "find", "Ctrl-F", => @showFindReplaceView no
+
+    @addKeyCombo "replace", "Ctrl-Shift-F", => @showFindReplaceView yes
+
+    @addKeyCombo "compileAndRun", "Ctrl-Shift-C", => @getDelegate().compileAndRun()
+
+    @addKeyCombo "preview", "Ctrl-Shift-P", => @getDelegate().preview()

     @getSingleton('windowController').on "keydown", (e) =>
       {findAndReplaceView} = @getDelegate()
@@ -87,7 +87,8 @@
     findAndReplaceView.setTextIntoFindInput selectedText
     findAndReplaceView.on "FindAndReplaceViewClosed", => @focus()

-  addKeyCombo: (name, winKey, macKey, callback) ->
+  addKeyCombo: (name, winKey, callback, macKey) ->
+    macKey or= winKey.replace "Ctrl", "Command"
     @editor.commands.addCommand
       name    : name
       bindKey :


ComputeController.UI: generateAddCredentialFormFor: support selection type field

--- client/app/lib/providers/computecontroller.ui.coffee
+++ client/app/lib/providers/computecontroller.ui.coffee
@@ -52,11 +52,21 @@
     unless credentialFields.length
       return

-    credentialFields.forEach (field)->
-      fields[field] = _.clone Providers[provider].credentialFields[field]
-      fields[field].required = yes
-
-    return form = new KDFormViewWithFields
+    selectOptions = []
+
+    credentialFields.forEach (field) ->
+
+      _field = fields[field] = _.clone Providers[provider].credentialFields[field]
+      _field.required = yes
+
+      if _field.type is 'selection'
+        {values}             = _field
+        _field.itemClass     = kd.SelectBox
+        _field.defaultValue ?= values.first.value
+        selectOptions.push { field, values }
+
+
+    form = new KDFormViewWithFields
       cssClass     : "form-view"
       fields       : fields
       buttons      :
@@ -89,6 +99,12 @@

           unless showError err
             @emit "CredentialAdded", credential
+
+    selectOptions.forEach (select) ->
+      { field, values } = select
+      form.inputs[field].setSelectOptions values
+
+    return form

   @generateCreateInstanceForm: ->


MachineSettingsModal: Disable snapshots tab.

--- client/app/lib/providers/machinesettingsmodal.coffee
+++ client/app/lib/providers/machinesettingsmodal.coffee
@@ -24,7 +24,7 @@
   { title: 'Disk Usage',    viewClass: MachineSettingsDiskUsageView }
   { title: 'Domains',       viewClass: MachineSettingsDomainsView   }
   { title: 'VM Sharing',    viewClass: MachineSettingsVMSharingView }
-  { title: 'Snapshots',     viewClass: MachineSettingsSnapshotsView }
+  # { title: 'Snapshots',     viewClass: MachineSettingsSnapshotsView }
   { title: 'Advanced',      viewClass: MachineSettingsAdvancedView  }
   { title: 'Common guides', viewClass: MachineSettingsGuidesView    }
 ]


ApplicationManager: fixed setMissingRoute for group slugs

--- client/landing/app/MainApp/ApplicationManager.coffee
+++ client/landing/app/MainApp/ApplicationManager.coffee
@@ -26,14 +26,21 @@
       image : "Viewer"
       sound : "Viewer"
     @on 'AppManagerWantsToShowAnApp', @bound "setFrontApp"
+
+    # temp fix, until router logic is complete
     @on 'AppManagerWantsToShowAnApp', @bound "setMissingRoute"

   # temp fix, until router logic is complete
   setMissingRoute:(appController, appView, appOptions)->
-    router = @getSingleton('router')
-    # log router.getCurrentPath(), appOptions.route
-    if router.getCurrentPath().search(appOptions.route.slice(1)) isnt 0
-      router.handleRoute appOptions.route, suppressListeners : yes
+    router       = @getSingleton('router')
+    {entryPoint} = KD.config
+
+    route = if entryPoint?.slug?
+    then "#{entryPoint.slug}#{appOptions.route}"
+    else appOptions.route.slice(1)
+
+    if router.getCurrentPath().search(route) isnt 0
+      router.handleRoute appOptions.route, {suppressListeners : yes, entryPoint}

   open: do ->


double quotes to single quotes

double quotes to single quotes

--- app/coffee/components/contacts/spec.coffee
+++ app/coffee/components/contacts/spec.coffee
@@ -9,20 +9,20 @@
         'plugins/template/look'
         'plugins/form/validate'
         'plugins/template/hbsResolver'
-        "plugins/behavior/dialog"
+        'plugins/behavior/dialog'
     ]

     view:
         render:
             template:
-                module: "text!components/contacts/template.html"
+                module: 'text!components/contacts/template.html'
         insert:
             at: {$ref: 'slot'}

     contactsList:
         render:
             template:
-                module: "text!components/contacts/list.html"
+                module: 'text!components/contacts/list.html'
         insert:
             at: {$ref: 'dom.first!#contactsWrapper', at: 'view'}
         look:
@@ -35,57 +35,57 @@

     contacts:
         create:
-            module: "plugins/utils/entity/Collection"
+            module: 'plugins/utils/entity/Collection'
             args: [
-                {uniqKey: "email"}
+                {uniqKey: 'email'}
             ]

     form:
         render:
             template:
-                module: "text!components/contacts/form.html"
+                module: 'text!components/contacts/form.html'
         insert:
             at: {$ref: 'dom.first!#contactsFormWrapper', at: 'view'}
         validate:
             fieldNames: [
-                "firstName"
-                "lastName"
-                "email"
+                'firstName'
+                'lastName'
+                'email'
             ]
             strategy: {$ref: 'formStrategy'}
             displaySlot: {$ref: 'dom.first!.displayErrorsWrapper', at: 'form'}
-            displaySlotClass: "displaySlotClass"
+            displaySlotClass: 'displaySlotClass'
             successHandler: {$ref: 'controller.addContact'}

-    nameMessage: "The field can contain only english and russian letters and hyphen"
+    nameMessage: 'The field can contain only english and russian letters and hyphen'

     formStrategy:
         firstName:
-            "firstNameValidation":
+            'firstNameValidation':
                 rule: /^[a-zA-Zа-яА-ЯёЁ]+[a-zA-Zа-яА-ЯёЁ\-]*$/g
                 message: {$ref: 'nameMessage'}
         lastName:
-            "lastNameValidation":
+            'lastNameValidation':
                 rule: /^[a-zA-Zа-яА-ЯёЁ]+[a-zA-Zа-яА-ЯёЁ\-]*$/g
                 message: {$ref: 'nameMessage'}
         email:
-            "emailValidation":
+            'emailValidation':
                 rule: /^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/g   #`'"'
-                message: "Input email"
+                message: 'Input email'

     dialog:
         createDialog:
-            body: "Are you going to override it?"
-            confirmButtonLabel: "Yes, override it"
-            refuseButtonLabel: "No, by no means"
-            onDialogShow: {$ref: "controller.onDialogShow"}
-            onConfirmation: {$ref: "controller.onDialogConfirmation"}
-            onDialogClose: {$ref: "controller.onDialogClose"}
-            showAfter: {$ref: "controller.displayWarning"}
-            appendTo: {$ref: "view"}
+            body: 'Are you going to override it?'
+            confirmButtonLabel: 'Yes, override it'
+            refuseButtonLabel: 'No, by no means'
+            onDialogShow: {$ref: 'controller.onDialogShow'}
+            onConfirmation: {$ref: 'controller.onDialogConfirmation'}
+            onDialogClose: {$ref: 'controller.onDialogClose'}
+            showAfter: {$ref: 'controller.displayWarning'}
+            appendTo: {$ref: 'view'}

     controller:
-        create: "components/contacts/controller"
+        create: 'components/contacts/controller'
         properties:
             contacts: {$ref: 'contacts'}
             formStrategy: {$ref: 'formStrategy'}
@@ -95,12 +95,12 @@
             form: {$ref: 'form'}
         on:
             form:
-                "submit": {$ref: 'controller.onSubmit'}
+                'submit': {$ref: 'controller.onSubmit'}
             contactsList:
-                "click": {$ref: 'controller.onListItemClick'}
+                'click': {$ref: 'controller.onListItemClick'}
         ready:
             onReady: {}

     transformer:
-        module: "components/contacts/hashCode"
+        module: 'components/contacts/hashCode'


removed loggedin maincontroller

removed loggedin maincontroller

--- client/landing/app/coffee/core/maincontroller.coffee
+++ client/landing/app/coffee/core/maincontroller.coffee
@@ -1,309 +0,0 @@
-class MainController extends KDController
-  ###
-
-  * EMITTED EVENTS
-    - AppIsReady
-    - AccountChanged                [account, firstLoad]
-    - pageLoaded.as.loggedIn        [account, connectedState, firstLoad]
-    - pageLoaded.as.loggedOut       [account, connectedState, firstLoad]
-    - accountChanged.to.loggedIn    [account, connectedState, firstLoad]
-    - accountChanged.to.loggedOut   [account, connectedState, firstLoad]
-
-  ###
-
-  Promise.longStackTraces()
-
-  connectedState = connected : no
-
-  constructor:(options = {}, data)->
-
-    options.failWait  = 10000            # duration in miliseconds to show a connection failed modal
-
-    super options, data
-
-    @appStorages = {}
-
-    @createSingletons()
-    @setFailTimer()
-    @attachListeners()
-
-    @detectIdleUser()
-    @startCachingAssets()  unless KD.isLoggedInOnLoad
-
-    emojify.setConfig
-      img_dir : 'https://s3.amazonaws.com/koding-cdn/emojis'
-      ignored_tags  :
-        'TEXTAREA'  : 1,
-        'A'         : 1,
-        'PRE'       : 1,
-        'CODE'      : 1
-
-  createSingletons:->
-
-    KD.registerSingleton 'mainController',            this
-
-    KD.registerSingleton 'kontrol',                   new KodingKontrol
-
-    KD.registerSingleton 'appManager',   appManager = new ApplicationManager
-    KD.registerSingleton 'globalKeyCombos',  combos = new KDKeyboardMap priority : 0
-    KD.registerSingleton 'notificationController',    new NotificationController
-    KD.registerSingleton 'linkController',            new LinkController
-    KD.registerSingleton 'display',                   new ContentDisplayController
-    KD.registerSingleton 'kiteController',            new KiteController
-    KD.registerSingleton 'router',           router = new KodingRouter
-    KD.registerSingleton 'localStorageController',    new LocalStorageController
-    KD.registerSingleton 'oauthController',           new OAuthController
-    KD.registerSingleton 'groupsController',          new GroupsController
-    KD.registerSingleton 'activityController',        new ActivityController
-    KD.registerSingleton 'paymentController',         new PaymentController
-    # KD.registerSingleton 'vmController',              new VirtualizationController
-    KD.registerSingleton 'computeController',         new ComputeController
-    KD.registerSingleton 'locationController',        new LocationController
-    KD.registerSingleton 'helpController',            new HelpController
-    KD.registerSingleton 'troubleshoot',              new Troubleshoot
-    KD.registerSingleton 'appStorageController',      new AppStorageController
-    KD.registerSingleton 'localSync',                 new LocalSyncController
-    KD.registerSingleton 'mainView',             mv = new MainView
-    KD.registerSingleton 'mainViewController',  mvc = new MainViewController view : mv
-    KD.registerSingleton 'kodingAppsController',      new KodingAppsController
-    KD.registerSingleton 'socialapi',                 new SocialApiController
-    KD.registerSingleton 'autocomplete',              new AutoCompleteController
-
-    router.listen()
-    @mainViewController = mvc
-    mv.appendToDomBody()
-
-    @ready =>
-      KD.registerSingleton 'widgetController',        new WidgetController
-      KD.registerSingleton 'onboardingController',    new OnboardingController
-
-      @emit 'AppIsReady'
-
-      console.timeEnd 'Koding.com loaded'
-
-    @forwardEvents KD.remote, ['disconnected', 'reconnected']
-
-
-  isFeatureDisabled: (name) ->
-
-    return no  if KD.checkFlag 'super-admin'
-    return no  unless name
-
-    {roles}            = KD.config
-    {disabledFeatures} = KD.getGroup()
-
-    return no  unless disabledFeatures
-
-    role = 'member'    if 'member'    in roles
-    role = 'moderator' if 'moderator' in roles
-    role = 'admin'     if 'admin'     in roles
-
-    return no   if !disabledFeatures[role]
-    return yes  if disabledFeatures[role] and name in disabledFeatures[role]
-
-    return no
-
-
-
-  accountChanged:(account, firstLoad = no)->
-    account = KD.remote.revive account  unless account instanceof KD.remote.api.JAccount
-    KD.userAccount = account
-    connectedState.connected = yes
-
-    @on 'pageLoaded.as.loggedIn', (account)-> # ignore othter parameters
-      KD.utils.setPreferredDomain account if account
-
-    if KD.useNewKites
-      (KD.getSingleton 'kontrol').reauthenticate()
-      # (KD.getSingleton 'kontrolProd').reauthenticate()
-
-    account.fetchMyPermissionsAndRoles (err, res)=>
-
-      return warn err  if err
-
-      KD.config.roles       = res.roles
-      KD.config.permissions = res.permissions
-
-      @ready @emit.bind this, "AccountChanged", account, firstLoad
-
-      @emit 'ready'
-
-      # this emits following events
-      # -> "pageLoaded.as.loggedIn"
-      # -> "pageLoaded.as.loggedOut"
-      # -> "accountChanged.to.loggedIn"
-      # -> "accountChanged.to.loggedOut"
-      eventPrefix = if firstLoad then "pageLoaded.as" else "accountChanged.to"
-      eventSuffix = if KD.isLoggedIn() then "loggedIn" else "loggedOut"
-      @emit "#{eventPrefix}.#{eventSuffix}", account, connectedState, firstLoad
-
-  doLogout:->
-    mainView = KD.getSingleton("mainView")
-    KD.logout()
-    storage = new LocalStorage 'Koding'
-
-    KD.remote.api.JUser.logout (err) =>
-      mainView._logoutAnimation()
-      KD.singletons.localSync.removeLocalContents()
-
-      Cookies.expire "koding082014"
-      Cookies.expire "useOldKoding"
-
-      wc = KD.singleton 'windowController'
-      wc.clearUnloadListeners()
-
-      KD.utils.wait 1000, =>
-        @swapAccount replacementAccount: null
-        storage.setValue 'loggingOut', '1'
-        location.reload()
-
-  attachListeners:->
-    # @on 'pageLoaded.as.(loggedIn|loggedOut)', (account)=>
-    #   log "pageLoaded", KD.isLoggedIn()
-
-    # TODO: this is a kludge we needed.  sorry for this.  Move it someplace better C.T.
-    wc = KD.singleton 'windowController'
-    @utils.wait 15000, ->
-      KD.remote.api?.JSystemStatus.on 'forceReload', ->
-        window.removeEventListener 'beforeunload', wc.bound 'beforeUnload'
-        location.reload()
-
-    # async clientId change checking procedures causes
-    # race conditions between window reloading and post-login callbacks
-    cookieChangeHandler = do (cookie = Cookies.get 'clientId') => =>
-      cookieExists = cookie?
-      cookieMatches = cookie is (Cookies.get 'clientId')
-      cookie = Cookies.get 'clientId'
-
-      if cookieExists and not cookieMatches
-        return @isLoggingIn off  if @isLoggingIn() is on
-
-        window.removeEventListener 'beforeunload', wc.bound 'beforeUnload'
-        @emit "clientIdChanged"
-
-        # window location path is set to last route to ensure visitor is not
-        # redirected to another page
-        @utils.defer ->
-          lastRoute = localStorage?.routeToBeContinued or KD.getSingleton("router").visitedRoutes.last
-
-          if lastRoute and /^\/(?:Reset|Register|Verify|Confirm)\//.test lastRoute
-            lastRoute = "/Activity"
-
-          {entryPoint} = KD.config
-          KD.getSingleton('router').handleRoute lastRoute or '/Activity', {replaceState: yes, entryPoint}
-          localStorage?.removeItem "routeToBeContinued"
-
-        @utils.wait 3000, cookieChangeHandler
-    # Note: I am using wait instead of repeat, for the subtle difference.  See this StackOverflow answer for more info:
-    #       http://stackoverflow.com/questions/729921/settimeout-or-setinterval/731625#731625
-    @utils.wait 3000, cookieChangeHandler
-
-  swapAccount: (options, callback) ->
-    return { message: 'Login failed!' } unless options
-
-    { account, replacementToken } = options
-
-    { maxAge, secure } = KD.config.sessionCookie
-
-    if replacementToken and replacementToken isnt Cookies.get 'clientId'
-      Cookies.set 'clientId', replacementToken, { maxAge, secure }
-      window.location.href= '/'
-
-    if account
-      @accountChanged account
-      if callback
-        @once 'AccountChanged', (account) -> callback null, options
-
-  handleLogin: (credentials, callback) ->
-    { JUser } = KD.remote.api
-
-    @isLoggingIn on
-
-    credentials.username = credentials.username.toLowerCase().trim()
-
-    JUser.login credentials, (err, result) =>
-      return callback err  if err
-      KD.setVersionCookie result.account
-      @swapAccount result, callback
-
-  handleFinishRegistration: (formData, callback) ->
-    { JUser } = KD.remote.api
-
-    @isLoggingIn on
-
-    JUser.finishRegistration formData, (err, result) =>
-      return callback err  if err
-      @swapAccount result, callback
-
-  handleOauthAuth : (formData, callback)->
-    { JUser } = KD.remote.api
-
-    @isLoggingIn on
-
-    # Same oauth flow is used for login and registering, however
-    # after auth code paths differs.
-    JUser.authenticateWithOauth formData, (err, result) =>
-      return callback err          if err
-      return callback err, result  if result.isNewUser
-      return callback err, result  if formData.isUserLoggedIn
-
-      @swapAccount result, callback
-
-  isLoggingIn: (isLoggingIn) ->
-
-    storage = new LocalStorage 'Koding'
-    if storage.getValue('loggingOut') is '1'
-      storage.unsetKey 'loggingOut'
-      return yes
-    if isLoggingIn?
-      @_isLoggingIn = isLoggingIn
-    else
-      @_isLoggingIn ? no
-
-  setFailTimer: do->
-    notification = null
-    fail  = ->
-
-      notification = new KDNotificationView
-        title         : "Couldn't connect to backend!"
-        type          : "tray"
-        closeManually : no
-        content       : """We don't know why, but your browser couldn't reach our server.
-                           <br>Still trying but if you want you can click here to refresh the page."""
-        duration      : 0
-        click         : -> location.reload yes
-
-    checkConnectionState = ->
-      unless connectedState.connected
-        KD.logToExternalWithTime "Connect to backend"
-        fail()
-
-    return ->
-      @utils.wait @getOptions().failWait, checkConnectionState
-      @on "AccountChanged", -> notification.destroy()  if notification
-
-  detectIdleUser: (threshold = KD.config.userIdleMs) ->
-    idleDetector = new IdleUserDetector { threshold }
-    @forwardEvents idleDetector, ['userIdle', 'userBack']
-
-
-  startCachingAssets:->
-
-    KD.singletons.appManager.require 'Login', ->
-
-      images = [
-        '/a/images/city.jpg'
-        '/a/images/home-pat.png'
-        '/a/images/edu-pat.png'
-        '/a/images/biz-pat.png'
-        '/a/images/pricing-pat.png'
-        '/a/images/ss-activity.jpg'
-        '/a/images/ss-terminal.jpg'
-        '/a/images/ss-teamwork.jpg'
-        '/a/images/ss-environments.jpg'
-        "/a/images/unsplash/#{LoginView.backgroundImageNr}.jpg"
-      ]
-
-      for src in images
-        image     = new Image
-        image.src = src


Fix multiple line quotes

Fix multiple line quotes

--- client/landing/site.landing/coffee/core/utils.coffee
+++ client/landing/site.landing/coffee/core/utils.coffee
@@ -400,7 +400,7 @@
             return container.emit 'TwoFactorEnabled'  if /TwoFactor/i.test responseText

             container.emit 'EmailIsNotAvailable'
-            input.setValidationResult 'available', """Sorry, #{email} is already in use!"""
+            input.setValidationResult 'available', "Sorry, #{email} is already in use!"

   checkedPasswords: {}
@@ -563,4 +563,4 @@
       data        : { username }
       xhrFields   : withCredentials : yes
       success     : callbacks.success
-      error       : callbacks.error+      error       : callbacks.error


Added another test for measurements.

Added another test for measurements.

--- spec/finger_tree_spec.coffee
+++ spec/finger_tree_spec.coffee
@@ -43,6 +43,14 @@
   it "should have the right size", ->
     expect(tree.measure()).toBe 10

+  it "should produce correct sizes while being deconstructed", ->
+    expect(tree.init().measure()).toBe 9
+    expect(tree.rest().measure()).toBe 9
+    expect(tree.init().init().measure()).toBe 8
+    expect(tree.init().rest().measure()).toBe 8
+    expect(tree.rest().init().measure()).toBe 8
+    expect(tree.rest().rest().measure()).toBe 8
+
 describe "A finger tree made by appending elements from a sequence", ->
   tree = FingerTree.buildLeft [1..100]...