Handles connection errors to origin.

Handles connection errors to origin.

--- src/middleware/proxyRequest.coffee
+++ src/middleware/proxyRequest.coffee
@@ -11,7 +11,6 @@
         agent: false # Disable connection pooling

     RequestClient = if req.secure then Https else Http
-
     clientReq = RequestClient.request options, (clientRes) ->
         statusCode = clientRes.statusCode
         headers = clientRes.headers
@@ -31,7 +30,14 @@

             if clientRes.trailers
                 res.addTrailers clientRes.trailers
-
+
+    clientReq.on "error", (err) ->
+        console.log "Request Error:"
+        console.dir err
+
+        res.writeHead 500, "Error connecting.", {}
+        res.end()
+
     req.on "data", (data) ->
         clientReq.write data


`Scope.toItemCtor()` added

`Scope.toItemCtor()` added

--- scope.coffee
+++ scope.coffee
@@ -7,7 +7,7 @@

 {isArray} = Array

-module.exports = class Scope
+class Scope
 	@__name__ = 'Scope'

 	@ID_RE = ///^([a-z0-9_A-Z]+)$///
@@ -57,9 +57,11 @@
 		# only children
 		if isArray opts
 			children = opts
+			opts = null

 			# opts as first child
 			if utils.isObject children[0]
+				children = utils.clone children
 				opts = children.shift()

 		opts ?= {}
@@ -76,4 +78,39 @@
 		else
 			item = new ctor opts

-		item+		item
+
+history = {}
+module.exports = class CloneableScope extends Scope
+
+	constructor: ->
+		super
+		history[@id] = []
+
+	create: (type, opts, children) ->
+		history[@id].push [type, utils.clone(opts), utils.clone(children)]
+
+		super
+
+	clone: ->
+		new Scope
+			id: "#{@id}_#{utils.uid()}"
+
+	toItemCtor: ->
+		(opts, children) =>
+			scope = @clone()
+
+			calls = history[@id]
+			for call in calls
+				scope.create call[0], call[1], call[2]
+
+			# custom opts
+			if opts?
+				utils.merge scope.mainItem, opts
+
+			# extra children
+			if children?
+				for child in children
+					child.parent = scope.mainItem
+
+			scope.mainItem


Fixed fact_id that might have been changed

--- core/app/backbone/views/evidence/react_add_comment.coffee
+++ core/app/backbone/views/evidence/react_add_comment.coffee
@@ -61,9 +61,9 @@

     @model().unshift(comment)
     comment.save {},
-      success: =>
+      success: ->
         mp_track "Factlink: Added comment",
-          factlink_id: @model().fact.id
+          factlink_id: comment.collection.fact.id
       error: =>
         @model().remove(comment)
         FactlinkApp.NotificationCenter.error 'Your comment could not be posted, please try again.'


Made logic a bit clearer

Made logic a bit clearer

--- core/app/backbone/views/wheel/base_fact_wheel_view.coffee
+++ core/app/backbone/views/wheel/base_fact_wheel_view.coffee
@@ -144,16 +144,21 @@
       path: [["M", start.x, start.y], ["A", radius, radius, 0, direction, 0, end.x, end.y]]

   mouseoverOpinionType: (path, opinionType) ->
-    destinationOpacity = @options.hoverStrokeOpacity
-    destinationOpacity = @options.userOpinionStrokeOpacity  if opinionType.is_user_opinion
+    destinationOpacity = if opinionType.is_user_opinion
+                           @options.userOpinionStrokeOpacity
+                         else
+                           @options.hoverStrokeOpacity
+
     path.animate(
       "stroke-width": @hoverStrokeWidth()
       opacity: destinationOpacity
     , 200, "<>")

   mouseoutOpinionType: (path, opinionType) ->
-    destinationOpacity = @options.defaultStrokeOpacity
-    destinationOpacity = @options.userOpinionStrokeOpacity  if opinionType.is_user_opinion
+    destinationOpacity = if opinionType.is_user_opinion
+                           @options.userOpinionStrokeOpacity
+                         else
+                           @options.defaultStrokeOpacity
     path.animate(
       "stroke-width": @defaultStrokeWidth()
       opacity: destinationOpacity


2014-03-14

--- tasks/sass-format.coffee
+++ tasks/sass-format.coffee
@@ -63,17 +63,22 @@

                 # セレクタ後スペース有無チェック
                 if /[^ ][ ][{,]$/.test(text[i])
-                  msg += 'スペース有り'
+                  #msg += 'スペース有り'
+                  msg += ''
                 if /[^ ][ ]{2,}[{,]$/.test(text[i])
-                  msg += '!!スペース多い!!'
+                  #msg += '!!スペース多い!!'
+                  msg += ''
                 if /[^ ][{,]$/.test(text[i])
-                  msg += '!!スペースなし!!'
+                  #msg += '!!スペースなし!!'
+                  msg += ''

                 # セレクタ並び方チェック
                 if /^[^,]+[{,]$/.test(text[i])
-                  msg += '1行1プロパティ'
+                  #msg += '1行1プロパティ'
+                  msg += ''
                 if /^([^,]+,){1,}[^,{]+{$/.test(text[i])
-                  msg += '!!1行に複数ある!!'
+                  #msg += '!!1行に複数ある!!'
+                  msg += ''

                 # セレクタ記述終了
                 if /^([ \t]+)?.*{([ \t]+)?$/.test(text[i])
@@ -84,8 +89,13 @@

               #セレクタ記述
               if /^[^;]+;$/.test(text[i])
+
                 #インデントチェック
+                #!!要改良!!
+
                 #タブ
+                if /^[^\t ]{1,}/.test(text[i])
+                  msg += 'インデント無し'
                 if /^[\t]{1,}/.test(text[i])
                   msg += 'インデントがタブ'
                 #ホワイトスペース
@@ -101,6 +111,11 @@
                 else
                   msg += 'インデント指定通りじゃない'

+                #コロンの後のスペース
+                if /: /.test(text[i])
+                  msg += 'スペース有り'
+                if /:[^ ]/.test(text[i])
+                  msg += 'スペース無し'

                 console.log line+': '+msg+': '+text[i]


Visibility management fixes

Visibility management fixes


Small cleanup.

Small cleanup.

--- public/src/controllers/view-player-controller.coffee
+++ public/src/controllers/view-player-controller.coffee
@@ -55,11 +55,9 @@
         # Load matches for the player
         @loadMoreMatches()

-        # Refresh matches REFRESH_MATCHES_INTERVAL
+        # Refresh matches every REFRESH_MATCHES_INTERVAL
         @matchProgressLoader.once('finish', () =>
-          @refreshMatchTimeout = $timeout(() =>
-            @refreshMatches()
-          , REFRESH_MATCHES_INTERVAL)
+          @refreshMatchTimeout = $timeout(@refreshMatches, REFRESH_MATCHES_INTERVAL)
         )

         $scope.$on '$destroy', () =>
@@ -92,7 +90,7 @@
           .catch @onMatchesLoadError

       # Method for refreshing the first few match
-      refreshMatches: () ->
+      refreshMatches: () =>
         @player.getMatches(10, null, false).then (matchData) =>
           highMatchId = @matches[0].match_id
           newMatches = _.filter matchData.matches, (match) ->


:arrow_up: adapt signature view to accessor

--- src/renderer/components/doc-signatures-component.coffee
+++ src/renderer/components/doc-signatures-component.coffee
@@ -9,26 +9,76 @@
     c = @props.current

       {
-        return_elm = []
+        elm = []
         if c.signatures?
-          return_elm.push {c.signatures[0].name}
-          return_elm.push (
+          elm.push {c.signatures[0].name}
+          elm.push (
           c.signatures[0].parameters?.forEach (prm, i) ->
-            return_elm.push {prm.name}
-            return_elm.push :
-            return_elm.push {prm.type.name}
+            elm.push {prm.name}
+            elm.push :
+            elm.push {prm.type.name}
             if prm.type.isArray
-              return_elm.push []
+              elm.push []
             if i != c.signatures[0].parameters.length - 1
-              return_elm.push ,
-          return_elm.push )
-          return_elm.push :
-          return_elm.push {c.signatures[0].type.name}
+              elm.push ,
+          elm.push )
+          elm.push :
+          elm.push {c.signatures[0].type.name}
         else if c.type?
-          return_elm.push {c.name}
-          return_elm.push :
-          return_elm.push {c.type.name}
-        return_elm
+          elm.push {c.name}
+          elm.push :
+          elm.push {c.type.name}
+          if c.type.typeArguments?
+            elm.push {'<'}
+            elm.push {c.type.typeArguments[0].name}
+            elm.push {'>'}
+        else
+          dstyle = {}
+          if c.getSignature? && c.setSignature?
+            dstyle =
+              get_signature:
+                paddingBottom: 11
+                borderBottomWidth: 1
+                borderBottomStyle: 'solid'
+                borderBottomColor: '#555'
+              set_signature:
+                paddingTop: 10
+          if c.getSignature?
+            elm.push do ->
+

+                get
+                {c.name}
+                ():
+                {c.getSignature[0].type.name}
+                {
+                  if c.getSignature[0].type.isArray
+                    []
+                }
+

+          if c.setSignature?
+            elm.push do ->
+

+                set
+                {c.name}
+                (
+                {
+                  prm_elm = []
+                  c.setSignature[0].parameters.forEach (prm, i) ->
+                    prm_elm.push {prm.name}
+                    prm_elm.push :
+                    prm_elm.push {prm.type.name}
+                    if i != c.setSignature[0].parameters.length - 1
+                      prm_elm.push ,
+                  prm_elm
+                }
+                ):
+                {c.getSignature[0].type.name}
+                {
+                  if c.getSignature[0].type.isArray
+                    []
+                }
+

+        elm
       }


fix keyboard traps in the update avatar dialog

when elements change in the dialog, the keyboard focus can get
reset to the document body and the user couldn't get back into
the dialog via keyboard

fixes CNVS-23328

test plan:
 - open the dialog to update a user's avatar
 - use the keyboard to select a file a file to upload
 - should still be able to navigate dialog via keyboard after
   choosing a file
   - note that you never could set the crop via keyboard
   - note focus gets reset to the close button because the
     element that had focus is gone
 - run the same test with the Take Picture pane of the dialog
 - test in multiple browsers; it's a bit more likely than usual
   that there will be browser specific problems for this fix.

Change-Id: I4e07b7104c3cd14a258de2c027e41c531f29cbe2
Reviewed-on: https://gerrit.instructure.com/64884
Tested-by: Jenkins
Reviewed-by: Clay Diffrient <9dff2e5c98626d20d2848250c411e8009465bb87@instructure.com>
QA-Review: Jahnavi Yetukuri <ed2b2672ccc2e59e56c0615df7f01b579202e014@instructure.com>
Product-Review: Jon Willesen <eb5ce5e6a76c243326fecfa94534101600f87bd9@instructure.com>

--- app/coffeescripts/views/profiles/AvatarDialogView.coffee
+++ app/coffeescripts/views/profiles/AvatarDialogView.coffee
@@ -220,6 +220,16 @@

     onReady: (ready = true) ->
       $('.select_button').prop('disabled', !ready)
+      @checkFocus()
+
+    checkFocus: () ->
+      # deferring this makes it work more reliably because in some cases (like
+      # visibility updates) the focus isn't lost immediately.
+      _.defer(@checkFocusDeferred)
+
+    checkFocusDeferred: () =>
+      unless $.contains(@$el[0], document.activeElement) && $(document.activeElement).is(':visible')
+        $('.ui-dialog-titlebar-close').focus()

     teardown: ->
       _.each(@children, (child) -> child.teardown())


just uncommenting codes :D

just uncommenting codes :D

--- scripts/coffee/lib/_Film.coffee
+++ scripts/coffee/lib/_Film.coffee
@@ -138,28 +138,28 @@
 			actor.addPropOfObject 'Width', objName, 'widthNormalized', 0
 			actor.addPropOfObject 'Height', objName, 'heightNormalized', 0

-		# if 'hallowText' in props
+		if 'hallowText' in props

-		# 	hallowText = new HallowText el, 5
+			hallowText = new HallowText el, 5

-		# 	hallowTextObjectName = objName + '-hallowText'
+			hallowTextObjectName = objName + '-hallowText'

-		# 	@theatre.timeline.addObject hallowTextObjectName, hallowText
+			@theatre.timeline.addObject hallowTextObjectName, hallowText

-		# 	hallowActor = @theatre.model.graph.getGroup groupName
-		# 	.getActor actorName + ' - HallowText'
+			hallowActor = @theatre.model.graph.getGroup groupName
+			.getActor actorName + ' - HallowText'

-		# 	@_addNormalizedAlternative hallowText, 'setBaseRadius', 'setBaseRadiusNormalized'
-		# 	@_addNormalizedAlternative hallowText, 'setMaxMotionRadius', 'setMaxMotionRadiusNormalized'
-		# 	@_addNormalizedAlternative hallowText, 'setVelocityX', 'setVelocityXNormalized'
-		# 	@_addNormalizedAlternative hallowText, 'setVelocityY', 'setVelocityYNormalized'
+			@_addNormalizedAlternative hallowText, 'setBaseRadius', 'setBaseRadiusNormalized'
+			@_addNormalizedAlternative hallowText, 'setMaxMotionRadius', 'setMaxMotionRadiusNormalized'
+			@_addNormalizedAlternative hallowText, 'setVelocityX', 'setVelocityXNormalized'
+			@_addNormalizedAlternative hallowText, 'setVelocityY', 'setVelocityYNormalized'

-		# 	hallowActor.addPropOfObject 'Base Radius', hallowTextObjectName, 'setBaseRadiusNormalized', 0
-		# 	hallowActor.addPropOfObject 'Max Motion Radius', hallowTextObjectName, 'setMaxMotionRadiusNormalized', 10
-		# 	hallowActor.addPropOfObject 'Samples', hallowTextObjectName, 'setSamples', 5
+			hallowActor.addPropOfObject 'Base Radius', hallowTextObjectName, 'setBaseRadiusNormalized', 0
+			hallowActor.addPropOfObject 'Max Motion Radius', hallowTextObjectName, 'setMaxMotionRadiusNormalized', 10
+			hallowActor.addPropOfObject 'Samples', hallowTextObjectName, 'setSamples', 5

-		# 	hallowActor.addPropOfObject 'Velocity X', hallowTextObjectName, 'setVelocityXNormalized', 0
-		# 	hallowActor.addPropOfObject 'Velocity Y', hallowTextObjectName, 'setVelocityYNormalized', 0
+			hallowActor.addPropOfObject 'Velocity X', hallowTextObjectName, 'setVelocityXNormalized', 0
+			hallowActor.addPropOfObject 'Velocity Y', hallowTextObjectName, 'setVelocityYNormalized', 0

 		if 'wysihwyg' in props and @wysihwyg?


Handle css live reloading correctly.

Handle css live reloading correctly.

--- grunt/config/watch.coffee
+++ grunt/config/watch.coffee
@@ -37,10 +37,8 @@
       files: [
         '<%= watch.express.files %>'
         '<%= watch.client.files %>'
-        '<%= watch.coffee2css.files %>'
-        #'<%= watch.less.files %>'
-        'static/css/*.css'
         '<%= watch.i18n.files %>'
         '<%= watch.jade.files %>'
+        '<%= static %>/css/*.css'
       ]
   }


fix auto grow height calculation procedure

replace newline characters with line break

--- client/Framework/components/inputs/KDInputView.coffee
+++ client/Framework/components/inputs/KDInputView.coffee
@@ -333,7 +333,7 @@
       @$()[0].style.height = "none" # hack to set to initial

     @on "keydown", =>
-      $growCalculator.text @getValue()
+      $growCalculator.html @getValue().replace /\n/gm, "<br />"
       height = $growCalculator.height()
       if @$().css('box-sizing') is "border-box"
         padding    = parseInt($growCalculator.css("padding-top"), 10) + parseInt($growCalculator.css("padding-bottom"), 10)


removed semi-colons [b116039ad6ed94c2040de00d2b1727ca4ff0ae82]

--- review_front/app/components/copy-to-clipboard.coffee
+++ review_front/app/components/copy-to-clipboard.coffee
@@ -1,4 +1,4 @@
-`import Ember from 'ember';`
+`import Ember from 'ember'`
 `import ZeroClipboard from 'ember-cli-zero-clipboard/components/zero-clipboard';`

 CopyToClipboard = ZeroClipboard.extend
@@ -17,4 +17,4 @@
       ), 1500

-`export default CopyToClipboard;`
+`export default CopyToClipboard`


add getter for asset type name

add getter for asset type name

--- v1meta.coffee
+++ v1meta.coffee
@@ -2,10 +2,6 @@

 client = require('./client')
 et = require('elementtree')
-
-future = require('fibers/future')
-wait = future.wait
-

 class AssetClassBase
@@ -21,6 +17,8 @@
         return @
     create_in_context: (asste_type, data) ->
         pass
+    getName: () ->
+        return @_v1_asset_type_name
     _v1_get: (attr) ->
         if attr of @v1_new_data
             return @v1_new_data[attr]
@@ -85,13 +83,11 @@
                     _v1_ops: []
                     _v1_attrs: []
                     constructor: (@id) ->
-
             xml.iter 'Operation', (operation) ->
                 opname = operation.get('name')
                 cls::_v1_ops.push(opname)
                 cls.prototype[opname] = () ->
                     @_v1_execute_operation(opname)
-
             xml.iter 'AttributeDefinition', (attribute) ->
                 attr = attribute.get('name')
                 cls::_v1_attrs.push(attr)
@@ -115,28 +111,5 @@
                 cls = @build_asset_class_from_xml(asset_type_name, xml)
                 callback(undefined, cls)

-        #query: (asset_types, where_terms, select_list, callback) ->
-        #    fiber = Fiber () ->
-        #        classes = {}
-        #        for asset_type in asset_types.split(" ")
-        #            classes[asset_type] = @sync_get_asset_type(asset_type)
-        #        query = @prepare_query(where_terms, select_list)
-        #        @run_query(query, callback)
-        #
-        #    return fiber.run()
-
-        #sync_run_query: (asset_type, where_terms, select_list) ->
-        #    f = future.wrap(@run_query)
-        #    return f(where_terms, select_list).wait()
-
-        #sync_get_asset_class: (asset_type_name) ->
-        #    self = this
-        #    getit = future.wrap((name, cb) -> self.get_asset_class(name,cb))
-        #    return getit(asset_type_name).wait()
-
-        #asset_from_oid: (oidtoken) ->
-        #    sync_get_asset_class = future.wrap(@get_asset_class)
-        #    [asset_type, id] = oidtoken.split(':', 2)
-        #    AssetClass = sync_get_asset_class(asset_type).wait()
-        #    return new AssetClass(id)
+


updated failure message in spec

updated failure message in spec

the old "Expected these tables..." doesn't make sense anymore

--- spec/stringTable_spec.coffee
+++ spec/stringTable_spec.coffee
@@ -28,7 +28,7 @@
       toMatchTable: (expectedTable) ->
         this.message = ->
           """
-          Expected these tables to match:
+          Table did not match expectations:

           #{juxtapose(this.actual, expectedTable, 5)}
           """


:green_heart: Fix more tests using tokenizedLineForScreenRow

--- spec/text-editor-spec.coffee
+++ spec/text-editor-spec.coffee
@@ -4988,11 +4988,11 @@

       runs ->
         expect(editor.getGrammar()).toBe atom.grammars.nullGrammar
-        expect(editor.tokenizedLineForScreenRow(0).tokens.length).toBe 1
+        expect(editor.tokensForScreenRow(0).length).toBe(1)

         atom.grammars.addGrammar(jsGrammar)
         expect(editor.getGrammar()).toBe jsGrammar
-        expect(editor.tokenizedLineForScreenRow(0).tokens.length).toBeGreaterThan 1
+        expect(editor.tokensForScreenRow(0).length).toBeGreaterThan 1

   describe "editor.autoIndent", ->
     describe "when editor.autoIndent is false (default)", ->
@@ -5220,10 +5220,10 @@
       expect(editor.getSelectedBufferRanges()).toEqual [[[3, 5], [3, 5]], [[9, 0], [14, 0]]]

       # folds are also duplicated
-      expect(editor.tokenizedLineForScreenRow(5).fold).toBeDefined()
-      expect(editor.tokenizedLineForScreenRow(7).fold).toBeDefined()
-      expect(editor.tokenizedLineForScreenRow(7).text).toBe "    while(items.length > 0) {"
-      expect(editor.tokenizedLineForScreenRow(8).text).toBe "    return sort(left).concat(pivot).concat(sort(right));"
+      expect(editor.isFoldedAtScreenRow(5)).toBe(true)
+      expect(editor.isFoldedAtScreenRow(7)).toBe(true)
+      expect(editor.lineTextForScreenRow(7)).toBe "    while(items.length > 0) {⋯"
+      expect(editor.lineTextForScreenRow(8)).toBe "    return sort(left).concat(pivot).concat(sort(right));"

     it "duplicates all folded lines for empty selections on folded lines", ->
       editor.foldBufferRow(4)
@@ -5419,17 +5419,15 @@
         runs ->
           editor.setText("// http://github.com")

-          {tokens} = editor.tokenizedLineForScreenRow(0)
-          expect(tokens[1].value).toBe " http://github.com"
-          expect(tokens[1].scopes).toEqual ["source.js", "comment.line.double-slash.js"]
+          tokens = editor.tokensForScreenRow(0)
+          expect(tokens).toEqual ['source.js', 'comment.line.double-slash.js', 'punctuation.definition.comment.js']

         waitsForPromise ->
           atom.packages.activatePackage('language-hyperlink')

         runs ->
-          {tokens} = editor.tokenizedLineForScreenRow(0)
-          expect(tokens[2].value).toBe "http://github.com"
-          expect(tokens[2].scopes).toEqual ["source.js", "comment.line.double-slash.js", "markup.underline.link.http.hyperlink"]
+          tokens = editor.tokensForScreenRow(0)
+          expect(tokens).toEqual ['source.js', 'comment.line.double-slash.js', 'punctuation.definition.comment.js', 'markup.underline.link.http.hyperlink']

       describe "when the grammar is updated", ->
         it "retokenizes existing buffers that contain tokens that match the injection selector", ->
@@ -5439,28 +5437,22 @@
           runs ->
             editor.setText("// SELECT * FROM OCTOCATS")

-            {tokens} = editor.screenLineForScreenRow(0)
-            expect(tokens[2].closeTags).toEqual ['comment.line.double-slash.js', 'source.js']
-            expect(tokens[2].openTags).toEqual []
-            expect(tokens[2].text).toBe ""
+            tokens = editor.tokensForScreenRow(0)
+            expect(tokens).toEqual ['source.js', 'comment.line.double-slash.js', 'punctuation.definition.comment.js']

           waitsForPromise ->
             atom.packages.activatePackage('package-with-injection-selector')

           runs ->
-            {tokens} = editor.screenLineForScreenRow(0)
-            expect(tokens[2].closeTags).toEqual ['comment.line.double-slash.js', 'source.js']
-            expect(tokens[2].openTags).toEqual []
-            expect(tokens[2].text).toBe ""
+            tokens = editor.tokensForScreenRow(0)
+            expect(tokens).toEqual ['source.js', 'comment.line.double-slash.js', 'punctuation.definition.comment.js']

           waitsForPromise ->
             atom.packages.activatePackage('language-sql')

           runs ->
-            {tokens} = editor.screenLineForScreenRow(2)
-            expect(tokens[2].closeTags).toEqual []
-            expect(tokens[2].openTags).toEqual ["keyword.other.DML.sql"]
-            expect(tokens[2].text).toBe "SELECT"
+            tokens = editor.tokensForScreenRow(0)
+            expect(tokens).toEqual ['source.js', 'comment.line.double-slash.js', 'punctuation.definition.comment.js', 'keyword.other.DML.sql', 'keyword.operator.star.sql', 'keyword.other.DML.sql']

   describe ".normalizeTabsInBufferRange()", ->
     it "normalizes tabs depending on the editor's soft tab/tab length settings", ->


wip in arvid's branch

wip in arvid's branch

--- node_modules_koding/jraphical/lib/graphlet.coffee
+++ node_modules_koding/jraphical/lib/graphlet.coffee
@@ -63,13 +63,13 @@
       @push relationships...
       callback null

-    selectFromNode =(sharedOptions, acc, node, callback)->
+    selectFromNode =(node, sharedOptions, acc, callback)->
       {selector, query, limit, sort, skip, hint} = sharedOptions
       selector = extend {}, selector, sourceId: node.getId()
       options = {limit, sort, skip, hint}
       Relationship.some selector, options, selectorCallback.bind acc, callback

-    selectFromEdge =(sharedOptions, acc, edge, callback)->
+    selectFromEdge =(edge, sharedOptions, acc, callback)->
       {selector, query, limit, sort, skip, hint} = options
       selector = extend {}, selector, sourceId: edge.targetId
       options = {limit, sort, skip, hint}


Fix follow btn following context

Fix follow btn following context

--- assets/javascripts/views/profile_follow_button.js.coffee
+++ assets/javascripts/views/profile_follow_button.js.coffee
@@ -9,16 +9,11 @@
     @entity = @$entity.val()

     @current_entity = @parentView.entity
-    if TentStatus.config.domain_entity.assertEqual(@current_entity)
-      api_root = TentStatus.config.tent_api_root
-    else
-      api_root = TentStatus.config.tent_proxy_root + "/#{encodeURIComponent @current_entity}"
-
     if @entity == TentStatus.config.current_entity.toStringWithoutSchemePort()
       @buttons.submit.attr 'disabled', 'disabled'
       @buttons.submit.val 'You'
     else
-      new HTTP 'GET', "#{api_root}/followings", {
+      new HTTP 'GET', "#{TentStatus.config.tent_api_root}/followings", {
         entity: @entity
       }, (followings, xhr) =>
         return unless xhr.status == 200


Revert "Compact HUD"

Revert "Compact HUD"

This reverts commit a1215ac56163ca281a3d324f6d2b8ff46aa56331.

--- modules/player/hud.coffee
+++ modules/player/hud.coffee
@@ -75,26 +75,32 @@
       url: item.sauce
       color: 0xAAFF00
       title: '[click for sauce]'
-      description: """
-      [[donate]](https://tblnk.me/focabot-donate/)
-      **Length**: #{@util.displayTime item.duration}
-      **Position in queue**: ##{pos}
-      """
+      description: '[[donate]](https://tblnk.me/focabot-donate/)'
       author:
         name: item.title
         icon_url: @util.getIcon item.sauce
       thumbnail:
         url: item.thumbnail
+      fields: [
+        { name: 'Length:', value: "#{@util.displayTime item.duration}\n ", inline: true }
+        { name: 'Position in queue:', value: "##{pos}", inline: true }
+      ]
       footer:
         icon_url: item.requestedBy.staticAvatarURL
         text: "Requested by #{item.requestedBy.name}"
     if item.filters and item.filters.length
-      reply.description += "\n**Filters**: #{@util.displayFilters(item.filters)}"
+      reply.description = "**Filters**: #{@util.displayFilters(item.filters)}"
     if item.time and item.time > 0
-      reply.description += "\n**Start at**: #{@util.displayTime(item.time)}"
+      reply.fields.push {
+        name: 'Start at:'
+        value: @util.displayTime(item.time)
+        inline: true
+      }
     if estimated
-      est = @util.displayTime(estimated)
-      reply.description += "\n**Estimated time before playback**: #{est}"
+      reply.fields.push {
+        name: 'Estimated time before playback:',
+        value: @util.displayTime(estimated)
+      }
     reply

   removeItem: (item, removedBy)=>
@@ -102,21 +108,21 @@
       url: item.sauce
       color: 0xF44277
       title: '[click for sauce]'
-      description: """
-      [[donate]](https://tblnk.me/focabot-donate/)
-      **Length**: #{@util.displayTime item.duration}
-      """
+      description: '[[donate]](https://tblnk.me/focabot-donate/)'
       author:
         name: item.title
         icon_url: @util.getIcon item.sauce
       thumbnail:
         url: item.thumbnail
+      fields: [
+        { name: 'Length:', value: "#{@util.displayTime item.duration}\n ", inline: true }
+      ]
     if removedBy
       reply.footer =
         icon_url: removedBy.staticAvatarURL
         text: "Removed by #{removedBy.name}"
     if item.filters and item.filters.length
-      reply.description += "\n**Filters**: #{@util.displayFilters(item.filters)}"
+      reply.description = "**Filters**: #{@util.displayFilters(item.filters)}"
     reply

   addPlaylist: (user, playlist, channel)=>
@@ -160,7 +166,6 @@
       description: """
       [[donate]](https://tblnk.me/focabot-donate/)
       #{@generateProgressOuter item}
-      **Length**: #{@util.displayTime item.duration}
       """
       author:
         name: item.title
@@ -170,11 +175,14 @@
       footer:
         text: "Requested by #{item.requestedBy.name}"
         icon_url: item.requestedBy.staticAvatarURL
+      fields: [
+        { inline: true, name: 'Length', value: @util.displayTime item.duration }
+      ]
     }
     if item.filters and item.filters.length
-      r.description += "\n**Filters**: #{@util.displayFilters item.filters}"
+      r.fields.push { inline: true, name: 'Filters', value: @util.displayFilters item.filters }
     if item.radioStream
-      r.description += "\n\n#{await @radioInfo(item)}"
+      r.description += "\n#{await @radioInfo(item)}"
     r

   queue: (q, page=1)=>


Remove unnecessary unsubscribe from buffer in autocomplete

It no longer subscribes to the buffer, so unsubscribe isn't needed.

--- src/packages/autocomplete/src/autocomplete.coffee
+++ src/packages/autocomplete/src/autocomplete.coffee
@@ -31,7 +31,6 @@

   handleEvents: ->
     @editor.on 'editor-path-change', => @setCurrentBuffer(@editor.getBuffer())
-    @editor.on 'before-remove', => @currentBuffer?.off '.autocomplete'
     @editor.command 'autocomplete:attach', => @attach()

     @miniEditor.preempt 'textInput', (e) =>


Formatting

Formatting

--- routes/itemdata.coffee
+++ routes/itemdata.coffee
@@ -8,17 +8,17 @@
   newItem = new item.item database.getId(), req.body.name, req.body.status, req.body.type, req.body.link, req.body.description, req.body.date, req.body.technologies, req.body.images
   db.collection('collection').find({'_id':database.getId(req.body.collection)}).toArray (err, result) ->
     currentCollection = new item.collection result[0]._id, result[0].name, result[0].status, result[0].type, result[0].link, result[0].description, result[0].image, result[0].hasItems
-    newItem.setCollection(currentCollection)
-    db.collection('collection').update({'_id':database.getId(req.body.collection)}, currentCollection)
-    db.collection('item').insert(newItem)
-    res.redirect('back')
+    newItem.setCollection currentCollection
+    db.collection('collection').update {'_id':database.getId(req.body.collection)}, currentCollection
+    db.collection('item').insert newItem
+    res.redirect 'back'

   updateCollectionSet = ->
     db.collection('collection').find({'_id':database.getId(req.body.collection)}).toArray (err, result) ->
       currentCollection = new item.collection result[0]._id, result[0].name, result[0].status, result[0].type, result[0].link, result[0].description, result[0].image, result[0].hasItems
-      newItem.setCollection(currentCollection)
-      db.collection('item').insert(newItem)
-      db.collection('collection').update({'_id':database.getId(req.body.collection)}, currentCollection)
+      newItem.setCollection currentCollection
+      db.collection('item').insert newItem
+      db.collection('collection').update {'_id':database.getId(req.body.collection)}, currentCollection

 router.post '/getItem', (req, res, next) ->
   db = database.getDb()
@@ -30,7 +30,7 @@
   db.collection('item').find({'_id':database.getId(req.params.id)}).toArray (err, result) ->
     editedItem = new item.item database.getId(req.params.id), req.body.name, req.body.status, req.body.type, req.body.link, req.body.description, req.body.date, req.body.technologies, req.body.images
     db.collection('item').update {'_id':database.getId(req.params.id)}, editedItem, ->
-      res.redirect('back')
+      res.redirect 'back'

 router.post '/deleteItem', (req, res, next) ->
   db = database.getDb()
@@ -48,15 +48,15 @@
             res.redirect('back')
     else
       db.collection('item').remove {'_id':database.getId(req.body.id)}, ->
-        res.redirect('back')
+        res.redirect 'back'

 router.get '/', (req, res, next) ->
   database.getDb().collection('item').find({}).toArray (err, items) ->
     database.getDb().collection('collection').find({}).toArray (err, collections) ->
       res.render 'itemdata',
-        itemKeys: Object.keys(items)
+        itemKeys: Object.keys items
         items: items
-        collectionKeys: Object.keys(collections)
+        collectionKeys: Object.keys collections
         collections: collections

 module.exports = router


Fixed bugs in tags input related to undefined content (issue with Ember Data records)

--- packages/emberella/lib/views/tags_input.js.coffee
+++ packages/emberella/lib/views/tags_input.js.coffee
@@ -51,12 +51,10 @@

   init: ->
     ret = @_super()
-    value = get(@, 'value') ? ''
-    set(@, 'content', get(@, 'content') ? Ember.A())
+    value = get(@, 'value')
     set(@, '_value', value)
-    @capture value
-    @_setupContent()
-    @_renderList()
+    @capture value unless Ember.isEmpty(value)
+    @_contentDidChange() if Ember.isArray(get(@, 'content'))
     ret

   ###
@@ -450,6 +448,8 @@
     inputValue = get(@, 'inputView.value')
     value = inputValue unless typeOf(value) is 'string'

+    set(@, 'content', Ember.A()) unless Ember.isArray(get(@, 'content'))
+
     values = @tagify(value)
     len = get(@, 'content.length')

@@ -738,7 +738,7 @@
   refocus: (force, beginning) ->
     inputView = get(@, 'inputView')

-    return unless force or @isFocused()
+    return unless inputView? and (force or @isFocused())

     if get(inputView, 'state') is 'inDOM'
       @focus({}, beginning)
@@ -875,7 +875,8 @@
   ###
   didInsertElement: ->
     @_super()
-    set(@, 'cursor', get(@, 'content.length'))
+    set(@, '_cursor', get(@, 'content.length') || 0)
+    @_updateChildViews() if get(@, 'content') isnt undefined

   ###
     Respond to a click event on the view element. The tags input will try to
@@ -1046,7 +1047,7 @@
     @method _cursorDidChange
   ###
   _cursorDidChange: Ember.observer ->
-    if get(@, 'childViews.length') then @_updateCursorLocation() else @_updateChildViews()
+    @_updateCursorLocation() if get(@, 'childViews.length')
   , 'cursor'

   ###
@@ -1246,7 +1247,7 @@
     itemViewClass = @getItemViewClass()

     content = get(@, 'content')
-    contentLength = get(@, 'content.length')
+    contentLength = get(@, 'content.length') || 0

     for i in [0...Math.max(childViewsLength, contentLength)]
       childView = @objectAt(i)
@@ -1435,7 +1436,7 @@
   ###
   _contentWillChange: Ember.beforeObserver ->
     content = get(@, 'content')
-    len = if content then get(content, 'length') else 0
+    len = get(@, 'content.length') || 0

     @contentArrayWillChange @, 0, len, undefined
     @contentWillChange @


Better github site.

Better github site.

--- config/jknt-smblott.coffee
+++ config/jknt-smblott.coffee
@@ -111,7 +111,7 @@
     "border-color": "#55B4CF"

 configs.push
-  name: "Github Issues/Pulls"
+  name: "Github Issues/Pulls/Notifications"
   regexps: [
     "^https?://github.com/.*/(issues|pulls)($|\\?)"
     "^https?://github.com/notifications"
@@ -120,13 +120,35 @@
   selectors: [
     "li.js-navigation-item"
     "div.pagination a.next_page"
-    # "ul.table-list li.selectable"
-    # "ul.notifications li.issue-notification"
-    # "ul.notifications li.pull-request-notification"
-    # "ul.notifications li.notifications-more"
   ]
   activators: "a.issue-title-link"
-  offset: 80
+  offset: 30
+
+configs.push
+  name: "Github Discussions"
+  regexps: [
+    "^https?://github.com/.*/(issues?|pulls?)/[1-9]+$"
+  ]
+  selectors: [
+    "div.discussion-timeline div[id^='issue-']"
+    "div.discussion-timeline div[id^='issuecomment-']"
+    "div.discussion-timeline div[id^='commitcomment-']"
+    # Navigation bar.
+    "div.tabnav a.tabnav-tab:not(.selected):not(.preview-tab)"
+  ]
+  offset: 30
+
+configs.push
+  name: "Github Commits"
+  regexps: [
+    "^https?://github.com/.*/commits$"
+  ]
+  selectors: [
+    "div#commits_bucket li.js-navigation-item"
+    # Navigation bar.
+    "div.tabnav a.tabnav-tab:not(.selected):not(.preview-tab)"
+  ]
+  offset: 30

 configs.push
   name: "Google Plus"


Keep pointer status through items with no handlers

--- src/renderer/impl/base/level0/item/pointer.coffee
+++ src/renderer/impl/base/level0/item/pointer.coffee
@@ -128,8 +128,7 @@
                         itemsToMove.push item
                     if event._stopPropagation
                         return STOP_PROPAGATION
-                    return getEventStatus()
-                PROPAGATE_UP | STOP_ASIDE_PROPAGATION
+                getEventStatus()

             (e) ->
                 event._stopPropagation = false
@@ -155,8 +154,7 @@
                 if capturePointer & (RELEASE | CLICK)
                     if event._stopPropagation
                         return STOP_PROPAGATION
-                    return getEventStatus()
-                PROPAGATE_UP | STOP_ASIDE_PROPAGATION
+                getEventStatus()

             (e) ->
                 eventLoop.lock()
@@ -204,8 +202,7 @@
                 if capturePointer & (ENTER | EXIT | MOVE)
                     if event._stopPropagation
                         return STOP_PROPAGATION
-                    return getEventStatus()
-                PROPAGATE_UP | STOP_ASIDE_PROPAGATION
+                getEventStatus()

             (e) ->
                 eventLoop.lock()
@@ -247,8 +244,7 @@
                         emitSignal pointer, 'onWheel', event
                         if event._stopPropagation
                             return STOP_PROPAGATION
-                        return getEventStatus()
-                PROPAGATE_UP | STOP_ASIDE_PROPAGATION
+                getEventStatus()

             (e) ->
                 eventLoop.lock()


fix: harcoded title in share extension...

--- src/javascripts/extensions/share.coffee
+++ src/javascripts/extensions/share.coffee
@@ -35,7 +35,7 @@
   shareLinks: (currentTimeInSeconds) =>
     url = encodeURI(@shareUrl())
     fileUrl = @audioFileUrl()
-    title = encodeURIComponent("#001 | Hallo Küchenherde | Gastro Hacks für Gastronomen")
+    title = encodeURIComponent(@episode.title)
     coverUrl = encodeURI(@episode.coverUrl)

     shareLinks =


Preload events of next 3 months (was 2 previously)

--- server/controllers/index.coffee
+++ server/controllers/index.coffee
@@ -26,7 +26,7 @@
         # months and < +3 months). That way it doesn't load too much events.
         (cb) ->
             start = moment().startOf('month').subtract 3, 'months'
-            end = moment().startOf('month').add 3, 'months'
+            end = moment().endOf('month').add 3, 'months'
             Event.load start, end, (err, events) ->
                 Event.request 'reccuring', (err, reccuringEvents) ->
                     cb null, events.concat reccuringEvents


Admin: Defensive check for member listing.

--- client/admin/lib/views/members/memberitemview.coffee
+++ client/admin/lib/views/members/memberitemview.coffee
@@ -76,7 +76,8 @@
       @settings  = new kd.CustomHTMLView
         cssClass : 'settings hidden'

-    buttons = buttonSet[@loggedInUserRole.slug][@memberRole.slug]
+    set     = buttonSet[@loggedInUserRole.slug]
+    buttons = if set then (set[@memberRole.slug] ? []) else []

     buttons.forEach (button) =>


trim the value of fields which has a value for credential forms

--- client/app/lib/providers/computecontroller.ui.coffee
+++ client/app/lib/providers/computecontroller.ui.coffee
@@ -200,7 +200,9 @@
         delete data.title

         # Remove fields which has no value in it
+        # Trim value of fields which has value
         for field, value of data
+          value = value.trim()  if value
           delete data[field]  if value is ''

         if callback


[Server] client.coffee was throwing #patch

--- server/lib/server/client.coffee
+++ server/lib/server/client.coffee
@@ -14,7 +14,7 @@
   # and it means it is koding group
   # it is like Activity -- Develop

-  if name[0].toUpperCase() is name[0]
+  if not name or name[0].toUpperCase() is name[0]
     return callback null, "koding"
   else
     JName.fetchModels "#{name}/#{section}", (err, models)->


register form submit fail fix

register form submit fail fix

--- client/landing/app/MainApp/login/registerform.coffee
+++ client/landing/app/MainApp/login/registerform.coffee
@@ -162,11 +162,16 @@
             required  : yes
           messages    :
             required  : "Please enter your invitation code."
+
     @on "SubmitFailed", (msg)=>
       if msg is "Wrong password"
         @passwordConfirm.input.setValue ''
         @password.input.setValue ''
         @password.input.validate()
+
+      @button.hideLoader()
+      @invitationCode.notify msg
+

   usernameCheckTimer = null


quote: remove empty line

quote: remove empty line

--- test/option.quote.coffee
+++ test/option.quote.coffee
@@ -135,7 +135,6 @@
       """, quote: true, columns: true, (err, data) ->
         data.should.eql [ { a: '1', b: '2', c: '3' } ] unless err
         next err
-

   describe 'error "Quoted field not terminated"', ->


Add failing test for second theme filter behavior

--- client/test/src/views/indicator_selector_view.coffee
+++ client/test/src/views/indicator_selector_view.coffee
@@ -250,3 +250,46 @@
   assert.strictEqual spy.callCount, 0,
     "Expected the spy not to be called, as the parent view should have stopped listening"
 )
+
+test("Clicking theme filters works twice", ->
+  section = new Backbone.Models.Section(
+    _id: Factory.findNextFreeId('Section')
+  )
+
+  themes = [
+    Factory.theme(title: 'theme 1')
+    Factory.theme(title: 'theme 2')
+  ]
+  indicators = [
+    {theme: themes[0].get('_id'), title: 'indicator 1'}
+    {theme: themes[1].get('_id'), title: 'indicator 2'}
+  ]
+
+  populateCollectionStub = sinon.stub(
+    Backbone.Views.IndicatorSelectorView::, 'populateCollections', ->
+      defer = $.Deferred()
+
+      @themes.set(themes)
+      @indicators.set(indicators)
+      defer.resolve()
+
+      defer.promise()
+  )
+
+  view = new Backbone.Views.IndicatorSelectorView(
+    section: section
+  )
+
+  try
+    view.subViews["theme-filter-#{themes[0].cid}"].$el.trigger('click')
+    assert.strictEqual view.results.at(0).get('title'), indicators[0].title,
+      "Expected the first indicator to be the results"
+
+    view.subViews["theme-filter-#{themes[1].cid}"].$el.trigger('click')
+    assert.strictEqual view.results.at(0).get('title'), indicators[1].title,
+      "Expected the second indicator to be the results"
+
+  finally
+    view.close()
+    populateCollectionStub.restore()
+)


fix !!! smiley test

fix !!! smiley test

--- src/smc-util/test/misc-test.coffee
+++ src/smc-util/test/misc-test.coffee
@@ -1152,7 +1152,7 @@

 describe "smileys", ->
     it "replaces strings", ->
-        misc.smiley(s : "hey :-) you !!!").should.be.eql "hey 😁 you ⚠"
+        misc.smiley(s : "hey :-) you !!! :-)").should.be.eql "hey 😁 you !!! 😁"
     it "wraps for html", ->
         res = misc.smiley
             s : "foo :-) bar"


Fixed Camera Bug

Fixed Camera Bug

--- js/camera.coffee
+++ js/camera.coffee
@@ -30,10 +30,10 @@
     render: (context, width, height) ->
       context.clearRect 0, 0, width, height
       context.translate width/2, height/2
-      context.translate @offset.x, @offset.y
       context.rotate @rotation
       context.scale @scale, @scale
       context.translate -width/2, -height/2
+      context.translate @offset.x, @offset.y

     reset: (context) ->
       context.setTransform 1, 0, 0, 1, 0, 0


add useScroller function to setup scrolling where needed.

--- js/flight.coffee
+++ js/flight.coffee
@@ -36,7 +36,10 @@
       @startPanel = document.querySelector startPanel
       if @startPanel is undefined then throw new Error "Cannot find start panel"
     else
-      @startPanel = startPanel
+      @startPanel = startPanel
+
+    if @useScroller is true
+      @setScroller(@startPanel)

   # Goes to page, transitionAnimation defines if transition happens or not
   goToPage: (targetPanel, options) =>
@@ -126,15 +129,10 @@
     @back = false
     @isTransitioning = false
     @currentPanel.removeEventListener "webkitTransitionEnd", @finishTransition, false
-
+
     if @useScroller is true
-
-      if @iScrollInstance? then @iScrollInstance.destroy(); @iScrollInstance = null
-
-      window.setTimeout =>
-        @iScrollInstance = new iScroll(@targetPanel.getElementsByClassName('wrapper')[0].id)
-      , 0
-
+      @setScroller(@targetPanel)
+
    # displays pages when transiton is false
    displayPage: =>
     @targetPanel.style.display = "block"
@@ -154,7 +152,14 @@
       flightViewport.style.height = content.offsetHeight + "px"
     else
       throw new Error "#flight or .content not found."
-
+
+  setScroller: (wrapper) =>
+
+      if @iScrollInstance? then @iScrollInstance.destroy(); @iScrollInstance = null
+
+      window.setTimeout =>
+        @iScrollInstance = new iScroll(wrapper.getElementsByClassName('wrapper')[0].id)
+      , 0
   # detects user agent being used
   detectUserAgent: ->
     userAgent = window.navigator.userAgent


make value an array

make value an array

--- app/assets/javascripts/components/subject-viewer.cjsx
+++ app/assets/javascripts/components/subject-viewer.cjsx
@@ -245,7 +245,7 @@
     annotation =
       task:               "dummy_task_name" # fix -STI
       generates_subjects: true
-      value:              mark
+      value:              [mark]
       subject_id:  @props.subject.id
       workflow_id: @props.workflow.id


OX-723 Expect 16 bit texture

OX-723 Expect 16 bit texture

--- app/assets/javascripts/oxalis/geometries/plane.coffee
+++ app/assets/javascripts/oxalis/geometries/plane.coffee
@@ -85,7 +85,7 @@

       void main() {
         vec4 volumeColor = texture2D(volumeTexture, vUv * repeat + offset);
-        float id = (volumeColor[0] * 255.0);
+        float id = (volumeColor[0] * 65535.0);
         float golden_ratio = 0.618033988749895;

         /* Color map (<= to fight rounding mistakes) */


replace `$.now` with native Date api

replace `$.now` with native Date api

--- app/assets/javascripts/uploadcare/files/object.coffee
+++ app/assets/javascripts/uploadcare/files/object.coffee
@@ -167,13 +167,13 @@

     uploadParts: (parts, uuid) ->
       progress = []
-      lastUpdate = $.now()
+      lastUpdate = Date.now()
       updateProgress = (i, loaded) =>
         progress[i] = loaded

-        if $.now() - lastUpdate < 250
+        if Date.now() - lastUpdate < 250
           return
-        lastUpdate = $.now()
+        lastUpdate = Date.now()

         total = 0
         for loaded in progress


Added missing Pt support to camera

Added missing Pt support to camera

--- app/assets/javascripts/uploadcare/locale/pt.js.coffee
+++ app/assets/javascripts/uploadcare/locale/pt.js.coffee
@@ -54,6 +54,19 @@
           line2: 'Apenas informe o link.'
           input: 'Cole seu link aqui...'
           button: 'Upload'
+        camera:
+          capture: 'Tirar uma foto'
+          mirror: 'Espelhar'
+          startRecord: 'Gravar um vídeo'
+          stopRecord: 'Parar'
+          cancelRecord: 'Cancelar'
+          retry: 'Requisitar permissão novamente'
+          pleaseAllow:
+              title: 'Por favor permita o acesso a sua câmera',
+              text: 'Você foi solicitado a permitir o acesso à câmera a partir deste site. ' + 'Para tirar fotos com sua câmera, você deve aprovar este pedido.'
+          notFoud:
+              title: 'Câmera não detectada'
+              text: 'Parece que você não tem uma câmera conectada a este dispositivo'
         preview:
           unknownName: 'desconhecido'
           change: 'Cancelar'


Make text task available to sub-task

Make text task available to sub-task

--- app/classifier/tasks/drawing-task-details-editor.cjsx
+++ app/classifier/tasks/drawing-task-details-editor.cjsx
@@ -65,14 +65,12 @@

                 Question
               </button>{' '}
-              {
-                if @canUseTask("text")
-                  <button type="submit" className="minor-button" onClick={@handleAddTask.bind this, 'text'} title="Text tasks: the volunteer writes free-form text into a dialog box.">
-
-

-                    Text
-                  </button>
-              }
+
+              <button type="submit" className="minor-button" onClick={@handleAddTask.bind this, 'text'} title="Text tasks: the volunteer writes free-form text into a dialog box.">
+
+

+                Text
+              </button>
           </TriggeredModalForm>


Guest Cleaner Worker : fixed deletion period limit

--- config/main.vagrant.coffee
+++ config/main.vagrant.coffee
@@ -78,7 +78,7 @@
     numberOfWorkers      : 2
     watch                : yes
     cronSchedule         : '* * * * * *'
-    usageLimitInMinutes  : 1
+    usageLimitInMinutes  : 60
   social        :
     login       : 'prod-social'
     numberOfWorkers: 1


server: fetch userEmail and groupMembersEmail to prepare result

--- servers/lib/server/handlers/invitetoteambycsv.coffee
+++ servers/lib/server/handlers/invitetoteambycsv.coffee
@@ -48,5 +48,49 @@
     parser content.toString('utf8'), csvParseOpts, (err, data) ->
       return callback err, null if err

-      { JInvitation } = (require './../bongo').models
-      JInvitation.create client, { invitations: data }, callback
+      { connection: { delegate: account } } = client
+      { _id } = account
+      myEmail = null
+      account.fetchEmail (err, email) ->
+
+        myEmail = email
+
+        { JGroup } = (require './../bongo').models
+        { group: slug } = client.context
+        JGroup.one { slug }, (err, group) ->
+          return callback err, null  if err
+
+          group.fetchMembersWithEmail client, {}, (err, users) ->
+            return callback err, null  if err
+
+            adminEmails = []
+            alreadyMemberEmails = []
+            userEmails = []
+            myself = no
+
+            users.map (user) ->
+              { profile: { email } } = user
+              userEmails.push email
+
+            for key in data
+              if myEmail? and key.email is myEmail
+                myself = yes
+                continue
+
+              if key.email in userEmails
+                alreadyMemberEmails.push key.email
+                continue
+
+              if key.role? and key.role is 'admin'
+                adminEmails.push key.email
+                continue
+
+            result =
+              myself: myself
+              alreadyMembers: alreadyMemberEmails
+              admins : adminEmails
+
+            { JInvitation } = (require './../bongo').models
+            JInvitation.create client, { invitations: data }, (err) ->
+              return callback err, null  if err
+              callback null, result


ceil not round

ceil not round

--- services/track-changes/app/coffee/PackManager.coffee
+++ services/track-changes/app/coffee/PackManager.coffee
@@ -534,5 +534,5 @@

 	_getOneDayInFutureWithRandomDelay: ->
 		thirtyMins = 1000 * 60 * 30
-		randomThirtyMinMax = Math.round(Math.random() * thirtyMins)
+		randomThirtyMinMax = Math.ceil(Math.random() * thirtyMins)
 		return new Date(Date.now() + randomThirtyMinMax + 1*DAYS)


require objects in storage test

require objects in storage test

--- test/storage_test.coffee
+++ test/storage_test.coffee
@@ -1,11 +1,10 @@
 Storage     = require '../lib/argumenta/storage'
 User        = require '../lib/argumenta/user'
-Argument    = require '../lib/argumenta/objects/argument'
-Proposition = require '../lib/argumenta/objects/proposition'
-Commit      = require '../lib/argumenta/objects/commit'
-Tag         = require '../lib/argumenta/objects/tag'
+Objects     = require '../lib/argumenta/objects'
 fixtures    = require '../test/fixtures'
 should      = require 'should'
+
+{Argument, Proposition, Commit, Tag} = Objects

 getStorage = (type) ->
   switch type


Increase timeout in ResizeCanvas tests

Increase timeout in ResizeCanvas tests

Hopefully makes them pass on Travis CI

--- spec/ResizeCanvas.coffee
+++ spec/ResizeCanvas.coffee
@@ -41,6 +41,7 @@

   describe 'specifying height+width', ->
     it 'should resize to specified size', (done) ->
+      @timeout 5000
       input = testutils.createCanvas 400, 300
       out.once "data", (canvas) ->
         chai.expect(canvas).to.be.an 'object'
@@ -53,6 +54,7 @@

   describe.skip 'specifying only height', ->
     it 'should calculate width', (done) ->
+      @timeout 5000
       input = testutils.createCanvas 400, 300
       out.once "data", (canvas) ->
         chai.expect(canvas).to.be.an 'object'
@@ -65,6 +67,7 @@

   describe.skip 'specifying only width', ->
     it 'should calculate height', (done) ->
+      @timeout 5000
       input = testutils.createCanvas 400, 300
       out.once "data", (canvas) ->
         chai.expect(canvas).to.be.an 'object'


Add default options for highcharts

Add default options for highcharts

--- js/script.coffee
+++ js/script.coffee
@@ -1,3 +1,50 @@
+# Radialize the colors
+Highcharts.setOptions
+  colors: [
+    '#96000F'
+    '#E10019'
+    '#AAA5A0'
+    '#46413C'
+    '#327D91'
+    '#4BBEE1'
+    '#560F32'
+    '#821350'
+    '#006450'
+    '#009682'
+    '#697D19'
+    '#9BC328'
+    '#AA5500'
+    '#FF8200'
+  ]
+  credits:
+    enabled: true
+  legend:
+    enabled: false
+  tooltip:
+    enabled: false
+  title:
+    text: ''
+  chart:
+    backgroundColor: 'rgba(0,0,0,0)'
+    plotBackgroundColor: null
+    plotBorderWidth: null
+    plotShadow: false
+    margin: [0, 0, 0, 0]
+    style:
+      fontFamily: 'Open Sans Light'
+      fontSize: '20px'
+      color: 'black'
+
+Highcharts.getOptions().colors = Highcharts.map Highcharts.getOptions().colors, (color) ->
+  radialGradient:
+    cx: 0.5
+    cy: 0.3
+    r: 0.7
+  stops: [
+    [0, color]
+    [1, Highcharts.Color(color).brighten(-0.3).get('rgb')] # darken
+  ]
+
 $.fn.extend
   typewriter: ->
     this.each ->


Use heartbeat URL from settings and suffix a slash.

--- community/browser/app/scripts/services/Server.coffee
+++ community/browser/app/scripts/services/Server.coffee
@@ -123,7 +123,7 @@
         status: (params = '')->
           # User a smaller timeout for status requests so IE10 detects when the
           # server goes down faster.
-          @options '/db/data', { timeout: (Settings.heartbeat * 1000)}
+          @options "#{Settings.endpoint.rest}/", { timeout: (Settings.heartbeat * 1000)}

         log: (path) ->
           @get(path).then((r)-> console.log (r))


binded bold + italic buttons

binded bold + italic buttons

--- js/taylor.coffee
+++ js/taylor.coffee
@@ -550,7 +550,7 @@
   # bind events to buttons
   bindButton @_bold, 'bold'
   bindButton @_italic, 'italic'
-  bindButton @_header, 'header1'
+  bindButton @_header, 'h1'

   return @


Add logs to lib/git

Add logs to lib/git

--- lib/git.coffee
+++ lib/git.coffee
@@ -76,6 +76,7 @@

 tag = (repo, oid) ->
   new Promise (resolve, reject) ->
+    console.log "tag #{oid}"
     repo.createLightweightTag oid, "#{oid}-tag"
     .then (reference) ->
       resolve reference
@@ -84,11 +85,12 @@

 push = (repo, src, dst) ->
   new Promise (resolve, reject) ->
+    refSpec = "#{src}:refs/heads/#{dst}"
     repo.getRemote 'origin'
     .then (remote) ->
-      console.log "push #{src}:#{dst}"
+      console.log "push origin #{refSpec}"
       pushOpts = callbacks: credentials: auth
-      remote.push ["#{src}:refs/heads/#{dst}"], pushOpts
+      remote.push ["#{refSpec}"], pushOpts
     .then () ->
       resolve()
     .catch (err) ->


Removed unnecessary escape

Removed unnecessary escape

--- core/app/backbone/views/react_feed_activities.coffee
+++ core/app/backbone/views/react_feed_activities.coffee
@@ -33,7 +33,7 @@
   render: ->
     _div [],
       if @model().length == 0 && !@model().loading()
-        "There aren\'t any comments."
+        "There aren't any comments."
       @model().map (model) =>
         ReactActivity model: model, key: model.id
       ReactLoadingIndicator model: @model()


fix bug with opinions-only mode

fix bug with opinions-only mode

--- @client/permissions.coffee
+++ @client/permissions.coffee
@@ -86,7 +86,7 @@
       if phase == 'opinions-only'
         can_add_to_list = false

-      if !current_user.is_admin && !matchEmail(subdomain.roles.proposer) && !can_add_to_list
+      if !current_user.is_admin && (!matchEmail(subdomain.roles.proposer) || !can_add_to_list)
         return Permission.INSUFFICIENT_PRIVILEGES
       return Permission.NOT_LOGGED_IN if !current_user.logged_in


Better tests

Better tests

--- tests.coffee
+++ tests.coffee
@@ -146,30 +146,30 @@
   test.isTrue _.isFunction node.update

 __relationCRC__ = (test, r, from, to, type, props = {}) ->
-    test.instanceOf r, Neo4jRelationship
-    test.isTrue _.isFunction r.get
-    test.isTrue _.isFunction r.delete
-    test.isTrue _.isFunction r.update
-    test.isTrue _.isFunction r.__refresh
-
-    _r = r.get()
-    test.isTrue _.has _r, 'id'
-    test.isTrue _.has _r, 'metadata'
-    test.isTrue _.has _r, 'type'
-    test.isTrue _.has _r, 'start'
-    test.isTrue _.has _r, 'end'
-
-    test.isTrue _r.type is type
-
-    if props
-      for key, value of props
-        test.isTrue _.has _r, key
-        test.equal _r[key], value
-
-    test.equal _r.start, from if from
-    test.equal _r.end, to if to
-
-Tinytest.add 'service endpoints', (test) ->
+  test.instanceOf r, Neo4jRelationship
+  test.isTrue _.isFunction r.get
+  test.isTrue _.isFunction r.delete
+  test.isTrue _.isFunction r.update
+  test.isTrue _.isFunction r.__refresh
+
+  _r = r.get()
+  test.isTrue _.has _r, 'id'
+  test.isTrue _.has _r, 'metadata'
+  test.isTrue _.has _r, 'type'
+  test.isTrue _.has _r, 'start'
+  test.isTrue _.has _r, 'end'
+
+  test.isTrue _r.type is type if type
+
+  if props
+    for key, value of props
+      test.isTrue _.has _r, key
+      test.equal _r[key], value
+
+  test.equal _r.start, from if from
+  test.equal _r.end, to if to
+
+Tinytest.add 'Neo4jDB - service endpoints - [BASICS]', (test) ->
   test.isTrue _.isArray db.propertyKeys()
   test.isTrue _.isArray db.labels()
   test.isTrue _.isArray db.relationshipTypes()
@@ -180,28 +180,28 @@
 @description basics
 query: (cypher, opts = {}) ->
 ###
-Tinytest.add 'db.query [BASICS]', (test) -> __BasicsTest__ test, 'query'
+Tinytest.add 'Neo4jDB - db.query - [BASICS]', (test) -> __BasicsTest__ test, 'query'

 ###
 @test
 @description basics
 cypher: (cypher, opts = {}) ->
 ###
-Tinytest.add 'db.cypher [BASICS]', (test) -> __BasicsTest__ test, 'cypher'
+Tinytest.add 'Neo4jDB - db.cypher - [BASICS]', (test) -> __BasicsTest__ test, 'cypher'

 ###
 @test
 @description Test standard query, Synchronous, with replacements
 query: (cypher, opts = {}) ->
 ###
-Tinytest.add 'db.query [SYNC]', (test) -> __SyncTest__ test, 'query'
+Tinytest.add 'Neo4jDB - db.query - [SYNC]', (test) -> __SyncTest__ test, 'query'

 ###
 @test
 @description Passing wrong Cypher query, returns empty cursor, and prints an error to console
 query: (cypher, callback) ->
 ###
-Tinytest.add 'db.query [Wrong cypher] [SYNC] (You will see errors at server console)', (test) ->
+Tinytest.add 'Neo4jDB - db.query - [Wrong cypher] [SYNC] (You will see errors at server console)', (test) ->
   test.equal db.query("MATCh (n:) RETRN n").fetch(), []

@@ -210,7 +210,7 @@
 @description Passing wrong Cypher query, returns error and prints an error to console
 query: (cypher, callback) ->
 ###
-Tinytest.addAsync 'db.query [Wrong cypher] [ASYNC] (You will see errors at server console)', (test, completed) ->
+Tinytest.addAsync 'Neo4jDB - db.query - [Wrong cypher] [ASYNC] (You will see errors at server console)', (test, completed) ->
   db.query "MATCh (n:) RETRN n", (error, data) ->
     test.isTrue _.isString error
     test.isTrue _.isEmpty data.fetch()
@@ -221,7 +221,7 @@
 @description Test standard async query
 query: (cypher, opts = {}, callback) ->
 ###
-Tinytest.add 'db.query [ASYNC]', (test) ->
+Tinytest.add 'Neo4jDB - db.query - [ASYNC]', (test) ->
   fut = new Future()
   db.query "CREATE (n:QueryTestAsync {data}) RETURN n", data: foo: 'bar', (error, cursor) -> fut.return cursor
   cursor = fut.wait()
@@ -255,28 +255,28 @@
 @description Test query basics of async
 query: (cypher, opts, callback) ->
 ###
-Tinytest.addAsync 'db.query [ASYNC] [BASICS]', (test, completed) -> __AsyncBasicsTest__ test, completed, 'query'
+Tinytest.addAsync 'Neo4jDB - db.query - [ASYNC] [BASICS]', (test, completed) -> __AsyncBasicsTest__ test, completed, 'query'

 ###
 @test
 @description Test cypher basics of async
 cypher: (cypher, opts, callback) ->
 ###
-Tinytest.addAsync 'db.cypher [ASYNC] [BASICS]', (test, completed) -> __AsyncBasicsTest__ test, completed, 'cypher'
+Tinytest.addAsync 'Neo4jDB - db.cypher - [ASYNC] [BASICS]', (test, completed) -> __AsyncBasicsTest__ test, completed, 'cypher'

 ###
 @test
 @description Test queryAsync
 queryAsync: (cypher, opts, callback) ->
 ###
-Tinytest.addAsync 'db.queryAsync [with callback]', (test, completed) -> __AsyncBasicsTest__ test, completed, 'queryAsync'
+Tinytest.addAsync 'Neo4jDB - db.queryAsync - [with callback]', (test, completed) -> __AsyncBasicsTest__ test, completed, 'queryAsync'

 ###
 @test
 @description Test queryOne
 queryOne: (cypher, opts) ->
 ###
-Tinytest.add 'db.queryOne', (test) ->
+Tinytest.add 'Neo4jDB - db.queryOne - [BASICS]', (test) ->
   test.isTrue _.isFunction(db.queryOne), "[queryOne] Exists on DB object"
   node = db.queryOne "CREATE (n:QueryOneTest {data}) RETURN n", data: test: true
   test.isTrue _.has node, 'n'
@@ -289,7 +289,7 @@
 @description Test queryOne non existent node, should return undefined
 queryOne: (cypher) ->
 ###
-Tinytest.add 'db.queryOne [ForSureNonExists]', (test) ->
+Tinytest.add 'Neo4jDB - db.queryOne - [ForSureNonExists]', (test) ->
   test.equal db.queryOne("MATCH (n:ForSureNonExists) RETURN n"), undefined

@@ -298,7 +298,7 @@
 @description Test queryAsync
 queryAsync: (cypher, opts, callback) ->
 ###
-Tinytest.addAsync 'db.queryAsync [no callback]', (test, completed) ->
+Tinytest.addAsync 'Neo4jDB - db.queryAsync - [no callback]', (test, completed) ->
   test.isTrue _.isFunction(db.queryAsync), "[queryAsync] Exists on DB object"
   db.queryAsync "CREATE (n:QueryAsyncNoCBTest {data}) RETURN n", {data: queryAsyncNoCB: 'queryAsyncNoCB'}

@@ -330,35 +330,35 @@
 @description Test querySync
 querySync: (cypher, opts) ->
 ###
-Tinytest.add 'db.querySync', (test) -> __SyncTest__ test, 'querySync'
+Tinytest.add 'Neo4jDB - db.querySync - [BASICS]', (test) -> __SyncTest__ test, 'querySync'

 ###
 @test
 @description Test querySync
 query: (settings.reactive: true, opts = {}) ->
 ###
-Tinytest.add 'db.query [SYNC] [REACTIVE NODES]', (test) -> __SyncReactiveTest__ test, 'query'
+Tinytest.add 'Neo4jDB - db.query - [SYNC] [REACTIVE]', (test) -> __SyncReactiveTest__ test, 'query'

 ###
 @test
 @description Test cypher
 cypher: (settings, opts = {}) ->
 ###
-Tinytest.add 'db.cypher [SYNC]', (test) -> __SyncTest__ test, 'cypher'
+Tinytest.add 'Neo4jDB - db.cypher - [SYNC]', (test) -> __SyncTest__ test, 'cypher'

 ###
 @test
 @description Test cypher reactive nodes
 cypher: (settings.reactive: true, opts = {}) ->
 ###
-Tinytest.add 'db.cypher [SYNC] [REACTIVE NODES]', (test) -> __SyncReactiveTest__ test, 'cypher'
+Tinytest.add 'Neo4jDB - db.cypher - [SYNC] [REACTIVE]', (test) -> __SyncReactiveTest__ test, 'cypher'

 ###
 @test
 @description Check `.transaction` method returns Neo4jTransaction instance, and it has all required methods
 db.transaction()
 ###
-Tinytest.add 'db.transaction [BASICS / open / rollback]', (test) ->
+Tinytest.add 'Neo4jDB - Neo4jTransaction - initiate (open) [BASICS]', (test) ->
   test.isTrue _.isFunction(db.transaction), "[transaction] exists on db object"
   t = db.transaction()
   test.instanceOf t, Neo4jTransaction
@@ -370,7 +370,7 @@
   test.isTrue _.isFunction t.rollback
   t.rollback()

-Tinytest.add 'db.transaction [resetTimeout] (waits for 1 sec to see difference)', (test) ->
+Tinytest.add 'Neo4jTransaction - [resetTimeout] (waits for 1 sec to see difference)', (test) ->
   t = db.transaction()
   ea = t._expiresAt
   fut = new Future()
@@ -390,7 +390,7 @@
 @description Check Neo4jTransaction `.current()` and  `.rollback()` methods
 db.transaction().current().rollback()
 ###
-Tinytest.add 'db.transaction [current / rollback]', (test) ->
+Tinytest.add 'Neo4jTransaction - [current / rollback]', (test) ->
   t = db.transaction "CREATE (n:TransactionsTesting {data})", data: transaction: true
   current = t.current()
   test.isTrue _.isFunction current[0].fetch
@@ -403,7 +403,7 @@
 @description Check Neo4jTransaction `.execute()` and  `.rollback()` methods
 db.transaction().execute().rollback()
 ###
-Tinytest.add 'db.transaction [execute / rollback]', (test) ->
+Tinytest.add 'Neo4jTransaction - [execute / rollback]', (test) ->
   t = db.transaction "CREATE (n:TransactionsTesting {data}) RETURN n", data: transaction: true
   current = t.current()
   node = current[0].fetch()[0]
@@ -423,7 +423,7 @@
 @description Check Neo4jTransaction `.execute()` and  `.commit()` methods
 db.transaction().execute().commit()
 ###
-Tinytest.add 'db.transaction [execute / commit]', (test) ->
+Tinytest.add 'Neo4jTransaction - [execute / commit]', (test) ->
   t = db.transaction "CREATE (n:TransactionsTesting {data}) RETURN n", data: transaction: true
   current = t.current()
   node = current[0].fetch()[0]
@@ -447,7 +447,7 @@
 @description Check Neo4jTransaction `.execute()`, `.current()` and  `.rollback()` methods
 db.transaction().execute(['query', 'query']).current().rollback()
 ###
-Tinytest.add 'db.transaction [execute multiple / current / rollback]', (test) ->
+Tinytest.add 'Neo4jTransaction - [execute multiple / current / rollback]', (test) ->
   t = db.transaction()

   t.execute ["CREATE (n:TransactionsTesting {data1}) RETURN n", "CREATE (n:TransactionsTesting2 {data2}) RETURN n"]
@@ -471,7 +471,7 @@
 @description Check Neo4jTransaction `.execute()` and  `.commit()` methods
 db.transaction().execute(['query', 'query']).commit()
 ###
-Tinytest.add 'db.transaction [execute multiple / commit]', (test) ->
+Tinytest.add 'Neo4jTransaction - [execute multiple / commit]', (test) ->
   db.transaction().execute(
     ["CREATE (n:TransactionsTesting {data1})", "CREATE (n:TransactionsTesting2 {data2})"]
   ,
@@ -495,7 +495,7 @@
 @description Check Neo4jTransaction `.last()` method
 db.transaction().execute(['query', 'query']).last().rollback()
 ###
-Tinytest.add 'db.transaction [last]', (test) ->
+Tinytest.add 'Neo4jTransaction - [last]', (test) ->
   t = db.transaction().execute(
     ["CREATE (n:TransactionsTesting {data1})", "CREATE (n:TransactionsTesting2 {data2}) RETURN n"]
   ,
@@ -511,7 +511,7 @@
 @description Check Neo4jTransaction `.execute()` and  `.commit()` methods
 db.transaction().execute().commit(cb:function())
 ###
-Tinytest.addAsync 'db.transaction [commit] [ASYNC]', (test, completed) ->
+Tinytest.addAsync 'Neo4jTransaction - [commit] [ASYNC]', (test, completed) ->
   db.transaction().commit
     query: "CREATE (n:TransactionsCommitAsync {foo: {data}}) RETURN n"
     params: data: 'bar'
@@ -527,7 +527,7 @@
 @description Check Neo4jTransaction `.execute()` and  `.commit()` methods
 db.transaction().execute().commit(function)
 ###
-Tinytest.addAsync 'db.transaction [commit] [ASYNC] 2', (test, completed) ->
+Tinytest.addAsync 'Neo4jTransaction - [commit] [ASYNC] 2', (test, completed) ->
   db.transaction("CREATE (n:TransactionsCommitAsync2 {foo: {data}}) RETURN n", {data: 'bar'}).commit (err, res)->
     bound ->
       node = res[0].fetch()[0]
@@ -540,7 +540,7 @@
 @description Check Neo4jTransaction `.commit()` method within reactive nodes
 db.transaction()().commit()
 ###
-Tinytest.addAsync 'db.transaction [commit] [ASYNC] [REACTIVE NODES]', (test, completed) ->
+Tinytest.addAsync 'Neo4jTransaction - [commit] [ASYNC] [REACTIVE]', (test, completed) ->
   db.transaction().commit
     query: "CREATE (n:TransactionsCommitReactiveAsync {foo: {data}}) RETURN n"
     params: data: 'TCRA'
@@ -563,7 +563,7 @@
 @description Check Neo4jTransaction check empty transaction
 db.transaction().rollback()
 ###
-Tinytest.add 'db.transaction [rollback] [EMPTY]', (test) ->
+Tinytest.add 'Neo4jTransaction - [rollback] [EMPTY]', (test) ->
   test.equal db.transaction().rollback(), undefined

 ###
@@ -571,7 +571,7 @@
 @description Check Neo4jTransaction check empty transaction
 db.transaction().commit()
 ###
-Tinytest.add 'db.transaction [commit] [EMPTY]', (test) ->
+Tinytest.add 'Neo4jTransaction - [commit] [EMPTY]', (test) ->
   test.equal db.transaction().commit(), []

 ###
@@ -579,7 +579,7 @@
 @description Check next tick batch
 db.queryAsync(query)
 ###
-Tinytest.addAsync 'Sending multiple async queries inside one Batch on next tick', (test, completed) ->
+Tinytest.addAsync 'Neo4jDB - core - Sending multiple async queries inside one Batch on next tick', (test, completed) ->
   conf = [
     'a'
     'b'
@@ -611,7 +611,7 @@
 @description Check graph
 db.graph()
 ###
-Tinytest.addAsync 'db.graph', (test, completed) ->
+Tinytest.addAsync 'Neo4jDB - db.graph - [BASICS]', (test, completed) ->
   db.querySync "CREATE (a:FirstTest)-[r:KNOWS]->(b:SecondTest), (a:FirstTest)-[r2:WorkWith]->(c:ThirdTest), (c:ThirdTest)-[r3:KNOWS]->(b:SecondTest)"
   graph = db.graph "MATCH ()-[r]-() RETURN r"
   test.instanceOf graph, Neo4jCursor
@@ -634,7 +634,7 @@
 @description Check batch
 db.batch(tasks)
 ###
-Tinytest.add 'db.batch [With custom ID]', (test) ->
+Tinytest.add 'Neo4jDB - db.batch - [With custom ID]', (test) ->
   batch = db.batch [
       method: "POST"
       to: db.__service.cypher.endpoint
@@ -664,7 +664,7 @@
 @description Check batch ASYNC
 db.batch(tasks, callback)
 ###
-Tinytest.addAsync 'db.batch [With custom ID] [ASYNC]', (test, completed) ->
+Tinytest.addAsync 'Neo4jDB - db.batch - [With custom ID] [ASYNC]', (test, completed) ->
   db.batch [
       method: "POST"
       to: db.__service.cypher.endpoint
@@ -698,7 +698,7 @@
 @description Check batch ASYNC
 db.batch(tasks, {plain: true}, false, true)
 ###
-Tinytest.add 'db.batch [With custom ID] [no data transform (plain)]', (test) ->
+Tinytest.add 'Neo4jDB - db.batch - [With custom ID] [no data transform (plain)]', (test) ->
   batch = db.batch [
       method: "POST"
       to: db.__service.cypher.endpoint
@@ -730,7 +730,7 @@
 @description Check batch ASYNC REACTIVE
 db.batch(tasks, {reactive: true}, true)
 ###
-Tinytest.add 'db.batch [With custom ID] [REACTIVE]', (test) ->
+Tinytest.add 'Neo4jDB - db.batch - [With custom ID] [REACTIVE]', (test) ->
   batch = db.batch [
       method: "POST"
       to: db.__service.cypher.endpoint
@@ -767,7 +767,7 @@
 @description Check nodes creation / deletion
 db.nodes(props)
 ###
-Tinytest.add 'db.nodes create / delete', (test) ->
+Tinytest.add 'Neo4jNode - [create / delete]', (test) ->
   node = db.nodes()
   _id = node.get().id

@@ -787,7 +787,7 @@
 @description Check nodes creation / deletion
 db.nodes(props)
 ###
-Tinytest.add 'db.nodes create / delete (2nd way)', (test) ->
+Tinytest.add 'Neo4jNode - [create / delete] (2nd way)', (test) ->
   node = db.nodes({testNodes: true})
   _id = node.get().id

@@ -807,7 +807,7 @@
 @description Check nodes creation / setProperty / deletion
 db.nodes(props).setProperty(name, val)
 ###
-Tinytest.add 'db.nodes create / setProperty / delete', (test) ->
+Tinytest.add 'Neo4jNode - setProperty()', (test) ->
   node = db.nodes({testNodes: true})
   _id = node.get().id

@@ -835,7 +835,7 @@
 @description Check nodes creation / setProperty / deletion
 db.nodes(props).setProperty({name: val})
 ###
-Tinytest.add 'db.nodes create / setProperty (from obj) / delete', (test) ->
+Tinytest.add 'Neo4jNode - setProperty({Object})', (test) ->
   node = db.nodes({testNodes2: 'true'})
   _id = node.get().id

@@ -863,7 +863,7 @@
 @description Check nodes creation / setProperty / deletion
 db.nodes(props).updateProperties({name: val, name2: val2})
 ###
-Tinytest.add 'db.nodes create / updateProperties / delete', (test) ->
+Tinytest.add 'Neo4jNode - updateProperties({Object}) [Override]', (test) ->
   node = db.nodes({testNodes3: 'updateProperties', testNodes4: 'updateProperties2'})
   _id = node.get().id

@@ -892,7 +892,7 @@
 Expect to delete or override old props, and create new
 db.nodes(props).updateProperties({name: val, name2: val2})
 ###
-Tinytest.add 'db.nodes create / updateProperties (not previously defined) / delete', (test) ->
+Tinytest.add 'Neo4jNode - updateProperties({Object}) [Override and add new]', (test) ->
   node = db.nodes({testNodes3: 'updateProperties', testNodes4: 'updateProperties2'})
   _id = node.get().id

@@ -922,7 +922,7 @@
 @description Check nodes creation / setProperties / deletion
 db.nodes(props).setProperties({name: val, name2: val2})
 ###
-Tinytest.add 'db.nodes create / setProperties / delete', (test) ->
+Tinytest.add 'Neo4jNode - setProperties({Object})', (test) ->
   node = db.nodes({one: 1})
   _id = node.get().id

@@ -952,7 +952,7 @@
 @description Check nodes creation / property / deletion
 db.nodes(props).property(name)
 ###
-Tinytest.add 'db.nodes create / property [GET] / delete', (test) ->
+Tinytest.add 'Neo4jNode - property(name) [GET]', (test) ->
   node = db.nodes({one: 1, two: 2})
   test.equal node.property('two'), 2
   test.equal node.delete(), undefined
@@ -963,7 +963,7 @@
 @description Check nodes creation / property / deletion
 db.nodes(props).property(name, value).property(name)
 ###
-Tinytest.add 'db.nodes create / property [SET] / delete', (test) ->
+Tinytest.add 'Neo4jNode - property(name, value) [SET]', (test) ->
   node = db.nodes({one: 1, two: 2})
   __nodesInstanceCRC__ test, node

@@ -980,7 +980,7 @@
 @description Check nodes creation / property / deletion
 db.nodes(props).property(name, value).property(name)
 ###
-Tinytest.add 'db.nodes create / property [UPDATE] / delete', (test) ->
+Tinytest.add 'Neo4jNode - property(name, value) [UPDATE]', (test) ->
   node = db.nodes({one: 1, two: 2})
   __nodesInstanceCRC__ test, node

@@ -997,7 +997,7 @@
 @description Check nodes creation / getProperty / deletion
 db.nodes(props).getProperty(name)
 ###
-Tinytest.add 'db.nodes create / getProperty / delete', (test) ->
+Tinytest.add 'Neo4jNode - getProperty(name)', (test) ->
   node = db.nodes({one: 1, two: 2})
   __nodesInstanceCRC__ test, node

@@ -1010,7 +1010,7 @@
 @description Check nodes creation / deletion
 db.nodes({node returned from Neo4j}).delete()
 ###
-Tinytest.add 'db.nodes initiate from obj / delete', (test) ->
+Tinytest.add 'Neo4jNode - nodes({Object})', (test) ->
   task =
     method: 'POST'
     to: db.__service.cypher.endpoint
@@ -1030,7 +1030,7 @@
 @description Check nodes creation / deletion
 db.nodes({node ID}).delete()
 ###
-Tinytest.add 'db.nodes initiate by id / delete', (test) ->
+Tinytest.add 'Neo4jNode - nodes(id)', (test) ->
   task =
     method: 'POST'
     to: db.__service.cypher.endpoint
@@ -1050,7 +1050,7 @@
 @description Check nodes creation / deletion
 db.nodes({node returned from Neo4j}, true).delete(name)
 ###
-Tinytest.add 'db.nodes initiate from obj / delete [REACTIVE]', (test) ->
+Tinytest.add 'Neo4jNode - nodes({Object}) [REACTIVE]', (test) ->
   task =
     method: 'POST'
     to: db.__service.cypher.endpoint
@@ -1073,7 +1073,7 @@
 @description Check nodes creation / deletion
 db.nodes({node ID}, true).delete(name)
 ###
-Tinytest.add 'db.nodes initiate by id / delete [REACTIVE]', (test) ->
+Tinytest.add 'Neo4jNode - nodes(id) [REACTIVE]', (test) ->
   task =
     method: 'POST'
     to: db.__service.cypher.endpoint
@@ -1095,7 +1095,7 @@
 @test
 @description Check functionality of Neo4jCursor
 ###
-Tinytest.add 'Neo4jCursor = db.query(...)', (test) ->
+Tinytest.add 'Neo4jCursor - [BASICS]', (test) ->
   db.transaction().commit([
     "CREATE (n:Neo4jCursorTests {data1}) RETURN n"
     "CREATE (n:Neo4jCursorTests {data2}) RETURN n"
@@ -1152,10 +1152,10 @@

 ###
 @test
-@description Check nodes creation / getProperty / deletion
+@description
 db.queryOne("...").nodeLink.delete()
 ###
-Tinytest.add 'db.nodes test returned node instance from db.queryOne / delete', (test) ->
+Tinytest.add 'Neo4jNode - [BASICS]', (test) ->
   cursor = db.query "CREATE (n:NodesTests {data}) RETURN n", {data: testing: 'NodesTests'}

   test.equal cursor.length, 1
@@ -1171,7 +1171,7 @@
 @description Check nodes fetching / deletion
 db.query("...").current().nodeLink.delete()
 ###
-Tinytest.add 'db.nodes test returned node instance from db.queryOne / delete [REACTIVE]', (test) ->
+Tinytest.add 'Neo4jNode - [REACTIVE]', (test) ->
   cursor = db.query
     query: "CREATE (n:NodesTestsReactive {data}) RETURN n"
     opts: data: testingReactive: 'some data'
@@ -1195,7 +1195,7 @@
 @description Check nodes fetching / setting label / deletion
 db.nodes().setLabel('label').delete()
 ###
-Tinytest.add 'db.nodes create / setLabel / delete', (test) ->
+Tinytest.add 'Neo4jNode - setLabel(name)', (test) ->
   node = db.nodes().setLabel('MyLabel')
   __nodesInstanceCRC__ test, node

@@ -1210,7 +1210,7 @@
 @description Check nodes fetching / setting label / deletion
 db.nodes().setLabels(['label', 'label2']).delete()
 ###
-Tinytest.add 'db.nodes create / setLabels / delete', (test) ->
+Tinytest.add 'Neo4jNode - setLabels([name, name2]) ', (test) ->
   node = db.nodes().setLabels(['MyLabel', 'MyLabel2'])
   __nodesInstanceCRC__ test, node

@@ -1225,7 +1225,7 @@
 @description Check nodes fetching / setting label / deletion
 db.nodes().setLabels(['label', 'label2']).setLabel('label').setLabels(['label', 'label2']).setLabel('label').delete()
 ###
-Tinytest.add 'db.nodes create / setLabels / setLabel / delete', (test) ->
+Tinytest.add 'Neo4jNode - setLabels([name, name2]).setLabel(name3)', (test) ->
   node = db.nodes().setLabels(['MyLabel', 'MyLabel2']).setLabel('MyLabel3').setLabels(['MyLabel4', 'MyLabel5']).setLabel('MyLabel6')
   __nodesInstanceCRC__ test, node

@@ -1240,7 +1240,7 @@
 @description Check nodes fetching / setting label / deletion
 db.nodes().setLabels(['label', 'label2']).setLabel('label').setLabels(['label', 'label2']).setLabel('label').delete()
 ###
-Tinytest.add 'db.nodes create / setLabels / setLabel / delete [DUPLICATES]', (test) ->
+Tinytest.add 'Neo4jNode - setLabels([name, name]).setLabel(name) [DUPLICATES]', (test) ->
   node = db.nodes().setLabels(['MyLabel', 'MyLabel2']).setLabel('MyLabel').setLabels(['MyLabel2', 'MyLabel5']).setLabel('MyLabel5')
   __nodesInstanceCRC__ test, node

@@ -1255,7 +1255,7 @@
 @description Check nodes fetching / setting label / deletion
 db.nodes().setLabels(['label', 'label2']).setLabel('label').setLabels(['label', 'label2']).setLabel('label').delete()
 ###
-Tinytest.add 'db.nodes create / setLabels / setLabel / delete [Invalid Names]', (test) ->
+Tinytest.add 'Neo4jNode - setLabels([name, ""]).setLabel("") [Invalid Names]', (test) ->
   node = db.nodes().setLabels(['My Label', '']).setLabel('').setLabel('Label').setLabels(['', ''])
   __nodesInstanceCRC__ test, node

@@ -1270,7 +1270,7 @@
 @description Check nodes fetching / replacing label / deletion
 db.nodes().setLabels(['label', 'label2']).replaceLabels(['label']).delete()
 ###
-Tinytest.add 'db.nodes create / replaceLabels / delete', (test) ->
+Tinytest.add 'Neo4jNode - replaceLabels([String])', (test) ->
   node = db.nodes().setLabels(['MyLabel1', 'MyLabel2'])
   __nodesInstanceCRC__ test, node

@@ -1291,7 +1291,7 @@
 @description Check nodes fetching / replacing label / deletion
 db.nodes().setLabels(['label', 'label2']).replaceLabels(['label']).delete()
 ###
-Tinytest.add 'db.nodes create / replaceLabels / delete [DUPLICATES]', (test) ->
+Tinytest.add 'Neo4jNode - replaceLabels([String]) [DUPLICATES]', (test) ->
   node = db.nodes().setLabels(['MyLabel1', 'MyLabel2', 'MyLabel1']).setLabel('MyLabel1')
   __nodesInstanceCRC__ test, node

@@ -1312,7 +1312,7 @@
 @description Check nodes fetching / replacing label / deletion
 db.nodes().setLabels(['label', 'label2']).replaceLabels(['label']).delete()
 ###
-Tinytest.add 'db.nodes create / replaceLabels / delete [Invalid Names]', (test) ->
+Tinytest.add 'Neo4jNode - replaceLabels([String]) [Invalid Names]', (test) ->
   node = db.nodes().setLabels(['MyLabel1', 'MyLabel2', '']).setLabel('').replaceLabels(["", ""])
   __nodesInstanceCRC__ test, node

@@ -1333,7 +1333,7 @@
 @description Check nodes fetching / deleting label / deletion
 db.nodes().setLabels(['label', 'label2']).deleteLabel('label').delete()
 ###
-Tinytest.add 'db.nodes create / deleteLabel / delete', (test) ->
+Tinytest.add 'Neo4jNode - deleteLabel(name)', (test) ->
   node = db.nodes().setLabels(['MyLabel1', 'MyLabel2'])
   __nodesInstanceCRC__ test, node

@@ -1354,7 +1354,7 @@
 @description Check nodes fetching / deleting label / deletion
 db.nodes().setLabels(['label', 'label2']).deleteLabel('label').delete()
 ###
-Tinytest.add 'db.nodes create / deleteLabel / delete [Non Existent]', (test) ->
+Tinytest.add 'Neo4jNode - deleteLabel(name) [Non Existent]', (test) ->
   node = db.nodes().setLabels(['MyLabel1', 'MyLabel2'])
   __nodesInstanceCRC__ test, node

@@ -1375,7 +1375,7 @@
 @description Check nodes fetching / deleting labels / deletion
 db.nodes().setLabels(['label', 'label2', 'label3']).deleteLabels(['label', 'label3']).delete()
 ###
-Tinytest.add 'db.nodes create / deleteLabels / delete', (test) ->
+Tinytest.add 'Neo4jNode - deleteLabels([String])', (test) ->
   node = db.nodes().setLabels(['MyLabel1', 'MyLabel2', 'MyLabel3'])
   __nodesInstanceCRC__ test, node

@@ -1396,7 +1396,7 @@
 @description Check nodes fetching / deleting labels / deletion
 db.nodes().setLabels(['label', 'label2', 'label3']).deleteLabels(['label5', 'label6']).delete()
 ###
-Tinytest.add 'db.nodes create / deleteLabels / delete [Non Existent]', (test) ->
+Tinytest.add 'Neo4jNode - deleteLabels([String]) [Non Existent]', (test) ->
   node = db.nodes().setLabels(['MyLabel1', 'MyLabel2', 'MyLabel3'])
   __nodesInstanceCRC__ test, node

@@ -1417,7 +1417,7 @@
 @description Check nodes fetching / getting labels / deletion
 db.nodes().labels().delete()
 ###
-Tinytest.add 'db.nodes create / labels / delete [GET]', (test) ->
+Tinytest.add 'Neo4jNode - labels() [GET]', (test) ->
   node = db.nodes().setLabels(['MyLabel1', 'MyLabel2', 'MyLabel3'])
   test.equal node.labels(), ["MyLabel1", "MyLabel2", "MyLabel3"]
   node.delete()
@@ -1427,7 +1427,7 @@
 @description Check nodes fetching / getting labels / deletion
 db.nodes().labels(['label', 'label2']).labels().delete()
 ###
-Tinytest.add 'db.nodes create / labels / delete [SET / GET]', (test) ->
+Tinytest.add 'Neo4jNode - labels([String]).labels() [SET / GET]', (test) ->
   node = db.nodes().labels(['MyLabel1', 'MyLabel2', 'MyLabel3'])
   test.equal node.labels(), ["MyLabel1", "MyLabel2", "MyLabel3"]

@@ -1442,7 +1442,7 @@
 @description Check nodes fetching / getting labels / deletion
 db.nodes().labels(['label', 'label2']).labels().delete()
 ###
-Tinytest.add 'db.nodes create / labels / delete [SET / GET] [REACTIVE]', (test) ->
+Tinytest.add 'Neo4jNode - labels([String]).labels() [SET / GET] [REACTIVE]', (test) ->
   node = db.nodes(null, true)
   test.equal node.labels(), []

@@ -1458,7 +1458,7 @@
 @description
 db.getRelation(id).delete()
 ###
-Tinytest.add 'r = db.getRelation / r.delete', (test) ->
+Tinytest.add 'Neo4jDB - getRelation(id)', (test) ->
   r = db.queryOne("CREATE (a)-[r:KNOWS {test: true}]->(b) RETURN r").r
   _r = db.getRelation(r.id)
   __relationCRC__ test, _r, r.start, r.end, 'KNOWS', {test: true}
@@ -1472,7 +1472,7 @@
 @description
 db.getRelation(id, true).delete()
 ###
-Tinytest.add 'r = db.getRelation / r.delete [REACTIVE]', (test) ->
+Tinytest.add 'Neo4jDB - getRelation(id, true) [REACTIVE]', (test) ->
   r = db.queryOne("CREATE (a)-[r:KNOWS {test: true}]->(b) RETURN r").r
   _r = db.getRelation(r.id, true)

@@ -1489,7 +1489,7 @@
 @description
 db.createRelation(db.nodes(), db.nodes()).delete()
 ###
-Tinytest.add 'r = db.createRelation / r.delete', (test) ->
+Tinytest.add 'Neo4jDB - createRelation(from, to, type, {})', (test) ->
   n1 = db.nodes()
   n2 = db.nodes()
   r = db.createRelation n1, n2, 'KNOWS', {test: true}
@@ -1504,7 +1504,7 @@
 @description
 db.createRelation(db.nodes(), db.nodes()).delete()
 ###
-Tinytest.add 'r = db.createRelation / r.delete [NoProps]', (test) ->
+Tinytest.add 'Neo4jDB - createRelation(from, to, type) [NoProps]', (test) ->
   n1 = db.nodes()
   n2 = db.nodes()
   r = db.createRelation n1, n2, 'KNOWS'
@@ -1519,7 +1519,7 @@
 @description
 db.createRelation(db.nodes(), db.nodes(), {_reactive: true}).delete()
 ###
-Tinytest.add 'r = db.createRelation / r.delete [REACTIVE]', (test) ->
+Tinytest.add 'Neo4jDB - createRelation(from, to, type, {_reactive: true}) [REACTIVE]', (test) ->
   n1 = db.nodes()
   n2 = db.nodes()
   r = db.createRelation n1, n2, 'KNOWS', _reactive: true
@@ -1540,7 +1540,7 @@
 @description
 db.node().to(node2).delete()
 ###
-Tinytest.add 'Create relationship db.node().to(node2) / r.delete', (test) ->
+Tinytest.add 'Neo4jNode - [relationship] - node.to(node2, type)', (test) ->
   n1 = db.nodes()
   n2 = db.nodes()
   r = n1.to n2, 'KNOWS', foo: 'bar'
@@ -1560,7 +1560,7 @@
 @description
 db.node().from(node2).delete()
 ###
-Tinytest.add 'Create relationship db.node().from(node2) / r.delete', (test) ->
+Tinytest.add 'Neo4jNode - [relationship] - node.from(node2, type)', (test) ->
   n1 = db.nodes()
   n2 = db.nodes()
   r = n1.from n2, 'KNOWS', foo: 'bar'
@@ -1580,7 +1580,7 @@
 @description
 db.node().to(node2).delete()
 ###
-Tinytest.add 'Create relationship db.node().to(node2) / r.delete [REACTIVE]', (test) ->
+Tinytest.add 'Neo4jNode - [relationship] - node.to(node2, type, {_reactive: true}) [REACTIVE]', (test) ->
   n1 = db.nodes()
   n2 = db.nodes()
   r = n1.to n2, 'KNOWS', {foo: 'bar', _reactive: true}
@@ -1602,7 +1602,7 @@
 @description
 db.node().from(node2).delete()
 ###
-Tinytest.add 'Create relationship db.node().from(node2) / r.delete [REACTIVE]', (test) ->
+Tinytest.add 'Neo4jNode - [relationship] - node.from(node2, type, {_reactive: true}) [REACTIVE]', (test) ->
   n1 = db.nodes()
   n2 = db.nodes()
   r = n1.from n2, 'KNOWS', {foo: 'bar', _reactive: true}
@@ -1624,7 +1624,7 @@
 @description Check nodes fetching / getting degree / deletion
 db.nodes(id).degree().delete()
 ###
-Tinytest.add 'db.nodes.degree()', (test) ->
+Tinytest.add 'Neo4jNode - degree()', (test) ->
   n1 = db.nodes()
   n2 = db.nodes()
   n3 = db.nodes()
@@ -1757,4 +1757,362 @@
   test.equal n2.delete(), undefined
   test.equal n3.delete(), undefined

-
+###
+@test
+@description
+db.node().relationships()
+###
+Tinytest.add 'Neo4jNode - relationships()', (test) ->
+  n1 = db.nodes()
+  n2 = db.nodes()
+  r1 = n1.to n2, 'LIKES', tests: 'yes'
+  r2 = n2.to n1, 'KNOWS'
+
+  __relationCRC__ test, r1, n1.get().id, n2.get().id, 'LIKES', {tests: 'yes'}
+  __relationCRC__ test, r2, n2.get().id, n1.get().id, 'KNOWS', {}
+
+  cursor1 = n1.relationships()
+  cursor2 = n2.relationships()
+
+  test.instanceOf cursor1, Neo4jCursor
+  test.instanceOf cursor2, Neo4jCursor
+
+  cursor1.each (relation) -> __relationCRC__ test, relation
+  cursor2.each (relation) -> __relationCRC__ test, relation
+
+  r1.delete()
+  r2.delete()
+  n1.delete()
+  n2.delete()
+
+###
+@test
+@description
+db.node().relationships("in|out|all", [types])
+###
+Tinytest.add 'Neo4jNode - relationships("in|out|all", [types])', (test) ->
+  n1 = db.nodes()
+  n2 = db.nodes()
+  r1 = n1.to n2, 'LIKES', tests: 'yes'
+  r2 = n2.to n1, 'KNOWS'
+
+  __relationCRC__ test, r1, n1.get().id, n2.get().id, 'LIKES', {tests: 'yes'}
+  __relationCRC__ test, r2, n2.get().id, n1.get().id, 'KNOWS', {}
+
+  cursor1 = n1.relationships('out')
+  cursor2 = n2.relationships('in')
+
+  test.instanceOf cursor1, Neo4jCursor
+  test.instanceOf cursor2, Neo4jCursor
+
+  cursor1.each (relation) -> __relationCRC__ test, relation, n1.get().id, n2.get().id, 'LIKES', {tests: 'yes'}
+  cursor2.each (relation) -> __relationCRC__ test, relation, n1.get().id, n2.get().id, 'LIKES', {tests: 'yes'}
+
+  cursor1 = n1.relationships('in')
+  cursor2 = n2.relationships('out')
+
+  test.instanceOf cursor1, Neo4jCursor
+  test.instanceOf cursor2, Neo4jCursor
+
+  cursor1.each (relation) -> __relationCRC__ test, relation, n2.get().id, n1.get().id, 'KNOWS'
+  cursor2.each (relation) -> __relationCRC__ test, relation, n2.get().id, n1.get().id, 'KNOWS'
+
+  cursor1 = n1.relationships('all', ['KNOWS'])
+  cursor2 = n2.relationships('all', ['LIKES'])
+
+  test.instanceOf cursor1, Neo4jCursor
+  test.instanceOf cursor2, Neo4jCursor
+
+  cursor1.each (relation) -> __relationCRC__ test, relation, n2.get().id, n1.get().id, 'KNOWS'
+  cursor2.each (relation) -> __relationCRC__ test, relation, n1.get().id, n2.get().id, 'LIKES', {tests: 'yes'}
+
+  r1.delete()
+  r2.delete()
+  n1.delete()
+  n2.delete()
+
+
+###
+@test
+@description
+db.node().relationships("in|out|all", [types], true)
+###
+Tinytest.add 'Neo4jNode - relationships("in|out|all", [types]) [REACTIVE]', (test) ->
+  n1 = db.nodes()
+  n2 = db.nodes()
+  r1 = n1.to n2, 'LIKES', tests: 'yes'
+  r2 = n2.to n1, 'KNOWS'
+
+  __relationCRC__ test, r1, n1.get().id, n2.get().id, 'LIKES', {tests: 'yes'}
+  __relationCRC__ test, r2, n2.get().id, n1.get().id, 'KNOWS', {}
+
+  cursor1 = n1.relationships('out', [], true)
+  cursor2 = n2.relationships('in', [], true)
+
+  test.instanceOf cursor1, Neo4jCursor
+  test.instanceOf cursor2, Neo4jCursor
+
+  db.transaction([
+    "MATCH ()-[r]-() WHERE id(r) = {id1} SET r.newProp1 = 'rrrreactive!'"
+    "MATCH ()-[r]-() WHERE id(r) = {id2} SET r.newProp2 = 'rrrreactive!'"]
+  ,
+    id1: r1.get().id
+    id2: r2.get().id
+  ).commit()
+
+  cursor1.each (relation) -> __relationCRC__ test, relation, n1.get().id, n2.get().id, 'LIKES', {
+    tests: 'yes'
+    newProp1: 'rrrreactive!'
+  }
+  cursor2.each (relation) -> __relationCRC__ test, relation, n1.get().id, n2.get().id, 'LIKES', {
+    tests: 'yes'
+    newProp1: 'rrrreactive!'
+  }
+
+  cursor1 = n1.relationships('in', [], true)
+  cursor2 = n2.relationships('out', [], true)
+
+  test.instanceOf cursor1, Neo4jCursor
+  test.instanceOf cursor2, Neo4jCursor
+
+  db.transaction([
+    "MATCH ()-[r]-() WHERE id(r) = {id1} SET r.newProp3 = 'rrrreactive3!'"
+    "MATCH ()-[r]-() WHERE id(r) = {id2} SET r.newProp4 = 'rrrreactive4!'"]
+  ,
+    id1: r1.get().id
+    id2: r2.get().id
+  ).commit()
+
+  cursor1.each (relation) -> __relationCRC__ test, relation, n2.get().id, n1.get().id, 'KNOWS', {
+    newProp2: 'rrrreactive!'
+    newProp4: 'rrrreactive4!'
+  }
+  cursor2.each (relation) -> __relationCRC__ test, relation, n2.get().id, n1.get().id, 'KNOWS', {
+    newProp2: 'rrrreactive!'
+    newProp4: 'rrrreactive4!'
+  }
+
+  cursor1 = n1.relationships('all', ['KNOWS'], true)
+  cursor2 = n2.relationships('all', ['LIKES'], true)
+
+  test.instanceOf cursor1, Neo4jCursor
+  test.instanceOf cursor2, Neo4jCursor
+
+  db.transaction([
+    "MATCH ()-[r]-() WHERE id(r) = {id1} SET r.newProp5 = 'rrrreactive5!'"
+    "MATCH ()-[r]-() WHERE id(r) = {id2} SET r.newProp6 = 'rrrreactive6!'"]
+  ,
+    id1: r1.get().id
+    id2: r2.get().id
+  ).commit()
+
+  cursor1.each (relation) -> __relationCRC__ test, relation, n2.get().id, n1.get().id, 'KNOWS', {
+    newProp2: 'rrrreactive!'
+    newProp4: 'rrrreactive4!'
+    newProp6: 'rrrreactive6!'
+  }
+  cursor2.each (relation) -> __relationCRC__ test, relation, n1.get().id, n2.get().id, 'LIKES', {
+    tests: 'yes'
+    newProp1: 'rrrreactive!'
+    newProp3: 'rrrreactive3!'
+    newProp5: 'rrrreactive5!'
+  }
+
+  r1.delete()
+  r2.delete()
+  n1.delete()
+  n2.delete()
+
+
+###
+@test
+@description
+r.setProperty(name, val)
+###
+Tinytest.add 'Neo4jRelationship - setProperty("name", "value")', (test) ->
+  n1 = db.nodes()
+  n2 = db.nodes()
+  r = n1.to n2, "KNOWS", {testRels: true}
+  _id = r.get().id
+
+  r.setProperty 'newProp', 'newPropValue'
+
+  __relationCRC__ test, r, n1.get().id, n2.get().id, "KNOWS", {testRels: true, newProp: 'newPropValue'}
+
+  cursor = db.query "MATCH ()-[r]-() WHERE id(r) = {id} RETURN DISTINCT r", {id: _id}
+  cursor.each (relation) ->
+    __relationCRC__ test, relation.r, n1.get().id, n2.get().id, "KNOWS", {testRels: true, newProp: 'newPropValue'}
+
+  test.equal r.delete(), undefined
+  test.equal n1.delete(), undefined
+  test.equal n2.delete(), undefined
+
+###
+@test
+@description
+r.setProperty({name: val})
+###
+Tinytest.add 'Neo4jRelationship - setProperty({Object})', (test) ->
+  n1 = db.nodes()
+  n2 = db.nodes()
+  r = n1.to n2, "KNOWS", {testRels: true}
+  _id = r.get().id
+
+  r.setProperty {newProp2: 'newPropValue2'}
+
+  __relationCRC__ test, r, n1.get().id, n2.get().id, "KNOWS", {testRels: true, newProp2: 'newPropValue2'}
+
+  cursor = db.query "MATCH ()-[r]-() WHERE id(r) = {id} RETURN DISTINCT r", {id: _id}
+  cursor.each (relation) ->
+    __relationCRC__ test, relation.r, n1.get().id, n2.get().id, "KNOWS", {testRels: true, newProp2: 'newPropValue2'}
+
+  test.equal r.delete(), undefined
+  test.equal n1.delete(), undefined
+  test.equal n2.delete(), undefined
+
+###
+@test
+@description Expect to delete or override old props, and create new
+r.updateProperties({name: val})
+###
+Tinytest.add 'Neo4jRelationship - updateProperties({Object})', (test) ->
+  n1 = db.nodes()
+  n2 = db.nodes()
+  r = n1.to n2, "KNOWS", {testRels: true}
+  _id = r.get().id
+
+  r.updateProperties {newProp1: 'newPropValue1', newProp2: 'newPropValue2'}
+
+  __relationCRC__ test, r, n1.get().id, n2.get().id, "KNOWS", {newProp1: 'newPropValue1', newProp2: 'newPropValue2'}
+
+  cursor = db.query "MATCH ()-[r]-() WHERE id(r) = {id} RETURN DISTINCT r", {id: _id}
+  cursor.each (relation) ->
+    __relationCRC__ test, relation.r, n1.get().id, n2.get().id, "KNOWS", {newProp1: 'newPropValue1', newProp2: 'newPropValue2'}
+
+  test.equal r.delete(), undefined
+  test.equal n1.delete(), undefined
+  test.equal n2.delete(), undefined
+
+###
+@test
+@description
+r.setProperties({name: val})
+###
+Tinytest.add 'Neo4jRelationship - setProperties({Object})', (test) ->
+  n1 = db.nodes()
+  n2 = db.nodes()
+  r = n1.to n2, "KNOWS", {testRels: true}
+  _id = r.get().id
+
+  r.updateProperties {testRels: true, newProp1: 'newPropValue1', newProp2: 'newPropValue2'}
+
+  __relationCRC__ test, r, n1.get().id, n2.get().id, "KNOWS", {testRels: true, newProp1: 'newPropValue1', newProp2: 'newPropValue2'}
+
+  cursor = db.query "MATCH ()-[r]-() WHERE id(r) = {id} RETURN DISTINCT r", {id: _id}
+  cursor.each (relation) ->
+    __relationCRC__ test, relation.r, n1.get().id, n2.get().id, "KNOWS", {testRels: true, newProp1: 'newPropValue1', newProp2: 'newPropValue2'}
+
+  test.equal r.delete(), undefined
+  test.equal n1.delete(), undefined
+  test.equal n2.delete(), undefined
+
+###
+@test
+@description
+r.property(name)
+###
+Tinytest.add 'Neo4jRelationship - property(name) [GET]', (test) ->
+  n1 = db.nodes()
+  n2 = db.nodes()
+  r = n1.to n2, "KNOWS", {testRels: true}
+
+  test.equal r.property('testRels'), true
+
+  test.equal r.delete(), undefined
+  test.equal n1.delete(), undefined
+  test.equal n2.delete(), undefined
+
+###
+@test
+@description
+r.property(name)
+###
+Tinytest.add 'Neo4jRelationship - property(name, value) [SET]', (test) ->
+  n1 = db.nodes()
+  n2 = db.nodes()
+  r = n1.to n2, "KNOWS", {testRels: true}
+  _id = r.get().id
+
+  r.property 'newProp', 'newPropValue'
+
+  __relationCRC__ test, r, n1.get().id, n2.get().id, "KNOWS", {testRels: true, newProp: 'newPropValue'}
+
+  cursor = db.query "MATCH ()-[r]-() WHERE id(r) = {id} RETURN DISTINCT r", {id: _id}
+  cursor.each (relation) ->
+    __relationCRC__ test, relation.r, n1.get().id, n2.get().id, "KNOWS", {testRels: true, newProp: 'newPropValue'}
+
+  test.equal r.delete(), undefined
+  test.equal n1.delete(), undefined
+  test.equal n2.delete(), undefined
+
+###
+@test
+r.property(name)
+###
+Tinytest.add 'Neo4jRelationship - property(name, value) [UPDATE]', (test) ->
+  n1 = db.nodes()
+  n2 = db.nodes()
+  r = n1.to n2, "KNOWS", {testRels: true}
+  _id = r.get().id
+
+  r.property('newProp', 'newPropValue').property('testRels', 'false')
+
+  __relationCRC__ test, r, n1.get().id, n2.get().id, "KNOWS", {testRels: 'false', newProp: 'newPropValue'}
+
+  cursor = db.query "MATCH ()-[r]-() WHERE id(r) = {id} RETURN DISTINCT r", {id: _id}
+  cursor.each (relation) ->
+    __relationCRC__ test, relation.r, n1.get().id, n2.get().id, "KNOWS", {testRels: 'false', newProp: 'newPropValue'}
+
+  test.equal r.delete(), undefined
+  test.equal n1.delete(), undefined
+  test.equal n2.delete(), undefined
+
+###
+@test
+@description
+r.getProperty(name)
+###
+Tinytest.add 'Neo4jRelationship - getProperty(name)', (test) ->
+  n1 = db.nodes()
+  n2 = db.nodes()
+  r = n1.to n2, "KNOWS", {testRels: true}
+
+  test.equal r.getProperty('testRels'), true
+
+  test.equal r.delete(), undefined
+  test.equal n1.delete(), undefined
+  test.equal n2.delete(), undefined
+
+
+###
+@test
+@description
+r = n1.to(n2, type, {_reactive: true})
+r.getProperty(name)
+###
+Tinytest.add 'Neo4jRelationship - getProperty(name) [REACTIVE]', (test) ->
+  n1 = db.nodes()
+  n2 = db.nodes()
+  r = n1.to n2, "KNOWS", {testRels: true, _reactive: true}
+  id = r.get().id
+
+  db.querySync "MATCH ()-[r]-() WHERE id(r) = {id} SET r.testRels = 'rrrreactive5!'", {id}
+
+  test.equal r.getProperty('testRels'), 'rrrreactive5!'
+
+  test.equal r.delete(), undefined
+  test.equal n1.delete(), undefined
+  test.equal n2.delete(), undefined
+
+
+


пытался оптимизировать ленту новостей

пытался оптимизировать ленту новостей

--- app/controllers/feed.coffee
+++ app/controllers/feed.coffee
@@ -1,4 +1,5 @@

+_ = 											require('underscore')
 mongoose = 										require('mongoose')
 colors = 										require('colors')
 EventEmitter = 									require('events').EventEmitter
@@ -13,6 +14,7 @@
 		this.on 'send', () =>
 			# console.log 						JSON.stringify(@mdl.model).cyan
 			@res.jsonp 							@mdl.model
+

 		this.on 'fail', () =>
 			@mdl.fail()
@@ -43,11 +45,9 @@
 		this.on 'get', () =>

 			@get (posts) =>
-
-				@mdl = 							require(global.home + '/script/models/feed/get')(posts)
+
+				@mdl = 					require(global.home + '/script/models/feed/get')(posts)
 				@emit 'send'
-
-

 	get: (callback) ->


Code style

Code style

--- lib/linter/gc.coffee
+++ lib/linter/gc.coffee
@@ -36,7 +36,7 @@
         if item[0] is '\t' and violations.length > 0
           # stuff like interfaces not being satisfied, etc will be indented
           unless skippingIndented
-            violations[violations.length-1].message += '\n' + item
+            violations[violations.length - 1].message += '\n' + item
         else
           [_, filePath, line, _, col, msg] = item.match(errorPattern)
           filePath = '/' + filePath
@@ -49,7 +49,7 @@
           line ||= '1'
           col ||= '1'

-          bufferPoint = new Point(parseInt(line)-1, parseInt(col)-1)
+          bufferPoint = new Point(parseInt(line) - 1, parseInt(col) - 1)
           bufferRange = new Range(bufferPoint, bufferPoint)
           violations.push(new Violation('error', bufferRange, msg))

@@ -81,7 +81,7 @@
   # normally `go build` does this all for us).
   # Opting for *g instead of go build because the linking would take up
   # unnecessary real and cpu time for no gain.
-  buildCommand: () ->
+  buildCommand: ->
     # compile with all the other files in the same directory so it doesn't
     # complain about missing identifiers, etc
     here = path.dirname(@filePath)


MachinesListItemHeader: Add provider column.

--- client/app/lib/environment/machineslistitemheader.coffee
+++ client/app/lib/environment/machineslistitemheader.coffee
@@ -16,6 +16,7 @@
   pistachio: ->
     """

NAME

+
PROVIDER

TYPE

OS

ALWAYS ON


Formatting

Formatting

--- spec/git-repository-async-spec.coffee
+++ spec/git-repository-async-spec.coffee
@@ -353,7 +353,7 @@
     it "emits a status-changed event when a buffer is saved", ->
       waitsForPromise ->
         atom.workspace.open('other.txt').then (o) ->
-                    editor = o
+          editor = o
       runs ->
         editor.insertNewline()
         statusHandler = jasmine.createSpy('statusHandler')