removed varPrefix

removed varPrefix

--- lib/provider.coffee
+++ lib/provider.coffee
@@ -52,7 +52,7 @@

                     @getObjectAvailableMethods(editor, prefix, objectType, setAsInherited)
                 else if matches[0] == "self::"
-                    completions = @getLocalAvailableCompletions(editor,prefix).filter((item) -> item.isStatic)
+                    completions = @getLocalAvailableCompletions(editor).filter((item) -> item.isStatic)
                     resolve(completions)
             else if objectType = @isKnownObject(editor, bufferPosition, prefix)
                 @getObjectAvailableMethods(editor, prefix, objectType, resolve)
@@ -63,15 +63,10 @@

         prefix.match(/(\$this->|parent::|self::)/)

-    getLocalAvailableCompletions: (editor,prefix) ->
+    getLocalAvailableCompletions: (editor) ->

         inline = []
         completions = []
-        varPrefix = ''
-
-        #WTF???
-        if  prefix.search('self::') or prefix.search('parent::')
-            varPrefix = '$'

         for line in editor.buffer.getLines()

@@ -88,7 +83,7 @@
                     inline = []

             if matches = line.match(propertyRegex)
-                completions.push(@createVariableCompletion(matches, varPrefix))
+                completions.push(@createVariableCompletion(matches))
             else if matches = line.match(constantRegex)
                 completions.push(@createConstantCompletion matches)
             else if matches = line.match(methodRegex) || ma
@@ -102,10 +97,10 @@

         return completions

-    createVariableCompletion: (matches,varPrefix = '') ->
+    createVariableCompletion: (matches) ->
         @createCompletion
             name: "$"+matches[3]
-            snippet: "#{varPrefix}#{matches[3]}${2}"
+            snippet: "#{matches[3]}${2}"
             isStatic: matches[2] != undefined
             visibility: matches[1]
             type: 'property'


Support And, Given, Then and When

Support And, Given, Then and When

--- lib/provider.coffee
+++ lib/provider.coffee
@@ -1,7 +1,7 @@
 fs = require 'fs'
 path = require 'path'

-propertyPrefixPattern = /(?:^|\[|\(|,|=|:|\s)\s*(And\s(?:[a-zA-Z]+\.?){0,2})$/
+propertyPrefixPattern = /(?:^|\[|\(|,|=|:|\s)\s*((?:And|Given|Then|When)\s(?:[a-zA-Z]+\.?){0,2})$/

 module.exports =
   selector: '.source.feature, .feature'


Remove unneeded bodyTree key

Remove unneeded bodyTree key

--- lib/snippets.coffee
+++ lib/snippets.coffee
@@ -169,6 +169,6 @@
   insert: (snippet, editor=atom.workspace.getActiveEditor()) ->
     if typeof snippet is 'string'
       bodyTree = @getBodyParser().parse(snippet)
-      snippet = new Snippet({name: '__anonymous', prefix: '', bodyTree: bodyTree, bodyText: snippet})
+      snippet = new Snippet({name: '__anonymous', prefix: '', bodyTree, bodyText: snippet})

     new SnippetExpansion(snippet, editor)


Be more verbose on demand

Be more verbose on demand

Better mehod naming and null handling

--- lib/uploader.coffee
+++ lib/uploader.coffee
@@ -6,8 +6,9 @@

 class Uploader extends EventEmitter
   #FIXME: 0 records?
-  constructor: ({accessKey, secretKey, region, stream, objectName, objectParams, bucket, partSize, maxBufferSize}, @cb) ->
+  constructor: ({accessKey, secretKey, region, stream, objectName, objectParams, bucket, partSize, maxBufferSize, verbose}, @cb) ->
     super()
+
     aws.config.update
       accessKeyId:     accessKey
       secretAccessKey: secretKey
@@ -18,7 +19,11 @@
     @objectParams.Bucket ?= bucket
     @objectParams.Key    ?= objectName

-    @maxBufferSize = maxBufferSize # TODO
+    @maxBufferSize        = maxBufferSize # TODO
+    @partSize             = partSize or 5242880 # 5MB
+    @verbose             ?= false
+
+

     if not @objectParams.Bucket then throw new Error "Bucket must be given"

@@ -30,13 +35,12 @@
     @partNumber      = 1
     @parts           = []
     @uploadedParts   = {}
-    @partSize        = partSize or 5242880 # 5MB
     @currentChunk    = new Buffer 0

     @on 'error', (err) => @failed = true

-    @handleStream stream
+    @setStreamHandlers stream
     process.nextTick => @initiateTransfer()

@@ -54,7 +58,7 @@
       @emit 'initiated', @uploadId

-  handleStream: (stream) ->
+  setStreamHandlers: (stream) ->
     stream.on 'data', (chunk) =>
       if typeof(chunk) is 'string' then chunk = new Buffer chunk, 'utf-8'
       @currentChunk = Buffer.concat [@currentChunk, chunk]
@@ -107,14 +111,15 @@
         chunk.progress = false
         chunk.finished = true

-        @uploadedParts[currentPartNumber] = data.ETag
+        @uploadedParts[currentPartNumber] = data?.ETag

         if err then @emit 'error', err
-        @emit 'uploaded', etag: data.ETag
+        @emit 'uploaded', etag: data?.ETag

-        next()
+        next err

     , (err) =>
+      if err then console.error 'Upload failed', err
       @pruneParts()

@@ -137,6 +142,7 @@
       if @parts.length is 0
         @finishJob()
       else
+        process.stdout.write('W') if @verbose
         setTimeout (=> @pruneParts()), 500


Query needs all URL

Query needs all URL

--- lib/zenproxy.coffee
+++ lib/zenproxy.coffee
@@ -65,8 +65,8 @@
         port = if ZENproxy.port is 80 then "" else ":#{ZENproxy.port}"
         if rule.https
           port = if ZENproxy.port is 443 then "" else ":#{ZENproxy.port}"
-        regexQuery = new RegExp "#{rule.query}"
-        if url.split("/")[1].match(regexQuery)?
+        regexQuery = new RegExp "#{rule.domain}#{port}#{rule.query}"
+        if url.match regexQuery
           queries[url] = index
           return rule


Removed enter

Removed enter

Signed-off-by: tomdev <96835dd8bfa718bd6447ccc87af89ae1675daeca@codigy.nl>

--- core/app/backbone/views/activity_item_view.coffee
+++ core/app/backbone/views/activity_item_view.coffee
@@ -13,7 +13,6 @@
 class GenericActivityFactItemView extends Backbone.Marionette.CompositeView
   itemView: FactView
   initialize: (opts) ->
-
     if @model.get('render_fact')
       fact = new Fact(@model.get("activity")["fact"])
       @collection = new Backbone.Collection([ fact ])


Title fix

Title fix

--- framer/Components/ShareComponent.coffee
+++ framer/Components/ShareComponent.coffee
@@ -139,7 +139,7 @@

 	_truncateCredential: (str) ->
 		maxLength = 32
-		maxLengthWithAvatar = 25
+		maxLengthWithAvatar = 23

 		str = _.escape(str)


Rework parsing of custom key mappings.

Rework parsing of custom key mappings.

Most of this is just a tidy up of code that's been around for a long
time.

The only difference, however, is that now a key mapping can include
extra data ("extras") after the name of the command.  For example,

map s vomnibar.activate keyword=g

Here, and extra property "extras" is added to the command registry:

   extras: ["keyword=g"]

This is a first step towards direct vomnibar activation for custom
search.

--- background_scripts/commands.coffee
+++ background_scripts/commands.coffee
@@ -24,21 +24,13 @@
       noRepeat: options.noRepeat
       repeatLimit: options.repeatLimit

-  mapKeyToCommand: (key, command) ->
+  mapKeyToCommand: ({ key, command, extras }) ->
     unless @availableCommands[command]
-      console.log(command, "doesn't exist!")
+      console.log command, "doesn't exist!"
       return

-    commandDetails = @availableCommands[command]
-
-    @keyToCommandRegistry[key] =
-      command: command
-      isBackgroundCommand: commandDetails.isBackgroundCommand
-      passCountToFunction: commandDetails.passCountToFunction
-      noRepeat: commandDetails.noRepeat
-      repeatLimit: commandDetails.repeatLimit
-
-  unmapKey: (key) -> delete @keyToCommandRegistry[key]
+    extras ?= []
+    @keyToCommandRegistry[key] = extend { command, extras }, @availableCommands[command]

   # Lower-case the appropriate portions of named keys.
   #
@@ -54,37 +46,29 @@
           "<" + (if optionalPrefix then optionalPrefix else "") + keyName.toLowerCase() + ">")

   parseCustomKeyMappings: (customKeyMappings) ->
-    lines = customKeyMappings.split("\n")
-
-    for line in lines
-      continue if (line[0] == "\"" || line[0] == "#")
-      splitLine = line.replace(/\s+$/, "").split(/\s+/)
-
-      lineCommand = splitLine[0]
-
-      if (lineCommand == "map")
-        continue if (splitLine.length != 3)
-        key = @normalizeKey(splitLine[1])
-        vimiumCommand = splitLine[2]
-
-        continue unless @availableCommands[vimiumCommand]
-
-        console.log("Mapping", key, "to", vimiumCommand)
-        @mapKeyToCommand(key, vimiumCommand)
-      else if (lineCommand == "unmap")
-        continue if (splitLine.length != 2)
-
-        key = @normalizeKey(splitLine[1])
-        console.log("Unmapping", key)
-        @unmapKey(key)
-      else if (lineCommand == "unmapAll")
-        @keyToCommandRegistry = {}
+    for line in customKeyMappings.split "\n"
+      unless  line[0] == "\"" or line[0] == "#"
+        tokens = line.replace(/\s+$/, "").split /\s+/
+        switch tokens[0]
+          when "map"
+            [ _, key, command, extras... ] = tokens
+            if command? and @availableCommands[command]
+              key = @normalizeKey key
+              console.log "Mapping", key, "to", command
+              @mapKeyToCommand { key, command, extras }
+
+          when "unmap"
+            if tokens.length == 2
+              key = @normalizeKey tokens[1]
+              console.log "Unmapping", key
+              delete @keyToCommandRegistry[key]
+
+          when "unmapAll"
+            @keyToCommandRegistry = {}

   clearKeyMappingsAndSetDefaults: ->
     @keyToCommandRegistry = {}
-
-    for key of defaultKeyMappings
-      @mapKeyToCommand(key, defaultKeyMappings[key])
+    @mapKeyToCommand { key, command } for key, command of defaultKeyMappings

   # An ordered listing of all available commands, grouped by type. This is the order they will
   # be shown in the help page.


change file name, refs #105

change file name, refs #105

--- server/helpers/thumb.coffee
+++ server/helpers/thumb.coffee
@@ -54,7 +54,7 @@
     # the image to a 300x300 image. If it's a 'scree' preview, it is resize
     # as a 1200 x 800 image.
     resize: (srcPath, file, name, callback) ->
-        dstPath = "/tmp/2-#{file.name}"
+        dstPath = "/tmp/2-#{file.id}"

         try
             attachFile = (err) =>
@@ -120,7 +120,7 @@
                 log.info """
 createThumb: #{file.id} / #{file.name}: Creation started...
 """
-                rawFile = "/tmp/#{file.name}"
+                rawFile = "/tmp/#{file.id}"
                 stream = file.getBinary 'file', (err) ->
                     return callback err if err
                 stream.pipe fs.createWriteStream rawFile


sidebar: add a css class to vms header

sidebar: add a css class to vms header

--- client/Social/Activity/sidebar/activitysidebar.coffee
+++ client/Social/Activity/sidebar/activitysidebar.coffee
@@ -458,7 +458,9 @@

   addVMTree: ->

-    @addSubView section = new KDCustomHTMLView tagName : 'section'
+    @addSubView section = new KDCustomHTMLView
+      tagName  : 'section'
+      cssClass : 'vms'

     @machineTree = new JTreeViewController
       type                : 'main-nav'


Sidebar: fix unwanted treeview scrollbar cc/ @usirin

--- client/Social/Activity/sidebar/activitysidebar.coffee
+++ client/Social/Activity/sidebar/activitysidebar.coffee
@@ -557,6 +557,8 @@
       type                : 'main-nav'
       treeItemClass       : NavigationItem
       addListsCollapsed   : yes
+
+    @machineTree.getView().unsetClass 'kdscrollview'

     # This is temporary, we will create a separate TreeViewController
     # for this and put this logic into there ~ FIXME ~ GG


sidebar: set unread count of workspace item

--- client/Social/Activity/sidebar/activitysidebar.coffee
+++ client/Social/Activity/sidebar/activitysidebar.coffee
@@ -108,8 +108,16 @@
       else
         pane.putNewMessageIndicator()

-
     item.setUnreadCount? unreadCount
+
+    @setUnreadCountForWorkspace data, unreadCount  if @workspaceItemChannelMap[data._id]
+
+
+  setUnreadCountForWorkspace: (data, unreadCount) ->
+
+    workspaceItem = @workspaceItemChannelMap[data._id]
+
+    workspaceItem.child.setUnreadCount unreadCount


<debug> Model - COrrecting syntax.

<debug> Model - COrrecting syntax.

--- server/models/sensor.coffee
+++ server/models/sensor.coffee
@@ -82,7 +82,7 @@
 	###
 	createMeasure: (data, callback) ->
 		data.sensorId = @id
-		Measure.create data callback
+		Measure.create data, callback

 	###


Remove the At symbol when we check if the alias is valid

--- src/scripts/drush.coffee
+++ src/scripts/drush.coffee
@@ -126,7 +126,7 @@
     site_alias = extra_args.shift()
     command_suff = ''
     if site_alias.charAt(0) is "@"
-      unless verify_alias(site_alias) is false
+      unless verify_alias(site_alias.slice(1)) is false
         command_suff = extra_args.shift()
       else
         `undefined`


rename to shrink code

rename to shrink code

--- src/shapes/Spline.coffee
+++ src/shapes/Spline.coffee
@@ -32,23 +32,27 @@
 	calcControlPoints = (spline) ->
 		spline.keyPoints = spline.vertices

-		vertices = spline.vertices
-		len = vertices.length
+		p = spline.vertices
+		len = p.length
 		if len >= 1
-			spline.controlPointsBehind[0] = vertices[0]
+			spline.controlPointsBehind[0] = p[0]
 		if len >= 2
-			spline.controlPointsAhead[len - 1] = vertices[len - 1]
+			spline.controlPointsAhead[len - 1] = p[len - 1]
 		if len >= 3
 			for i in [1...len - 1]
-				theta1 = Math.atan2 vertices[i].y - vertices[i - 1].y, vertices[i].x - vertices[i - 1].x
-				theta2 = Math.atan2 vertices[i + 1].y - vertices[i].y, vertices[i + 1].x - vertices[i].x
-				len1 = Bu.bevel vertices[i].y - vertices[i - 1].y, vertices[i].x - vertices[i - 1].x
-				len2 = Bu.bevel vertices[i].y - vertices[i + 1].y, vertices[i].x - vertices[i + 1].x
+				theta1 = Math.atan2 p[i].y - p[i - 1].y, p[i].x - p[i - 1].x
+				theta2 = Math.atan2 p[i + 1].y - p[i].y, p[i + 1].x - p[i].x
+				len1 = Bu.bevel p[i].y - p[i - 1].y, p[i].x - p[i - 1].x
+				len2 = Bu.bevel p[i].y - p[i + 1].y, p[i].x - p[i + 1].x
 				theta = theta1 + (theta2 - theta1) * len1 / (len1 + len2)
 				theta += Math.PI if Math.abs(theta - theta1) > Math.PI / 2
-				xA = vertices[i].x - len1 * spline.smooth * Math.cos(theta)
-				yA = vertices[i].y - len1 * spline.smooth * Math.sin(theta)
-				xB = vertices[i].x + len2 * spline.smooth * Math.cos(theta)
-				yB = vertices[i].y + len2 * spline.smooth * Math.sin(theta)
+				xA = p[i].x - len1 * spline.smooth * Math.cos(theta)
+				yA = p[i].y - len1 * spline.smooth * Math.sin(theta)
+				xB = p[i].x + len2 * spline.smooth * Math.cos(theta)
+				yB = p[i].y + len2 * spline.smooth * Math.sin(theta)
 				spline.controlPointsAhead[i] = new Bu.Point xA, yA
 				spline.controlPointsBehind[i] = new Bu.Point xB, yB
+
+				# add control lines for debugging
+				#spline.children[i * 2 - 2] = new Bu.Line spline.vertices[i], spline.controlPointsAhead[i]
+				#spline.children[i * 2 - 1] =  new Bu.Line spline.vertices[i], spline.controlPointsBehind[i]


Input support

Input support

--- grammars/latex.cson
+++ grammars/latex.cson
@@ -6,7 +6,8 @@
 foldingStartMarker: '{'
 foldingStopMarker: '}'

-# Rules to be implemented. Please add to repository and link here to include.
+# Rules to be implemented. Please add to repository and link to a 'meta' to include.
+# The following rules correspond to the ten special latex characters
 patterns: [
     {
         include: '#controlMeta'
@@ -43,6 +44,7 @@
 # List of available rules. Must 'include' a rule to patterns for it to be implemented.
 # Thinking of moving pure TeX commands to a separate file and linking it in here (like the preexisting package).
 repository:
+# Meta Commands
     controlMeta: {
         comment: 'This is (ideally) called when a backslash is found.'
         patterns: [
@@ -57,6 +59,9 @@
             }
             {
                 include: '#usepackage'
+            }
+            {
+                include: '#inputFile'
             }
             {
                 include: '#documentEnvironment'
@@ -173,7 +178,7 @@
         comment: 'Matches an underscore and next character or macro'
         comment: 'Considering making this give a warning, as brackets is best practice'
         name: 'punctuation.subscript.latex'
-        match: '_\\s*(\\\\[a-zA-Z]+|.)?'
+        match: '_\\s*(\\\\[a-zA-Z]+|\\\\[.]|.)?'
     }
     caretMeta: {
         comment: 'Like underscore, but superscript'
@@ -201,10 +206,10 @@
         comment: 'Matches a caret and next character or macro'
         comment: 'Considering making this give a warning, as brackets is best practice'
         name: 'punctuation.superscript.latex'
-        match: '\\^\\s*(\\\\[a-zA-Z]+|.)?'
+        match: '\\^\\s*(\\\\[a-zA-Z]+|\\\\[.]|.)?'
     }
     hashtagMeta: {
-        comment: 'I dont like calling this the pound symbol. Catcode says it is a parameter.'
+        comment: 'I dont like calling this the pound symbol. Catcode says it is a parameter identifier.'
         match: '(\\#{3,}[0-9]+)|(\\#{2}[0-9]+)|(\\#[0-9]+)'
         captures:
             1:
@@ -214,6 +219,7 @@
             3:
                 name: 'variable.parameter.hashtag.1.latex'
     }
+# Other
     escapedCharacter: {
         comment: 'Finds escaped characters like \$ and \%. Uses this regex so unique capture groups can be used.'
         name: 'constant.character.latex'
@@ -478,7 +484,6 @@
         )
         '''
     }
-    # Following needs to be improved to recognise escaped $
     inlineMathMode: {
         comment: 'This can be triggered using $ or \( \). Both can be used in the same pair.'
         contentName: 'string.other.math.inline.latex'
@@ -699,3 +704,62 @@
             }
         ]
     }
+    inputFile: {
+        comment: 'Matches the input/include command and allows custom path colours.'
+        begin: '(\\\\)input(?=[^a-zA-Z@])'
+        beginCaptures:
+            0:
+                name: 'keyword.control.input.latex'
+            1:
+                name: 'punctuation.definition.function.latex'
+        end: '(?<=\\})|(^\\s*$)'
+        endCaptures:
+            1:
+                name: 'invalid.illegal.latex'
+        patterns:[
+            {
+                include: '#awaitingArgumentBrackets'
+            }
+            {
+                comment: 'Only this one necessary because escaped characters will be picked up by awaitingArgumentBrackets.'
+                include: '#lineComment'
+            }
+            {
+                include: '#filePathScope'
+            }
+        ]
+    }
+    filePathScope: {
+        comment: 'Matches a file path (UNIX only, add Windows yourself reader).'
+        contentName: 'variable.parameter.argument.latex'
+        begin: '\\{'
+        beginCaptures:
+            0:
+                name: 'punctuation.definition.argument.begin.latex'
+        end: '\\}'
+        endCaptures:
+            0:
+                name: 'punctuation.definition.argument.end.latex'
+        patterns: [
+            {
+                name: 'support.filepath.back.latex'
+                match: '\\.{2}\\/'
+            }
+            {
+                name: 'support.filepath.home.latex'
+                match: '\\.\\/'
+            }
+            {
+                name: 'support.filepath.root.latex'
+                match: '(?<=\\{)\\/'
+            }
+            {
+                name: 'support.filepath.directory.latex'
+                match: '[^(\\.{1,2}\\/)].*?\\/'
+            }
+            {
+                name: 'support.filepath.file.latex'
+                match: '[^}]*'
+            }
+        ]
+    }


Contain begin when inside a group

Contain begin when inside a group

--- grammars/latex.cson
+++ grammars/latex.cson
@@ -854,7 +854,7 @@
         name: 'variable.parameter.optional.function.environment.latex'
         patterns: [{ include: '$self' }]
       9: name: 'punctuation.definition.arguments.optional.end.latex'
-    end: '((\\\\)end)(\\{)(\\4)(\\})'
+    end: '((\\\\)end)(\\{)(\\4)(\\})|(?=})'
     endCaptures:
       1: name: 'support.function.environment.end.latex'
       2: name: 'punctuation.definition.function.latex'
@@ -873,7 +873,7 @@
       3: name: 'punctuation.definition.arguments.begin.latex'
       4: name: 'variable.parameter.function.latex'
       5: name: 'punctuation.definition.arguments.end.latex'
-    end: '((\\\\)end)(\\{)(\\4)(\\})'
+    end: '((\\\\)end)(\\{)(\\4)(\\})|(?=})'
     endCaptures:
       1: name: 'support.function.environment.end.latex'
       2: name: 'punctuation.definition.function.latex'
@@ -908,7 +908,7 @@
         name: 'variable.parameter.optional.function.environment.latex'
         patterns: [{ include: '$self' }]
       9: name: 'punctuation.definition.arguments.optional.end.latex'
-    end: '((\\\\)end)(\\{)(\\4)(\\})'
+    end: '((\\\\)end)(\\{)(\\4)(\\})|(?=})'
     endCaptures:
       1: name: 'support.function.environment.end.latex'
       2: name: 'punctuation.definition.function.latex'
@@ -936,7 +936,7 @@
             name: 'variable.parameter.optional.function.environment.latex'
             patterns: [{ include: '$self' }]
           9: name: 'punctuation.definition.arguments.optional.end.latex'
-        end: '((\\\\)end)(\\{)(\\4)(\\})'
+        end: '((\\\\)end)(\\{)(\\4)(\\})|(?=})'
         endCaptures:
           1: name: 'support.function.environment.end.latex'
           2: name: 'punctuation.definition.function.latex'
@@ -965,7 +965,7 @@
               { include: '$self' }
             ] # This is amazing! It works!
           9: name: 'punctuation.definition.arguments.end.latex'
-        end: '((\\\\)end)(\\{)(\\4)(\\})'
+        end: '((\\\\)end)(\\{)(\\4)(\\})|(?=})'
         endCaptures:
           1: name: 'support.function.environment.end.latex'
           2: name: 'punctuation.definition.function.latex'
@@ -992,7 +992,7 @@
         name: 'variable.parameter.optional.function.environment.latex'
         patterns: [{ include: '$self' }]
       9: name: 'punctuation.definition.arguments.optional.end.latex'
-    end: '((\\\\)end)(\\{)(\\4)(\\})'
+    end: '((\\\\)end)(\\{)(\\4)(\\})|(?=})'
     endCaptures:
       1: name: 'support.function.environment.end.latex'
       2: name: 'punctuation.definition.function.latex'
@@ -1043,7 +1043,7 @@
         name: 'variable.parameter.optional.function.environment.latex'
         patterns: [{ include: '$self' }]
       9: name: 'punctuation.definition.arguments.optional.end.latex'
-    end: '((\\\\)end)(\\{)(\\4)(\\})'
+    end: '((\\\\)end)(\\{)(\\4)(\\})|(?=})'
     endCaptures:
       1: name: 'support.function.environment.end.latex'
       2: name: 'punctuation.definition.function.latex'
@@ -1124,7 +1124,7 @@
             (\\{)
             (\\4)
             (\\})
-            (?:\\s*)?
+            (?:\\s*)?|(?=})
          '''
     name: 'meta.function.environment.tabular.latex'
     patterns: [


put subsetting in repository

put subsetting in repository

--- grammars/stata.cson
+++ grammars/stata.cson
@@ -158,27 +158,7 @@
     'include': '#builtin_variables'
   }
   {
-    'comment': 'highlight [_n], etc when subsetting variable'
-    'begin': '[0-9a-zA-Z_]+(\\[)'
-    'beginCaptures':
-      '1':
-        'name': 'punctuation.definition.parameters.begin.stata'
-    'end': '(\\])'
-    'endCaptures':
-      '1':
-        'name': 'punctuation.definition.parameters.end.stata'
-    'name': 'meta.function.stata'
-    'patterns': [
-      {
-        'include': '#builtin_variables'
-      }
-      {
-        'include': '#operators'
-      }
-      {
-        'include': '#numbers'
-      }
-    ]
+    'include': '#subsetting'
   }
   {
     'match': '\\b(gl(o|ob|oba|obal)?)\\s+\\b([A-Za-z_][A-Za-z0-9_]{0,31})\\b'
@@ -633,6 +613,32 @@
           }
           {
             'include': '#macro-global'
+          }
+        ]
+      }
+    ]
+  'subsetting':
+    'patterns': [
+      {
+        'comment': 'highlight [_n], etc when subsetting variable'
+        'begin': '(?<=[0-9a-zA-Z_])(\\[)'
+        'beginCaptures':
+          '1':
+            'name': 'punctuation.definition.parameters.begin.stata'
+        'end': '(\\])'
+        'endCaptures':
+          '1':
+            'name': 'punctuation.definition.parameters.end.stata'
+        'name': 'meta.function.stata'
+        'patterns': [
+          {
+            'include': '#builtin_variables'
+          }
+          {
+            'include': '#operators'
+          }
+          {
+            'include': '#numbers'
           }
         ]
       }


Fix IE 11 render issue with travel guide settings

--- src/views/route-settings.coffee
+++ src/views/route-settings.coffee
@@ -275,11 +275,13 @@
             event.preventDefault()
             type = $(event.target).closest('li').data 'type'
             p13n.toggleTransport type
+            @render()

         switchTransportDetails: (event, group) ->
             event.preventDefault()
             type = $(event.target).closest('li').data 'type'
             p13n.toggleTransportDetails group, type
+            @render()

     class RouteControllersView extends base.SMItemView
         template: 'route-controllers'


Update stylus task for production

Update stylus task for production

--- grunt/stylus.coffee
+++ grunt/stylus.coffee
@@ -9,4 +9,10 @@
       compress: false
       linenos: true
     files:
-      'build/debug/css/<%= package.name %>.css': 'stylus/app/**/*.styl'+      'build/debug/css/<%= package.name %>.css': 'stylus/app/**/*.styl'
+  production:
+    options:
+      compress: true
+      linenos: false
+    files:
+      'build/debug/css/<%= package.name %>.css': 'stylus/app/**/*.styl'


Remove uneeded require to url

Remove uneeded require to url

--- src/window-event-handler.coffee
+++ src/window-event-handler.coffee
@@ -5,7 +5,6 @@
 shell = require 'shell'
 {Subscriber} = require 'emissary'
 fs = require 'fs-plus'
-url = require 'url'

 # Handles low-level events related to the window.
 module.exports =


Fix integration tests

Fix integration tests

--- src/window-event-handler.coffee
+++ src/window-event-handler.coffee
@@ -5,6 +5,7 @@
 shell = require 'shell'
 {Subscriber} = require 'emissary'
 fs = require 'fs-plus'
+url = require 'url'

 # Handles low-level events related to the window.
 module.exports =
@@ -28,7 +29,8 @@
               else
                 atom.project.addPath(pathToOpen)

-            if fs.isFileSync(pathToOpen)
+            {protocol} = url.parse(pathToOpen)
+            unless fs.isDirectorySync(pathToOpen) or protocol?
               atom.workspace?.open(pathToOpen, {initialLine, initialColumn})

           return


children of inputcell are static

children of inputcell are static

--- src/notebook.coffee
+++ src/notebook.coffee
@@ -172,10 +172,10 @@
       displayName: 'InputCellComponent'
       render: ->
         # TODO handle hiding
-        React.DOM.div {className: 'cell input', 'data-cell-number': @props.cell.number}, [
-          React.DOM.span {className: 'permalink', onClick: @permalink_link_clicked}, 'link'
-          React.DOM.div {className: 'code', ref: 'code'}
-        ]
+        React.DOM.div {className: 'cell input', 'data-cell-number': @props.cell.number},
+          React.DOM.span({className: 'permalink', onClick: @permalink_link_clicked}, 'link'),
+          React.DOM.div({className: 'code', ref: 'code'})
+
       componentDidMount: ->
         editor = @props.cell.editor
         @refs.code.getDOMNode().appendChild editor.display.wrapper


protocol: Better debug output on connection/IIP

--- src/protocol.coffee
+++ src/protocol.coffee
@@ -24,8 +24,8 @@
       metadata: process.metadata
       graph: graphId
   for connection in graph.connections
-    debug 'connecting edge', connection
     if connection.src?
+      debug 'connecting edge', connection
       runtime.sendGraph 'addedge',
         src:
           node: connection.src.process
@@ -37,6 +37,7 @@
         graph: graphId
     else
       iip = connection
+      debug 'adding IIP', iip
       runtime.sendGraph 'addinitial',
         src:
           data: iip.data


Use truly global require(), allow passing model class directly in

--- src/relation.coffee
+++ src/relation.coffee
@@ -111,8 +111,10 @@
      .toLowerCase()

 requireModel = (model) ->
-  requireFn = @require or ((value) -> eval(value))
-  requireFn(model)
+  if typeof model is 'string'
+    require?(model) or eval(model)
+  else
+    model

 association = (name, model, record, fkey, Ctor) ->
   model = requireModel(model) if typeof model is 'string'


Don't blow up with empty bodies

Don't blow up with empty bodies

--- src/site_mapper/http_source.coffee
+++ src/site_mapper/http_source.coffee
@@ -7,7 +7,7 @@
   url.split('/')[0]

 defaultBodyProcessor = (body) ->
-  body.split("\n")
+  if body? then body.split("\n") else []

 module.exports = class HttpSource extends Source
   constructor: (options) ->


Update BaseView with backButtonMethod

Update BaseView with backButtonMethod

--- Framework/Views/BaseView.coffee
+++ Framework/Views/BaseView.coffee
@@ -17,7 +17,6 @@
     @controls = []

     @window = Ti.UI.createWindow(@settings)
-
     @window.addEventListener('focus', @focus)
     @window.addEventListener('close', @onClose)

@@ -34,6 +33,15 @@
       if @settings.style == 'brushedMetal'
        @settings.backgroundImage = '/Common/Framework/Images/Patterns/brushedMetal.png'
        #@settings.backgroundRepeat = true #NOTE: GJ: waiting for titanium retina bug to be fixed
+
+  applyBackButtonStyle: =>
+    if @window.getBackButtonTitle()?
+      button = root.app.create 'ImageButton', {
+        type: 'back'
+        text: 'Back'
+        onClick: => @close()
+      }
+      @window.setLeftNavButton(button.view)

   focus: (e) =>
     @onInit() if !@uiInitialised


always clear proxy server cache after 30s (not just for raw server)

--- src/smc-hub/proxy.coffee
+++ src/smc-hub/proxy.coffee
@@ -343,18 +343,17 @@
                     t = {host:host, port:port}
                     _target_cache[key] = t
                     cb(false, t, internal_url)
-                    if type == 'raw'
-                        # Set a ttl time bomb on this cache entry. The idea is to keep the cache not too big,
-                        # but also if a new user is granted permission to the project they didn't have, or the project server
-                        # is restarted, this should be reflected.  Since there are dozens (at least) of hubs,
-                        # and any could cause a project restart at any time, we just timeout this.
-                        # This helps enormously when there is a burst of requests.
-                        # Also if project restarts the raw port will change and we don't want to have
-                        # fix this via getting an error.
-
-                        # Also, if the project stops and starts, the host=ip address could change, so
-                        # we need to timeout so we see that...
-                        setTimeout((->delete _target_cache[key]), 30*1000)
+                    # Set a ttl time bomb on this cache entry. The idea is to keep the cache not too big,
+                    # but also if a new user is granted permission to the project they didn't have, or the project server
+                    # is restarted, this should be reflected.  Since there are dozens (at least) of hubs,
+                    # and any could cause a project restart at any time, we just timeout this.
+                    # This helps enormously when there is a burst of requests.
+                    # Also if project restarts the raw port will change and we don't want to have
+                    # fix this via getting an error.
+
+                    # Also, if the project stops and starts, the host=ip address could change, so
+                    # we need to timeout so we see that...
+                    setTimeout((->delete _target_cache[key]), 30*1000)
             )

     #proxy = http_proxy.createProxyServer(ws:true)


Update documentation to reflect functionality

--- src/smc-util/misc.coffee
+++ src/smc-util/misc.coffee
@@ -557,7 +557,7 @@
 # Expects the string to be delimited by commas or semicolons
 #   between multiple users
 #
-# Non-email strings are ones without an '@'
+# Non-email strings are ones without an '@' and will be split on whitespace
 #
 # Emails may be wrapped by angle brackets.
 #   ie. <name@email.com> is valid and understood as name@email.com
@@ -565,8 +565,11 @@
 # Emails must be legal as specified by RFC822
 #
 # returns an object with the queries in lowercase
-#    string_queries: ["firstname lastname"]
+# eg.
+# {
+#    string_queries: ["firstname", "lastname", "somestring"]
 #    email_queries: ["email@something.com", "justanemail@mail.com"]
+# }
 exports.parse_user_search = (query) ->
     queries = (q.trim().toLowerCase() for q in query.split(/,|;/))
     r = {string_queries:[], email_queries:[]}


fix bug in displaying name of student when they haven't joined yet (it should show email)

--- src/smc-webapp/course/store.coffee
+++ src/smc-webapp/course/store.coffee
@@ -97,14 +97,14 @@
             full_name = last_name
         else
             full_name = email ? 'student'
-        if not include_email
-            return full_name
         if include_email and full_name? and email?
             full = full_name + " <#{email}>"
         else
             full = full_name
         if full_name == 'Unknown User' and email?
             full_name = email
+        if not include_email
+            return full_name
         return {simple:full_name.replace(/\W/g, ' '), full:full}

     get_student_email: (student) =>


Tiny typo

Tiny typo

--- desktop/components/json_page/client/editor.coffee
+++ desktop/components/json_page/client/editor.coffee
@@ -103,7 +103,7 @@
   # Unfortunately Hulk.js doesn't provide this functionality or the ability to
   # re-render based on data manipulations so we have to jump through hoops to
   # associate the DOM to `@data` and update the ordering for both.
-  # We could porbably avoid this classic problem with a React based solution:
+  # We could probably avoid this classic problem with a React based solution:
   # https://github.com/arqex/react-json
   #
   addSortingArrows: ->


Fix debug prefix in log handler

Fix debug prefix in log handler

--- handlers/log.coffee
+++ handlers/log.coffee
@@ -16,7 +16,7 @@
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 ###

-debug = (require 'debug')('Chatbot:log')
+debug = (require 'debug')('Chatbot:handlers:log')

 handleMessage = (message, callback) ->
 	debug "[#{message.username}] #{message.message}"


[#441] Add more commands to the Packages menu

--- menus/git-plus.cson
+++ menus/git-plus.cson
@@ -48,80 +48,88 @@
         {
           'label': 'Add'
           'command': 'git-plus:add'
-        }
+        },
         {
           'label': 'Add Modified'
           'command': 'git-plus:add-modified'
-        }
+        },
         {
           'label': 'Add All'
           'command': 'git-plus:add-all'
-        }
+        },
+        {
+          'label': 'Checkout Current File'
+          'command': 'git-plus:checkout-current-file'
+        },
         {
           'label': 'Commit'
           'command': 'git-plus:commit'
-        }
+        },
         {
           'label': 'Diff'
           'command': 'git-plus:diff'
-        }
+        },
         {
           'label': 'Difftool'
           'command': 'git-plus:difftool'
-        }
+        },
         {
           'label': 'Diff All'
           'command': 'git-plus:diff-all'
-        }
+        },
         {
           'label': 'Add + Commit'
           'command': 'git-plus:add-and-commit'
-        }
+        },
         {
           'label': 'Add + Commit + Push'
           'command': 'git-plus:add-and-commit-and-push'
-        }
+        },
         {
           'label': 'Add All + Commit'
           'command': 'git-plus:add-all-and-commit'
-        }
+        },
         {
           'label': 'Add All + Commit + Push'
           'command': 'git-plus:add-all-commit-and-push'
-        }
+        },
         {
           'label': 'Push'
           'command': 'git-plus:push'
-        }
+        },
         {
           'label': 'Log'
           'command': 'git-plus:log'
-        }
+        },
         {
           'label': 'Merge'
           'submenu': [
             {
               'label': 'Normal Merge'
               'command': 'git-plus:merge'
-            }
+            },
             {
               'label': 'Merge Remote'
               'command': 'git-plus:merge-remote'
-            }
+            },
             {
               'label': 'Merge without fast-forward'
               'command': 'git-plus:merge-no-fast-forward'
             }
           ]
-        }
+        },
         {
           'label': 'Pull Using Rebase'
           'command': 'git-plus:pull-using-rebase'
-        }
+        },
         {
           'label': 'Rebase'
           'command': 'git-plus:rebase'
-        }
+        },
+        {
+          'label': 'Run'
+          'command': 'git-plus:run'
+        },
       ]
     ]
   }


removed seconds from worklogs

removed seconds from worklogs

--- app/assets/javascripts/angular/worklogs/worklog.js.coffee
+++ app/assets/javascripts/angular/worklogs/worklog.js.coffee
@@ -41,16 +41,22 @@
         last_started = _.last(@timeframes).started
         if last_started
           t.started = new Date(last_started)
+          t.started.setSeconds(0,0)
         else
           t.started = new Date
+          t.started.setSeconds(0,0)
         last_ended = _.last(@timeframes).ended
         if last_ended
           t.ended = new Date(last_ended)
+          t.ended.setSeconds(0,0)
         else
           t.ended = new Date
+          t.ended.setSeconds(0,0)
       else
         t.started = new Date
         t.ended = new Date
+        t.started.setSeconds(0,0)
+        t.ended.setSeconds(0,0)
       @addNewTimeframe t

     calcTotal: ->


ajustado o nome do método inclusion, agora com In

--- app/assets/javascripts/jqvr/built_in_validators.js.coffee
+++ app/assets/javascripts/jqvr/built_in_validators.js.coffee
@@ -18,7 +18,7 @@
       true
   )
   # inclusion
-  jQuery.validator.addMethod("inclusion", (value,element,params) ->
+  jQuery.validator.addMethod("inclusionIn", (value,element,params) ->
     if value isnt ""
       jQuery.inArray(value,params) isnt -1
     else


Fix status bar

Fix status bar

--- app/assets/javascripts/neighborly/projects/show.js.coffee
+++ app/assets/javascripts/neighborly/projects/show.js.coffee
@@ -10,12 +10,10 @@
       'click .scroll-to-top': 'scrollTop'

     initialize: ->
-      #$tabs = new Neighborly.Tabs()
-      #$rewards = new Neighborly.Rewards.Index()
       this.statusBar()

     statusBar: ->
-      offset = $('.status-bar').offset().top
+      offset = this.$('.status-bar').offset().top
       $(window).scroll ->
         if $(document).scrollTop() > offset
           this.$('.status-bar').addClass('fixed')


Ensure subject set lists are sorted by display name

--- app/pages/lab/workflow.cjsx
+++ app/pages/lab/workflow.cjsx
@@ -312,8 +312,8 @@

   renderSubjectSets: ->
     projectAndWorkflowSubjectSets = Promise.all [
-      @props.project.get 'subject_sets'
-      @props.workflow.get 'subject_sets'
+      @props.project.get 'subject_sets', sort:"display_name"
+      @props.workflow.get 'subject_sets', sort:"display_name"
     ]

     <PromiseRenderer promise={projectAndWorkflowSubjectSets}>{([projectSubjectSets, workflowSubjectSets]) =>


autoRender views by default

autoRender views by default

--- src/tb/views/base.coffee
+++ src/tb/views/base.coffee
@@ -2,4 +2,6 @@

 module.exports = class BaseView extends Chaplin.View

+  autoRender: true
+
   getTemplateFunction: -> @template


Use astrifex.svg-star instead of md5.svg-star

--- src/modules/app/index.coffee
+++ src/modules/app/index.coffee
@@ -2,7 +2,7 @@

 module.exports = angular.module('astrifex', [
   'ui.router'
-  'md5.svg-star'
+  'astrifex.svg-star'
   require('../../../tmp/templates').name
   require('../common/index').name
   require('./maker/index').name


adds "awesome print" function

adds "awesome print" function

--- support/spec_helpers.coffee
+++ support/spec_helpers.coffee
@@ -57,3 +57,5 @@
   )

+window.AP = (object)->
+  "#{object.constructor.name}(#{jasmine.pp object})"


Add log persistency param

Add log persistency param

--- app/src/utils/logger.coffee
+++ app/src/utils/logger.coffee
@@ -54,7 +54,9 @@

   # Set all loggers level
   @_setGlobalLoggersLevel: (level) -> logger.setLevel(level) for name, logger of @_loggers when logger.useGlobalSettings
-
+  @setGlobalLoggersLevel: (level) -> @_setGlobalLoggersLevel(level)
+
+  @setGlobalLoggersPersistentLogsEnabled: (enable) -> logger.setPersistentsLogsEnabled(enable) for name, logger of @_loggers when logger.useGlobalSettings

   @getGlobalLoggersLevel: ->
     if ledger.preferences?.instance?
@@ -126,7 +128,10 @@
     @level = Levels[@level] if typeof @level == "string"
     @level = Levels.ALL if @level is true
     @level = Levels.NONE if @level is false
+    @setPersistentsLogsEnabled on
     @constructor._loggers[tag] = this
+
+  setPersistentLogsEnabled: (enable) -> @_areLogsPersistents = enable

   #################################
   # Accessors
@@ -212,6 +217,7 @@
   # @param [String] msg Message to log.
   # @param [String] msgType Log level.
   _storeLog: (msg, msgType) ->
+    return unless @_areLogsPersistents
     now = new Date()
     log = {}
     log[now.getTime()] = date: now.toUTCString(), type: msgType,  tag: @_tag, msg: msg


Added missing build queue locator

Added missing build queue locator

--- src/teamcity.coffee
+++ src/teamcity.coffee
@@ -4,6 +4,7 @@
 ChangesLocator = require './locators/changes-locator'
 BuildLocator = require './locators/build-locator'
 BuildTypeLocator = require './locators/build-type-locator'
+BuildQueueLocator = require './locators/build-queue-locator'

 class TeamCity
   constructor: (options) ->
@@ -52,6 +53,9 @@

   buildTypeLocator: ->
     return new BuildTypeLocator
+
+  buildQueueLocator: ->
+    return new BuildQueueLocator

   # URL Helpers


fix schema loading

fix schema loading

--- src/textorum/tinymce/plugin.coffee
+++ src/textorum/tinymce/plugin.coffee
@@ -31,7 +31,7 @@
   window.textorum ||= {}
   originalDTD = {}

-  schema = {
+  window.textorum.schema ||= {
     containedBy: {},
     defs: {}
   }
@@ -39,22 +39,28 @@

   $ = window.jQuery

-  schemaprocessor = new XSLTProcessor()
-  schemaStylesheet = helper.getXML "xsl/rng2js.xsl"
-  schemaprocessor.importStylesheet(schemaStylesheet)
-  schema = helper.getXML "test/rng/kipling-jp3-xsl.srng"
-  xsltschema = schemaprocessor.transformToDocument(schema)
-  schema = ($.parseJSON || tinymce.util.JSON.parse)(xsltschema.documentElement.innerText)
-  schema.containedBy ||= {}
-  schema.defs ||= {}
-  schema.$root ||= []
-  for element, details of schema.defs
-    elementContains = {}
-    for own containedElement, v of details.contains
-      schema.containedBy[containedElement] ||= {}
-      schema.containedBy[containedElement][element] = 1
-  window.textorum.schema = schema
+  _getSchema = ->
+    schemaprocessor = new XSLTProcessor()
+    schemaStylesheet = helper.getXML "xsl/rng2js.xsl"
+    schemaprocessor.importStylesheet(schemaStylesheet)
+    xmlschema = helper.getXML "test/rng/kipling-jp3-xsl.srng"
+    xsltschema = schemaprocessor.transformToDocument(xmlschema)
+    schemadoc = xsltschema.documentElement
+    schematext = (schemadoc.text || schemadoc.textContent || schemadoc.innerHTML)
+    schema = ($.parseJSON || tinymce.util.JSON.parse)(schematext)
+    schema ||= {}
+    schema.containedBy ||= {}
+    schema.defs ||= {}
+    schema.$root ||= []
+    for element, details of schema.defs
+      elementContains = {}
+      for own containedElement, v of details.contains
+        schema.containedBy[containedElement] ||= {}
+        schema.containedBy[containedElement][element] = 1
+    window.textorum.schema = schema

+  _getSchema()
+
   tinymce.create 'tinymce.plugins.textorum.loader', {
     init: (editor, url) =>
       console.log "editor", editor


Remove unnecessary (and error prone) regex-based HTML whitespace removal

--- src/trix/models/html_parser.coffee
+++ src/trix/models/html_parser.coffee
@@ -232,7 +232,6 @@
     JSON.parse(element.dataset.trixAttachment)

   sanitizeHTML = (html) ->
-    html = removeInsignificantWhitespace(html)
     doc = document.implementation.createHTMLDocument("")
     doc.documentElement.innerHTML = html
     {body, head} = doc
@@ -262,11 +261,6 @@

     body.innerHTML

-  removeInsignificantWhitespace = (html) ->
-    html
-      .replace(/>\n+</g, "><")
-      .replace(/>\ +</g, "> <")
-
   convertNewlinesToSpaces = (string) ->
     string.replace(/\s?\n\s?/g, " ")


Add SlugUrl virtual attribute

Add SlugUrl virtual attribute

--- models/badge.coffee
+++ models/badge.coffee
@@ -16,19 +16,30 @@

 BadgeSchema = new Schema
   name:          String
-  image:         {type: String, get: fullImageUrl}
+  image:
+    type: String,
+    get: fullImageUrl
   description:   String
   criteria:      String
   version:       String
   issuer_id:     Schema.ObjectId
-  issued_count:  { type: Number, default: 0}
-  slug :         String
+  issued_count:
+    type: Number,
+    default: 0
+  slug :
+    type: String,
+    unique: true
+  tags: [String]
+
+
+BadgeSchema.virtual('slugUrl').get ->
+  "http://#{process.env.HOST}/badges/issue/#{@slug}"

 BadgeSchema.pre 'save', (next)->
   if @criteria?
-    @criteria = markdown.parse(@criteria, markdown.flags.autolink)
+    @criteria = markdown.parse(@criteria, markdown.flags.autolink)
   if @description?
-    @description = markdown.parse(@description, markdown.flags.autolink)
+    @description = markdown.parse(@description, markdown.flags.autolink)
   next()

 findAvailableSlug = (slug, object, callback) ->


Fix spectra tool to erase sorry message

Fix spectra tool to erase sorry message

--- src/ubret/spectra.coffee
+++ src/ubret/spectra.coffee
@@ -45,6 +45,7 @@
     d3.extent @spectra.flux

   drawSorry: =>
+    @svg.selectAll('g.sorry').remove()
     @svg.append('g').attr('class', 'sorry')
       .append('text')
       .attr('text-anchor', 'middle')


Add font size options to Windows/Linux

Add font size options to Windows/Linux

--- src/ui/views/menu.coffee
+++ src/ui/views/menu.coffee
@@ -232,6 +232,37 @@
             enabled: viewstate.loggedin
             click: (it) -> action 'showconvlast', it.checked
         }, {
+            label: 'Font Size'
+            submenu: [
+                {
+                    label: 'Extra Small'
+                    type: 'radio'
+                    checked: viewstate.fontSize == 'x-small'
+                    click: -> action 'changefontsize', 'x-small'
+                }, {
+                    label: 'Small'
+                    type: 'radio'
+                    checked: viewstate.fontSize == 'small'
+                    click: -> action 'changefontsize', 'small'
+                }, {
+                    label: 'Medium'
+                    type: 'radio'
+                    checked: viewstate.fontSize == 'medium'
+                    click: -> action 'changefontsize', 'medium'
+                }, {
+                    label: 'Large'
+                    type: 'radio'
+                    checked: viewstate.fontSize == 'large'
+                    click: -> action 'changefontsize', 'large'
+                }, {
+                    label: 'Extra Large'
+                    type: 'radio'
+                    checked: viewstate.fontSize == 'x-large'
+                    click: -> action 'changefontsize', 'x-large'
+                }
+            ]
+
+        }, {
             label: 'Toggle Full Screen',
             accelerator: 'Control+Alt+F',
             click: -> action 'togglefullscreen'


fixing typo in javascript driver comment

--- drivers/javascript/protobuf.coffee
+++ drivers/javascript/protobuf.coffee
@@ -74,7 +74,7 @@
     # This case not covered in map, execute default case
     return dflt()

-# Swith on the datum type field of datum
+# Switch on the datum type field of datum
 module.exports.DatumTypeSwitch = (datum, map, dflt) ->
     type = datum.type
     if typeof type is 'string'


search by name or version

search by name or version

--- imports/ui/pages/meteor/AppsPage.coffee
+++ imports/ui/pages/meteor/AppsPage.coffee
@@ -12,13 +12,18 @@
   appSearchValue = App.state.appSearchValue()

   searchObj = {}
-  if appSearchValue then searchObj = name: {$regex: appSearchValue, $options: 'i'}
+  if appSearchValue then searchObj =
+    $or: [
+      name: {$regex: appSearchValue, $options: 'i'}
+    ,
+      version: {$regex: appSearchValue, $options: 'i'}
+    ]

-  appNames: Apps.find(searchObj, sort: name: 1, version: 1).fetch()
+  apps: Apps.find(searchObj, sort: name: 1, version: 1).fetch()
   appTags: (Apps.find({name:selectedAppName}, sort: version: 1).fetch().map (app) -> app.version)
   selectedAppName: selectedAppName
   appSearchValue: appSearchValue
-  appNameSelected: (name) -> App.emit 'app name selected', name
-  appsSearchEntered: (value) -> App.emit 'app search entered', value
+  onAppNameSelected: (name) -> App.emit 'app name selected', name
+  onAppSearchEntered: (value) -> App.emit 'app search entered', value

 , require '../AppsPage.cjsx'


activity/flux: remove unnecessary fat arrow

--- client/app/lib/flux/reactor.coffee
+++ client/app/lib/flux/reactor.coffee
@@ -11,7 +11,7 @@
   ###
   registerStores: (storeClasses) ->

-    stores = _.mapValues storeClasses, (StoreClass) => new StoreClass
+    stores = _.mapValues storeClasses, (StoreClass) -> new StoreClass

     # we injected reactor instance to our stores,
     # leave the rest to Nuclear.


Make glob matches that start with / match from project root.

--- src/utils/helpers.coffee
+++ src/utils/helpers.coffee
@@ -70,6 +70,7 @@
             glob.sync pattern,
                 dot: true
                 cwd: basePath
+                root: basePath
             .forEach (file) ->
                 if relativeFilename is path.normalize file
                     excluded = true


client: fix wording

client: fix wording

--- client/admin/lib/views/koding-admin/teaminviteview.coffee
+++ client/admin/lib/views/koding-admin/teaminviteview.coffee
@@ -68,7 +68,7 @@
   sendInvites: ->

     remote.api.JTeamInvitation.sendInvitationEmails @emails, (err, invitations) =>
-      message = if err then 'Please retry' else 'Invitations sent!'
+      message = if err then 'Please try again' else 'Invitations sent!'
       new kd.NotificationView
         title: message


suppr with messageListToolbar : Select Previous or Next Message

--- client/app/components/toolbar_messageslist_actions.coffee
+++ client/app/components/toolbar_messageslist_actions.coffee
@@ -3,6 +3,8 @@

 ToolboxActions = require './toolbox_actions'
 ToolboxMove    = require './toolbox_move'
+
+MessageStore = require '../stores/message_store'

 LayoutActionCreator  = require '../actions/layout_action_creator'
 MessageActionCreator = require '../actions/message_action_creator'
@@ -84,15 +86,26 @@
         return unless options = @_getSelectedAndMode applyToConversation

         doDelete = =>
-            MessageActionCreator.delete options, =>
-                if options.count > 0 and @props.messages.size > 0
-                    firstMessageID = @props.messages.first().get('id')
-                    MessageActionCreator.setCurrent firstMessageID, true
+            # Get next focus conversation
+            nextConversation = MessageStore.getPreviousConversation()
+            nextConversation = MessageStore.getNextConversation() unless nextConversation.size
+
+            MessageActionCreator.delete options

             @props.afterAction() if @props.afterAction?

-            # Close Detail Panel for deleted message
-            @redirect (url = @buildClosePanelUrl 'second')
+            unless nextConversation.size
+                # Close 2nd panel : no next conversation found
+                @redirect (url = @buildClosePanelUrl 'second')
+            else
+                # Goto to next conversation
+                @redirect
+                    direction: 'second',
+                    action: 'conversation',
+                    parameters:
+                        messageID: nextConversation.get('id')
+                        conversationID: nextConversation.get('conversationID')
+

         unless @props.settings.get 'messageConfirmDelete'
             doDelete()


API server additions for PPPs

API server additions for PPPs

--- node/server.coffee
+++ node/server.coffee
@@ -1,6 +1,6 @@
-#
+#
 # Fake gravity express app
-#
+#

 _ = require 'underscore'
 express = require 'express'
@@ -47,7 +47,7 @@
   ]

 gravity.get '/api/v1/fair/:id/shows', (req, res) ->
-  res.send results: [fabricate('show',
+  res.send results: [fabricate('show',
     fair: fabricate('fair')
     fair_location: { display: 'Dock 4' }
     artworks: [fabricate('artwork')]
@@ -68,12 +68,51 @@
     res.send fabricate 'profile',
       owner_type: 'PartnerGallery'
       owner: fabricate('partner', id: 'gagosian-gallery')
+  else if req.params.id is 'lacma'
+    res.send fabricate 'profile',
+      owner_type: 'PartnerMuseum'
+      owner: fabricate('partner', id: 'lacma')
   else
     res.send fabricate('profile', owner_type: 'User')

+gravity.get '/api/v1/partner/:id', (req, res) ->
+  if req.params.id is 'gagosian-gallery'
+    res.send fabricate('partner', {
+      id: 'gagosian-gallery'
+      default_profile_id: 'gagosian-gallery'
+      displayable_shows_count: 2
+      profile: fabricate('profile',
+        owner_type: 'PartnerGallery'
+        owner: fabricate('partner', id: 'gagosian-gallery')
+      )
+    })
+  else if req.params.id is 'lacma'
+    res.send fabricate('partner', {
+      id: 'lacma'
+      default_profile_id: 'lacma'
+      displayable_shows_count: 1
+      name: 'Los Angeles County Museum Of Art'
+      published_not_for_sale_artworks_count: 1
+      published_for_sale_artworks_count: 1
+      profile: fabricate('profile',
+        owner_type: 'PartnerMuseum'
+        owner: fabricate('partner', id: 'lacma')
+      )
+    })
+  else
+    res.send fabricate('partner')
+
+gravity.get '/api/v1/partner/:id/locations', (req, res) ->
+  return res.send [] if req.query.page > 2
+  res.send [fabricate('location'), fabricate('location')]
+
 gravity.get '/api/v1/partner/:id/shows', (req, res) ->
   return res.send [] if req.query.page > 2
-  res.send [fabricate('show', status: 'closed', featured: true), fabricate('show', status: 'running', featured: false)]
+  res.send [fabricate('show', status: 'closed', featured: true), fabricate('show', status: 'running', featured: false)]
+
+gravity.get '/api/v1/partner/:id/artworks', (req, res) ->
+  return res.send [] if req.query.page > 2
+  res.send [fabricate('artwork'), fabricate('artwork')]

 gravity.get '/api/v1/search/filtered/fair/:id/options', (req, res) ->
   res.send { medium: { Painting: 'painting' } }
@@ -93,4 +132,4 @@
 gravity.get '/api/v1/me', (req, res) ->
   res.send [fabricate 'user']

-gravity.all '*', (req, res) -> res.send 404, "Not Found."+gravity.all '*', (req, res) -> res.send 404, "Not Found."


actual working 404 profile route

actual working 404 profile route

--- node/server.coffee
+++ node/server.coffee
@@ -65,11 +65,10 @@
 gravity.get '/api/v1/set/:id/items', (req, res) ->
   res.send [fabricate('featured_link'), fabricate('featured_link')]

-gravity.get '/api/v1/profile/404', (req, res) ->
-  next(new Error('404 Profile not found'))
-
 gravity.get '/api/v1/profile/:id', (req, res) ->
-  if req.params.id is 'thearmoryshow'
+  if req.params.id is '404'
+    res.send 404, "Not Found."
+  else if req.params.id is 'thearmoryshow'
     res.send fabricate 'profile',
       owner_type: 'FairOrganizer'
       owner: { default_fair_id: 'the-armory-show' }


Use comma if its not JTag

Use comma if its not JTag

--- client/landing/app/CommonViews/linkviews/linkgroup.coffee
+++ client/landing/app/CommonViews/linkviews/linkgroup.coffee
@@ -55,9 +55,9 @@
       click       : =>
         new FollowedModalView {group}, @getData()

-    sep = ' '
-    if participants[0] instanceof bongo.api.JAccount
-      sep = ', '
+    sep = ', '
+    if participants[0] instanceof bongo.api.JTag
+      sep = ' '
     switch totalCount
       when 0 then ""
       when 1 then "{{> @participant0}}"


Workspace: Set raw options to workspace class.

--- client/landing/app/CommonViews/workspace/workspace.coffee
+++ client/landing/app/CommonViews/workspace/workspace.coffee
@@ -2,7 +2,12 @@

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

+    raw      = {}
+    raw[key] = value for own key, value of options
+
     super options, data
+
+    @rawOptions = raw

     @listenWindowResize()


Heartbeats are important

Heartbeats are important

--- src/serverjs/job_watcher.coffee
+++ src/serverjs/job_watcher.coffee
@@ -15,6 +15,9 @@
     @startIOServer()

   initFromFirebase: (callback) ->
+    firebase.WORKER_STATUS_REF.on 'child_changed', (snapshot) =>
+      for name, value of snapshot.val()
+        @clientMap[name] = value
     # keep it ALL in memory because reasons
     @clientMap = {}
     firebase.WORKER_STATUS_REF.once 'value', (snapshot) =>


Add checks for empty SST

Add checks for empty SST

--- src/shared_strings_table.coffee
+++ src/shared_strings_table.coffee
@@ -19,7 +19,7 @@
     @_.count = 0
     @_.uniqueCount = 0
     @_.strings = []
-    if xmlobj
+    if xmlobj && xmlobj.sst && xmlobj.sst.si
       @_.count = xmlobj.sst.$.count
       @_.uniqueCount = xmlobj.sst.$.uniqueCount
       for si in xmlobj.sst.si


Updating tests

Updating tests

--- test/hubot-mute_test.coffee
+++ test/hubot-mute_test.coffee
@@ -22,4 +22,4 @@
     expect(@robot.respond).to.have.been.calledWith(/(mute|unmute)$/i)

   it 'registers a catch all listener for ".*"', ->
-    expect(@robot.respond).to.have.been.calledWith(/(.*)$/i)
+    expect(@robot.hear).to.have.been.calledWith(/(.*)$/i)


Test/MyTeam fix coffeelint error

Test/MyTeam fix coffeelint error

--- client/test/lib/teams/teams.coffee
+++ client/test/lib/teams/teams.coffee
@@ -42,27 +42,27 @@
     teamsHelpers.createTeam(browser, user, inviteLink)
     teamsHelpers.createTeam(browser, user, createLink, 'AlreadyRegisteredUserName')

-
+
   signInWithNotAllowedEmail: (browser) ->
     teamsHelpers.loginTeam browser, user, yes , 'NotAllowedEmail', ->
       browser.pause 1

-
+
   signInWithInvalidUsername: (browser) ->
     teamsHelpers.loginTeam browser, user, yes, 'InvalidUserName', ->
       browser.pause 1

-
+
   signInWithInvalidPassword: (browser) ->
     teamsHelpers.loginTeam browser, user, yes, 'InvalidPassword', ->
       browser.pause 1

-
+
   loginTeam: (browser) ->
     teamsHelpers.loginTeam browser, user, no, ->
       browser.pause 1

-
+
   seePreviouslyVisitedTeams: (browser) ->
     url = helpers.getUrl()
     teamsHelpers.loginTeam browser, user, no, '', ->


remember last search

remember last search

--- assets/js/craigslist.coffee
+++ assets/js/craigslist.coffee
@@ -44,12 +44,24 @@
     SearchFormView = Elbow.ItemView.extend(
       template: '#searchTmpl'

+      initialize: (opts) ->
+        @remember = window.localStorage?
+        try
+          localStorage.setItem 'test','test'
+          localStorage.removeItem 'test'
+
+          @params = JSON.parse localStorage.getItem("last_search")
+
+        catch e
+          @remember = false
+
       serializeData: () ->
         categories: JSON.parse categories
         regions: JSON.parse regions

       ui:
         searchForm: '#searchForm'
+        searchQuery: 'input[name="query"]'
         regionSelect: 'select[name="region"]'
         categorySelect: 'select[name="category"]'

@@ -58,16 +70,24 @@
         'click #searchBtn': 'doSearch'

       onDomRefresh: ->
-        @ui.regionSelect.select2(placeholder: "Region")
-        @ui.categorySelect.select2(placeholder: "Category")
+        if @params
+          @ui.searchQuery.val @params.query
+          @ui.regionSelect.val(@params?.region).select2()
+          @ui.categorySelect.val(@params?.category).select2()
+        else
+          @ui.regionSelect.select2()
+          @ui.categorySelect.select2()

       doSearch: (e) ->
         e.preventDefault()
-        params = @ui.searchForm.form2obj()
-        console.log "Form params",e, params
+        @params = @ui.searchForm.form2obj()
+        console.log "Form params",e, @params
+
+        if @remember
+          localStorage.setItem "last_search", JSON.stringify(@params)

         new Search(
-          params: params
+          params: @params
         ).fetch(
           prefill: true
           success: (collection, response, options) =>


Added updateChart function.

Added updateChart function.

--- assets/js/lightcurve.coffee
+++ assets/js/lightcurve.coffee
@@ -64,6 +64,15 @@
                     fill: 'red'
                     r: '2'

+        updateChart: (isPhaseChart) ->
+            xDomain = if isPhaseChart then [0, 1] else d3.extent @data, (d) -> d.jd
+            @xScale.domain xDomain
+            @svg.select('.x.axis')
+                .call(@xAxis)
+            @svg.selectAll('circle')
+                .attr
+                    cx: (d) => @xScale if isPhaseChart then d.phase else d.jd
+

     selector = '.lightcurve'
     epoch = +$('.catalog-data .epoch').text()


Better margins

Better margins

--- core/app/backbone/views/wheel/base_fact_wheel_view.coffee
+++ core/app/backbone/views/wheel/base_fact_wheel_view.coffee
@@ -177,6 +177,7 @@
       positioning:
         side: 'top'
         popover_className: 'translucent-dark-popover fact-wheel-tooltip'
+        margin: @maxStrokeWidth()/2 - 7
       selector: '.authority'
       tooltipViewFactory: => new Marionette.ItemView
         template: 'facts/fact_wheel_authority_tooltip'
@@ -190,6 +191,7 @@
       positioning:
         side: @_tooltipSideForPath(@opinionTypeRaphaels[name])
         popover_className: 'translucent-dark-popover fact-wheel-tooltip'
+        margin: @maxStrokeWidth()/2 - 3
       selector: selector
       tooltipViewFactory: => new TextView
         model: new Backbone.Model text: @options.opinionStyles[name].groupname + ": " + @model.get('opinion_types')[name].percentage + "%"


Fix issue 704

Fix issue 704

--- src/smc-webapp/editor_chat.cjsx
+++ src/smc-webapp/editor_chat.cjsx
@@ -65,7 +65,6 @@
             @setState(messages: messages)

     send_chat: (mesg) =>
-        mesg = misc_page.sanitize_html(mesg)
         if not @syncdb?
             # TODO: give an error or try again later?
             return
@@ -107,8 +106,7 @@
             is_equal: (a, b) => (a - 0) == (b - 0)
         @syncdb.save()

-    send_edit: (message, raw_new_content) =>
-        mesg = misc_page.sanitize_html(raw_new_content)
+    send_edit: (message, mesg) =>
         if not @syncdb?
             # TODO: give an error or try again later?
             return


load module dir

load module dir

--- main.coffee
+++ main.coffee
@@ -2,6 +2,10 @@
 Path = require 'path'

 module.exports = (robot) ->
+  path = Path.resolve __dirname, 'module'
+  Fs.exists path, (exists) ->
+    robot.loadFile path, file for file in Fs.readdirSync(path) if exists
+
   path = Path.resolve __dirname, 'scripts'
   Fs.exists path, (exists) ->
     robot.loadFile path, file for file in Fs.readdirSync(path) if exists


fixed uuid2 creation

fixed uuid2 creation

--- main.coffee
+++ main.coffee
@@ -83,10 +83,9 @@
       .digest('hex')[...24]
       .toUpperCase()

-    uuid2 = uuid1
-      .split ''
-      .splice 7, 1, ((parseInt(uuid1[7], 16) + 1) % 16).toString(16).toUpperCase()
-      .join ''
+    uuid2 = uuid1.split ''
+    uuid2.splice 7, 1, ((parseInt(uuid1[7], 16) + 1) % 16).toString(16).toUpperCase()
+    uuid2 = uuid2.join ''

     editSync \
       "#{ projName }.xcodeproj/project.pbxproj",


Increase tolerance.

Increase tolerance.

--- test/performance-now.coffee
+++ test/performance-now.coffee
@@ -24,9 +24,9 @@
     earlier = now()
     Bluebird.resolve().delay(1).then -> assert.isAbove (now()-earlier), 0.2

-  it "shows that at most 2 ms has passed after a timeout of 1 ms", ->
+  it "shows that at most 3 ms has passed after a timeout of 1 ms", ->
     earlier = now()
-    Bluebird.resolve().delay(1).then -> assert.isBelow (now()-earlier), 2
+    Bluebird.resolve().delay(1).then -> assert.isBelow (now()-earlier), 3

   it "shows that at least 190ms ms has passed after a timeout of 200ms", ->
     earlier = now()


more and better love.window methods

more and better love.window methods

--- coffeescript/love.js/window.coffee
+++ coffeescript/love.js/window.coffee
@@ -1,15 +1,20 @@
 class Love.Window
   constructor: (@graphics) ->
+    @fullscreen = false

-  getDesktopDimensions: () =>
+  getDesktopDimensions: =>
+    [window.screen.width, window.screen.height]

-  getDimensions: () =>
+  getDimensions: =>
+    [@getWidth(), @getHeight()]

   getDisplayCount: () =>

-  getFullscreen: () =>
+  getFullscreen: =>
+    @fullscreen

   getFullscreenModes: () =>
+    []

   getHeight: =>
     @graphics.getHeight()
@@ -18,14 +23,17 @@

   getMode: () =>

-  getPixelScale: () =>
+  getPixelScale: =>
+    window.devicePixelRatio

-  getTitle: () =>
+  getTitle: =>
+    window.document.title

   getWidth: =>
     @graphics.getWidth()

-  hasFocus: () =>
+  hasFocus: =>
+    document.activeElement == Love.element

   hasMouseFocus: () =>

@@ -33,12 +41,15 @@

   isVisible: () =>

-  setFullscreen: () =>
+  setFullscreen: (@fullscreen) =>
+    @fullscreen = false

   setIcon: () =>

   setMode: (width, height, flags) =>
     @graphics.default_canvas.setDimensions(width, height)

-  setTitle: () =>
+  setTitle: (title) =>
+    window.document.title = title

+


Make asar work with internalModuleReadFile and internalModuleStat

--- atom/common/lib/asar.coffee
+++ atom/common/lib/asar.coffee
@@ -310,6 +310,38 @@

     files

+  internalModuleReadFile = process.binding('fs').internalModuleReadFile
+  process.binding('fs').internalModuleReadFile = (p) ->
+    [isAsar, asarPath, filePath] = splitPath p
+    return internalModuleReadFile p unless isAsar
+
+    archive = getOrCreateArchive asarPath
+    return undefined unless archive
+
+    info = archive.getFileInfo filePath
+    return undefined unless info
+    return '' if info.size is 0
+
+    buffer = new Buffer(info.size)
+    fd = archive.getFd()
+    retrun undefined unless fd >= 0
+
+    fs.readSync fd, buffer, 0, info.size, info.offset
+    buffer.toString 'utf8'
+
+  internalModuleStat = process.binding('fs').internalModuleStat
+  process.binding('fs').internalModuleStat = (p) ->
+    [isAsar, asarPath, filePath] = splitPath p
+    return internalModuleStat p unless isAsar
+
+    archive = getOrCreateArchive asarPath
+    return -34 unless archive  # -ENOENT
+
+    stats = archive.stat filePath
+    return -34 unless stats  # -ENOENT
+
+    if stats.isDirectory then return 1 else return 0
+
   overrideAPI fs, 'open'
   overrideAPI child_process, 'execFile'
   overrideAPISync process, 'dlopen', 1


Refine image getting logic

Refine image getting logic

--- src/scripts/hubot-zoi.coffee
+++ src/scripts/hubot-zoi.coffee
@@ -25,7 +25,7 @@
     if err
       cb.onError(err)
     else
-      zois = body.match(/image: 'https:\/\/pbs.twimg.com\/media\/.+.jpg:large'/mg).
+      zois = body.match(/image: ['"]?https?:\/\/.+.(jpg|png|gif).*["']?/mg).
                   map((l) -> l.match("'(https.+\.jpg):large'")[1])
       (cb.onZoi || cb.onSuccess)(zois)
   )


Guard upstream against empty configurations

--- components/split_test/index.coffee
+++ components/split_test/index.coffee
@@ -2,4 +2,6 @@
 SplitTest = require './split_test.coffee'

 module.exports = (key) ->
-  new SplitTest runningTests[key]
+  return unless (config = runningTests[key])?
+
+  new SplitTest config


Debugging the redis config

Debugging the redis config

--- config/initializers/pub_sub.coffee
+++ config/initializers/pub_sub.coffee
@@ -1,5 +1,7 @@
 _ = require 'underscore'
 redback = require 'redback'
+
+console.log Caboose.app.config.redis

 Caboose.app.channels = {
   command: redback.createClient(Caboose.app.config.redis).createChannel('commands')


Code layout improvement.

Code layout improvement.

--- app/assets/javascripts/app/controllers/agent_ticket_create.js.coffee
+++ app/assets/javascripts/app/controllers/agent_ticket_create.js.coffee
@@ -191,7 +191,7 @@
       @formValidate( form: e.target, errors: errors )

     # save ticket, create article
-    else
+    else

       # disable form
       @formDisable(e)
@@ -208,7 +208,7 @@

           # create new create screen
           ui.render()
-
+
           # scroll to top
           ui.scrollTo()


final fix for #1240

final fix for #1240

--- jsapp/xlform_model_view/view.row.templates.coffee
+++ jsapp/xlform_model_view/view.row.templates.coffee
@@ -90,7 +90,7 @@

   selectQuestionExpansion = ->
     """
-

+


Removed irrelevant reference to three.js.

--- testbed/app/scripts/main.coffee
+++ testbed/app/scripts/main.coffee
@@ -2,13 +2,12 @@
   paths:
     'jquery': '../vendor/jquery/dist/jquery.min'
     'd3': '../vendor/d3/d3'
-    'threejs': '../vendor/threejs/build/three'
     'topojson': '../vendor/topojson/topojson'
     'underscore': '../vendor/underscore/underscore'
   shim:
     'd3': exports: 'd3'

-requirejs( ['d3', 'threejs', 'topojson', 'underscore'], (d3, threejs, topojson, _) ->
+requirejs( ['d3', 'topojson', 'underscore'], (d3, topojson, _) ->

   makeId = (str) ->
     str.replace(/[!\"\s#$%&'\(\)\*\+,\.\/:;<=>\?\@\[\\\]\^`\{\|\}~]/g, '')


privatemessage: fetch bot channel within BotMessagePane

--- client/activity/lib/views/privatemessage/kodingbotmessagepane.coffee
+++ client/activity/lib/views/privatemessage/kodingbotmessagepane.coffee
@@ -5,11 +5,12 @@

 module.exports = class KodingBotMessagePane extends PrivateMessagePane

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

+    botChannel = kd.singletons.socialapi.getPrefetchedData 'bot'
     options.cssClass = kd.utils.curry 'privatemessage', options.cssClass

-    super options, data
+    super options, botChannel

     @listController.getListView().setClass 'kdlistview-privatemessage'
     @actionsMenu?.destroy()


webterm error handling

webterm error handling

--- client/landing/app/Applications/WebTerm.kdapplication/AppView.coffee
+++ client/landing/app/Applications/WebTerm.kdapplication/AppView.coffee
@@ -126,10 +126,13 @@
         sizeX  : @terminal.sizeX
         sizeY  : @terminal.sizeY
     , (err, remote) =>
-      @terminal.server = remote
-      remote.setSize @terminal.sizeX, @terminal.sizeY # might have changed in the meantime
-      @setKeyView()
-      @emit "WebTermConnected", remote
+      if err
+        log err
+      else
+        @terminal.server = remote
+        remote.setSize @terminal.sizeX, @terminal.sizeY # might have changed in the meantime
+        @setKeyView()
+        @emit "WebTermConnected", remote

   destroy: ->
     super


Modified in browser at pixie.strd6.com

Modified in browser at pixie.strd6.com

--- src/string_extensions.coffee
+++ src/string_extensions.coffee
@@ -73,7 +73,7 @@
 ###*
 Get the file extension of a string.

-    "README.md".extension()
+    "README.md".extension() # =>

 @name extension
 @methodOf String#


Don't error if poshytip is undefined

Don't error if poshytip is undefined

Useful for experimenting with other web UIs


Cleanup

Cleanup

--- framer/BaseClass.coffee
+++ framer/BaseClass.coffee
@@ -65,7 +65,7 @@
 		get: -> @_id

 	toString: =>
-		properties = _.map(@[DefinedPropertiesValuesKey], ((v, k) -> "#{k}:#{v}"), 4)
+		properties = _.map(@properties, ((v, k) -> "#{k}:#{v}"), 4)
 		"[#{@constructor.name} id:#{@id} #{properties.join " "}]"


Setting text on initialization instead of html

--- framer/TextLayer.coffee
+++ framer/TextLayer.coffee
@@ -41,7 +41,7 @@

 		_.defaults options, options.textStyle,
 			backgroundColor: "transparent"
-			html: "Hello World"
+			text: "Hello World"
 			color: "#888"
 			fontSize: 40
 			fontWeight: 400


EDSC-304: Redraw temporal bounds after zooming

--- app/assets/javascripts/modules/timeline/timeline.coffee
+++ app/assets/javascripts/modules/timeline/timeline.coffee
@@ -341,6 +341,7 @@

       @focus()
       @_updateTimeline()
+      @_drawTemporalBounds()
       #console.log 'zoom', @zoom, x, new Date(@start).toISOString(), new Date(@end).toISOString(), new Date(center_t).toISOString()

     focus: (t0, t1) ->


fix uploadcare.whenReady()

fix uploadcare.whenReady()

--- app/assets/javascripts/uploadcare/core/jquery.js.coffee
+++ app/assets/javascripts/uploadcare/core/jquery.js.coffee
@@ -3,15 +3,12 @@
 namespace 'uploadcare', (ns) ->
   ns.__readyCallbacks = []

-  isReady = false
+  ns.whenReady = (callback) ->
+    ns.__readyCallbacks.push(callback)
+
   ns.ready = ->
-    isReady = true
     callback() for callback in ns.__readyCallbacks
-  ns.whenReady = (callback) ->
-    if isReady
-      callback()
-    else
-      ns.__readyCallbacks.push(callback)
+    ns.whenReady = (callback) -> callback()


enable multi-select for box select tool

enable multi-select for box select tool

--- bokehjs/src/coffee/tool/gestures/box_select_tool.coffee
+++ bokehjs/src/coffee/tool/gestures/box_select_tool.coffee
@@ -29,7 +29,8 @@
       @mget('overlay').set('data', {vxlim: vxlim, vylim: vylim})

       if @mget('select_every_mousemove')
-        @_select(vxlim, vylim, false)
+        append = e.srcEvent.shiftKey ? false
+        @_select(vxlim, vylim, false, append)

       return null

@@ -43,13 +44,14 @@
       dims = @mget('dimensions')

       [vxlim, vylim] = @model._get_dim_limits(@_baseboint, curpoint, frame, dims)
-      @_select(vxlim, vylim, true)
+      append = e.srcEvent.shiftKey ? false
+      @_select(vxlim, vylim, true, append)
       @mget('overlay').set('data', {})

       @_baseboint = null
       return null

-    _select: ([vx0, vx1], [vy0, vy1], final) ->
+    _select: ([vx0, vx1], [vy0, vy1], final, append=false) ->
       geometry = {
         type: 'rect'
         vx0: vx0
@@ -61,7 +63,7 @@
       for r in @mget('renderers')
         ds = r.get('data_source')
         sm = ds.get('selection_manager')
-        sm.select(@, @plot_view.renderers[r.id], geometry, final)
+        sm.select(@, @plot_view.renderers[r.id], geometry, final, append)

       return null


Tilt nu

Tilt nu

--- lib/bottom-dock/results-pane.coffee
+++ lib/bottom-dock/results-pane.coffee
@@ -146,7 +146,7 @@
         for query in @processedQueries
             if query.queryId == result.queryid
                 setTimeout( () =>
-                    unless query.marker.isDestroyed()
+                    unless query.marker.isDestroyed() or query.marker? == false
                         atom.workspace.getActiveTextEditor().decorateMarker(query.marker, type: 'line-number', class: 'query-rendering')
                 , 300)

@@ -169,7 +169,7 @@
                     classType = 'query-error'
                     timeout = 5000
                 marker = editor.markBufferRange(query.range, invalidate: 'overlap')
-                editor.decorateMarker(marker, type: 'line-number', class: classType)
+                editor.decorateMarker(marker, type: 'line-number', class: classType) if marker?

                 @setErrorMarker(result, query)

@@ -188,7 +188,7 @@
         queryInfo.marker = marker
         @processedQueries.push queryInfo

-        editor.decorateMarker(marker, type: 'line-number', class: 'query-loading')
+        editor.decorateMarker(marker, type: 'line-number', class: 'query-loading') if marker?
     escapeRegExp: (str) ->
         str = str.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&");
         return str.replace(/(?:\r\n|\r|\n)/g, '[\\r?\\n]');
@@ -221,7 +221,7 @@
         item = document.createElement('div')
         item.classList.add 'arrow_box'
         item.textContent = description
-        atom.workspace.getActiveTextEditor().decorateMarker(m, {type:'overlay', item}, position:'head')
+        atom.workspace.getActiveTextEditor().decorateMarker(m, {type:'overlay', item}, position:'head') if m?

         @errorMarkers.push(m)


fix injector tests

fix injector tests

--- tests/unit/injector.unit.coffee
+++ tests/unit/injector.unit.coffee
@@ -19,7 +19,7 @@
       expect(@injector.get('myObject').test).to.equal testValue

     it 'throws error if mapping doesnt exist', ->
-      expect(=> @injector.get('blablub')).to.throw Error
+      expect(=> @injector.get('blablub')).to.throw new Space.CouldNotResolvePathError()

     it 'auto-maps singletons', ->
       first = @injector.get 'Space.Injector'
@@ -31,7 +31,7 @@
       expect(@injector.get('Space')).to.equal Space

     it 'throws if the auto-map value is undefined', ->
-      expect(=> @injector.get('NotExistingValue')).to.throw Error
+      expect(=> @injector.get('NotExistingValue')).to.throw

     it 'throws error if mapping would be overriden', ->
       @injector.map('test').to 'test'
@@ -41,7 +41,7 @@
     it 'can remove existing mappings', ->
       @injector.map('test').to 'test'
       @injector.remove 'test'
-      expect(=> @injector.get 'test').to.throw Error
+      expect(=> @injector.get 'test').to.throw

     it 'provides an alias for getting values', ->
       @injector.map('test').to 'test'


Drop px units and spaces from size label

--- lib/image-editor-status-view.coffee
+++ lib/image-editor-status-view.coffee
@@ -23,7 +23,7 @@
   getImageSize: (view) ->
     imageWidth = view.originalWidth
     imageHeight = view.originalHeight
-    @imageSizeStatus.text("#{imageWidth}px x #{imageHeight}px").show()
+    @imageSizeStatus.text("#{imageWidth}x#{imageHeight}").show()

   updateImageSize: ->
     editor = atom.workspaceView.getActivePaneItem()


Workaround for command shortcuts that start with letter c

--- extension/packages/commands.coffee
+++ extension/packages/commands.coffee
@@ -395,7 +395,9 @@
     str = keys[index..].join(',')
     for command in commands
       for key in command.keys()
-        if key.startsWith(str)
+        # The following hack is a workaround for the issue where # letter `c`
+        # is considered a start of command with control modifier `c-xxx`
+        if "#{key},".startsWith("#{str},")
           return {match: true, exact: (key == str), command}

   return {match: false}


snap: randomize the time between snapshotting -- distributes them more uniformly, and also lengthen time (so less aggressive)

--- salvus/snap.coffee
+++ salvus/snap.coffee
@@ -1030,8 +1030,9 @@
                     cb(err)

     ], (err) ->
-        # wait 3 seconds, to ensure uniqueness of time stamp, not be too aggressive checking locks, etc.
-        setTimeout(monitor_snapshot_queue, 3000)
+        # wait random interval up to 15 seconds between snasphots, to ensure uniqueness of
+        # time stamp, not be too aggressive checking locks, etc.
+        setTimeout(monitor_snapshot_queue, misc.randint(3000,15000))
         if nothing_to_do
             err = undefined
         if not retry_later


redux-components-legacy: export legacy Object and ValueComponents

--- packages/redux-components-legacy/src/index.coffee
+++ packages/redux-components-legacy/src/index.coffee
@@ -3,6 +3,8 @@
 import { mountRootComponent, willMountComponent, didMountComponent, willUnmountComponent } from 'redux-components'
 import ReduxComponent from 'redux-components'
 import { createComponent, SubtreeMixin } from './subtree'
+import ObjectComponent from './ObjectComponent'
+import ValueComponent from './ValueComponent'

 DefaultMixin = {}
 ObservableSelectorMixin = {}
@@ -19,4 +21,6 @@
 	createComponent
 	SubtreeMixin
 	ObservableSelectorMixin
+	ObjectComponent
+	ValueComponent
 }


Slava ██ █ ███████ :boom:

Slava ██ █ ███████ :boom:

--- scripts/ayp.coffee
+++ scripts/ayp.coffee
@@ -102,7 +102,7 @@
   text = text.replace(/([^@\s]+@)[^@\s]+\.[^@\s]+/, "$1[redacted]")

   # Let users redact shit too
-  text = text.replace(/\[[^\]*]\]/, "[redacted]")
+  text = text.replace(/\[[^\]]*\]/, "[redacted]")

   # Twitter length, then truncate with `...`
   limit = 140


Remove the last YAPE test for browsers

Remove the last YAPE test for browsers

--- spec/GetFeaturesYAPE.coffee
+++ spec/GetFeaturesYAPE.coffee
@@ -34,6 +34,9 @@
     'noText/flickr-8132786781-small.jpg'
     'textRegion/3010029968_02742a1aec_b.jpg'
   ]
+
+  testcases.pop() if noflo.isBrowser()
+
   for testcase in testcases

       describe testcase, ->


fixes spec

fixes spec

--- spec/IntegrationSpec.coffee
+++ spec/IntegrationSpec.coffee
@@ -33,7 +33,7 @@
     @$(".epages-shop-product-name:contains(#{name})").length == 1

   productLink: (name) ->
-    @$(".epages-shop-product-name:contains(#{name})").parent().find("a")
+    @$("a .epages-shop-product-name:contains(#{name})")

 describe "Integration", ->


new spec added

new spec added

--- spec/atom-clock-spec.coffee
+++ spec/atom-clock-spec.coffee
@@ -49,3 +49,12 @@
       expect(atom.config.get('atom-clock.dateFormat')).toEqual 'H:mm'
       expect(atom.config.get('atom-clock.refreshInterval')).toEqual 60
       expect(atom.config.get('atom-clock.showClockIcon')).toEqual false
+
+    it 'should properly call watcher methods for configuration', ->
+      mainPkg = (atom.packages.getActivePackage 'atom-clock').mainModule
+
+      spyOn mainPkg.atomClockView, 'refreshTicker'
+      # console.log mainPkg.atomClockView.refreshTicker()
+
+      atom.config.set 'atom-clock.refreshInterval', 10
+      expect(mainPkg.atomClockView.refreshTicker).toHaveBeenCalled()


Fix self closing div tags in knockout tests.

--- test-src/knockout.coffee
+++ test-src/knockout.coffee
@@ -34,7 +34,6 @@

     'updating model should update views' : (test) ->
         html.onload = "
-            console.log('inside onload');
             window.viewModel = {
                 stringValue : ko.observable('Hello'),
                 booleanValue : ko.observable(true)
@@ -43,11 +42,11 @@
         "
         html.body = "

+                   data-bind='text: stringValue'>

             <input id='stringInput'
                    data-bind='value: stringValue' />

+                   data-bind='text: booleanValue() ? \"true\" : \"false\"'>

             <input id='boolInput' type='checkbox'
                    data-bind='checked: booleanValue' />
         "


Use _.indexOf instead of _.contains

Use _.indexOf instead of _.contains

_.indexOf supports a isSorted flag which can be used
since the extension arrays are pre-sorted.

--- src/stdlib/fs.coffee
+++ src/stdlib/fs.coffee
@@ -152,35 +152,33 @@
     undefined

   isCompressedExtension: (ext) ->
-    _.contains([
+    _.indexOf([
       '.gz'
       '.jar'
       '.tar'
       '.zip'
-    ], ext)
+    ], ext, true) >= 0

   isImageExtension: (ext) ->
-    _.contains([
+    _.indexOf([
       '.gif'
       '.jpeg'
       '.jpg'
       '.png'
       '.tiff'
-    ], ext)
+    ], ext, true) >= 0

   isPdfExtension: (ext) ->
-    _.contains([
-      '.pdf'
-    ], ext)
+    ext is '.pdf'

   isMarkdownExtension: (ext) ->
-    _.contains([
+    _.indexOf([
       '.markdown'
       '.md'
       '.mkd'
       '.mkdown'
       '.ron'
-    ], ext)
+    ], ext, true) >= 0

   readObject: (path) ->
     contents = @read(path)


Defer execution of trace content.

Defer execution of trace content.

--- examples/delaunay.coffee
+++ examples/delaunay.coffee
@@ -22,7 +22,7 @@

 # Here's a quick hack for switching traces on and off.

-trace = (s) -> #console.log s
+trace = (s) -> #console.log s()

 # ----
@@ -177,7 +177,7 @@
       else if x = seq([[a, b], [b, c], [c, a]]).find((e) => @third__.get(e)?]
         [f, g] = x
         h = @third__.get x
-        trace "  Error in plus [#{@toSeq()?.join ', '}], (#{a}, #{b}, #{c})"
+        trace -> "  Error in plus [#{@toSeq()?.join ', '}], (#{a}, #{b}, #{c})"
         throw new Error "Orientation mismatch."
       else
         triangles = @triangles__.plus tri a, b, c
@@ -301,7 +301,7 @@
     # in which `t` is divided into three new triangles with `p` as a common
     # vertex.
     subdivide = (T, t, p) ->
-      trace "subdivide [#{T.triangulation__.toSeq().join ', '}], #{t}, #{p}"
+      trace -> "subdivide [#{T.triangulation__.toSeq().join ', '}], #{t}, #{p}"
       [a, b, c] = t.vertices()
       new T.constructor(
         T.triangulation__.minus(a,b,c).plus(a,b,p).plus(b,c,p).plus(c,a,p),
@@ -315,7 +315,7 @@
     # edge `ab` lies in triangles `abc` and `bad`, then after the flip those
     # are replaced by new triangle `bcd` and `adc`.
     flip = (T, a, b) ->
-      trace "flip [#{T.triangulation__.toSeq().join ', '}], #{a}, #{b}"
+      trace -> "flip [#{T.triangulation__.toSeq().join ', '}], #{a}, #{b}"
       c = T.third a, b
       d = T.third b, a
       children = seq [tri(b, c, d), tri(a, d, c)]


Modified in browser at pixie.strd6.com

Modified in browser at pixie.strd6.com

--- test/approachable.coffee
+++ test/approachable.coffee
@@ -40,7 +40,7 @@

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

-test "#addCooldown", 6, ->
+test "#addCooldown", 3, ->
   obj = GameObject()

   obj.include(Approachable)


Move Rework to PostCSS in tests

Move Rework to PostCSS in tests

--- test/autoprefixer.coffee
+++ test/autoprefixer.coffee
@@ -1,7 +1,6 @@
 autoprefixer = require('../lib/autoprefixer')
 Browsers     = require('../lib/autoprefixer/browsers')
 cases        = require('./lib/cases')
-rework       = require('rework')

 cleaner     = autoprefixer('none')
 compiler    = autoprefixer('chrome 25', 'opera 12')
@@ -81,8 +80,8 @@

       for type in commons
         continue if type == 'mistakes' or type == 'flex-rewrite'
-        input  = cases.read('autoprefixer/' + type + '.out')
-        output = cases.read('autoprefixer/' + type)
+        input  = cases.read(type + '.out')
+        output = cases.read(type)
         css    = cleaner.compile(input)
         compare(css, output)

@@ -90,13 +89,13 @@
       for type in commons
         instance = prefixer(type)

-        input  = cases.read('autoprefixer/' + type)
-        output = cases.read('autoprefixer/' + type + '.out')
+        input  = cases.read(type)
+        output = cases.read(type + '.out')
         css    = instance.compile( instance.compile(input) )
         compare(css, output)

     it 'parses difficult files', ->
-      input  = cases.read('autoprefixer/syntax')
+      input  = cases.read('syntax')
       output = cleaner.compile(input)
       compareWithoutComments(input, output)

@@ -110,16 +109,13 @@
       error.message.should.eql "Can't parse CSS: missing '}' near line 1:4"
       error.css.should.be.true

-  describe 'rework()', ->
+  describe 'postcss()', ->

     it 'is a Rework filter', ->
-      for type in commons
-        instance = prefixer(type)

-        real = rework(cases.read('autoprefixer/' + type)).
-          use(instance.rework).
-          toString()
-        compare(real, cases.read('autoprefixer/' + type + '.out'))
+      input  = cases.read(type)
+      output = postcss( compiler.postcss ).process(input)
+      compare(output, cases.read(type + '.out'))

   describe 'inspect()', ->

@@ -140,6 +136,6 @@
     it 'supports custom prefixes',      -> test('custom-prefix')

     it 'ignores transform in transition for IE', ->
-      input  = cases.read('autoprefixer/ie-transition')
+      input  = cases.read('ie-transition')
       output = autoprefixer('ie > 0').compile(input)
       compare(input, output)


Modified in browser at pixie.strd6.com

Modified in browser at pixie.strd6.com

--- test/clamp_bounds.coffee
+++ test/clamp_bounds.coffee
@@ -6,7 +6,7 @@

   # Hack in App.width, App.height
   App = {}
-  App
+  App.width =

   player.I.x = - 400
   player.update()


Modified in browser at pixie.strd6.com

Modified in browser at pixie.strd6.com

--- test/clamp_bounds.coffee
+++ test/clamp_bounds.coffee
@@ -6,12 +6,5 @@
   # Test for equality of two objects
   equals one, 1

-test "testing boolean values", ->
-  someFunction = ->
-    return true

-  # Test if someFunction returns true
-  ok someFunction()
-
-# Clear out the module
 module()


Mock downloads API

Mock downloads API

--- src/test/mock.coffee
+++ src/test/mock.coffee
@@ -7,15 +7,22 @@
   # GET

   $.mockjax (settings) ->
-    # settings.url == '/contents/<uuid>'
+    # settings.url === '/contents/<uuid>'
     service = settings.url.match(/\/contents\/(.*)$/)

     if service
       return {proxy: 'data/' + service[1] + '.json'}

   $.mockjax (settings) ->
-    # settings.url == '/search?q=physics'
+    # settings.url === '/search?q=physics'
     service = settings.url.match(/\/search\?q=physics$/)

     if service
       return {proxy: 'data/search.json'}
+
+  $.mockjax (settings) ->
+    # settings.url === 'exports-allowable-types/<uuid>'
+    service = settings.url.match(/\/exports-allowable-types\/(.*)$/)
+
+    if service
+      return {proxy: 'data/downloads.json'}


process.versions.atom-shell -> process.versions.electron

--- src/package.coffee
+++ src/package.coffee
@@ -751,7 +751,7 @@
     "installed-packages:#{@name}:#{@metadata.version}:build-error"

   getIncompatibleNativeModulesStorageKey: ->
-    electronVersion = process.versions['electron'] ? process.versions['atom-shell']
+    electronVersion = process.versions.electron
     "installed-packages:#{@name}:#{@metadata.version}:electron-#{electronVersion}:incompatible-native-modules"

   getCanDeferMainModuleRequireStorageKey: ->


n00b error

n00b error

--- routes/Event.coffee
+++ routes/Event.coffee
@@ -4,22 +4,18 @@

   # Display a list of story
   index: (req, res) ->
-    Event
-      .find {}
-      .exec (err, events) ->
-        if err then res.send 500
-        else
-          res.render 'Event/list',
-            events: events
+    Event.find({}).exec (err, events) ->
+      if err then res.send 500
+      else
+        res.render 'Event/list',
+          events: events

   # Display data as JSON
   index_json: (req, res) ->
-    Event
-      .find {}
-      .exec (err, events) ->
-        if err then res.send 500
-        else
-          res.json events
+    Event.find({}).exec (err, events) ->
+      if err then res.send 500
+      else
+        res.json events

   # Display an entry page
   add: (req, res) ->


:green_heart:

--- src/workspace.coffee
+++ src/workspace.coffee
@@ -509,11 +509,11 @@
   #
   # Note that the opener will be called if and only if the URI is not already open
   # in the current pane. The searchAllPanes flag expands the search from the
-  # current pane to all panes. If you wish to open a view of a different type for
-  # a file that is already open, consider changing the protocol of the URI. For
-  # example, perhaps you wish to preview a rendered version of the file `/foo/bar/baz.quux`
-  # that is already open in a text editor view. You could signal this by calling
-  # {Workspace::open} on the URI `quux-preview://foo/bar/baz.quux`. Then your opener
+  # current pane to all panes. If you wish to open a view of a different type for
+  # a file that is already open, consider changing the protocol of the URI. For
+  # example, perhaps you wish to preview a rendered version of the file `/foo/bar/baz.quux`
+  # that is already open in a text editor view. You could signal this by calling
+  # {Workspace::open} on the URI `quux-preview://foo/bar/baz.quux`. Then your opener
   # can check the protocol for quux-preview and only handle those URIs that match.
   addOpener: (opener) ->
     if includeDeprecatedAPIs


Rename Workspace::openSync's changeFocus option to activatePane

The old option is still supported as a deprecated shim.

--- src/workspace.coffee
+++ src/workspace.coffee
@@ -77,8 +77,10 @@
         console.error(error.stack ? error)

   # Private: Only used in specs
-  openSync: (uri, {changeFocus, initialLine, pane, split}={}) ->
-    changeFocus ?= true
+  openSync: (uri, options={}) ->
+    {initialLine, pane, split} = options
+    # TODO: Remove deprecated changeFocus option
+    activatePane = options.activatePane ? options.changeFocus ? true
     pane ?= @activePane
     uri = atom.project.relativize(uri)

@@ -105,7 +107,7 @@

     @itemOpened(paneItem)

-    pane.activate() if changeFocus
+    pane.activate() if activatePane
     paneItem

   # Public: Synchronously open an editor for the given URI or activate an existing


Modified in browser at pixie.strd6.com

Modified in browser at pixie.strd6.com

--- test/controllable.coffee
+++ test/controllable.coffee
@@ -10,6 +10,6 @@
   player.include(Controllable)

   keydown.left = true
-
+  player.

 module()


Modified in browser at pixie.strd6.com

Modified in browser at pixie.strd6.com

--- test/controllable.coffee
+++ test/controllable.coffee
@@ -73,7 +73,7 @@
   player.update()

   equals player.I.velocity.x, -Math.sqrt(2)
-  equals player.I.velocity.y, -Math.sqrt
+  equals player.I.velocity.y, -Math.sqrt(2)

 test "should correctly track facing direction", ->
   ok player.I.facing.equal(Point(1, 0))


Update scope for `$` in tests

Update scope for `$` in tests

--- spec/powershell-spec.coffee
+++ spec/powershell-spec.coffee
@@ -27,7 +27,7 @@
   describe "comments", ->
     it "parses comments at the end of lines", ->
       {tokens} = grammar.tokenizeLine("$foo = 'bar' # a trailing comment")
-      expect(tokens[0]).toEqual value: "$", scopes: ["source.powershell", "keyword.other.powershell"]
+      expect(tokens[0]).toEqual value: "$", scopes: ["source.powershell", "keyword.other.variable.definition.powershell"]
       expect(tokens[1]).toEqual value: "foo", scopes: ["source.powershell", "variable.other.readwrite.powershell"]
       expect(tokens[2]).toEqual value: " ", scopes: ["source.powershell"]
       expect(tokens[3]).toEqual value: "=", scopes: ["source.powershell", "keyword.operator.assignment.powershell"]
@@ -47,7 +47,7 @@
   describe "start of variable", ->
     it "parses the dollar sign at the beginning of a variable separately", ->
       {tokens} = grammar.tokenizeLine("$var")
-      expect(tokens[0]).toEqual value: "$", scopes: ["source.powershell", "keyword.other.powershell"]
+      expect(tokens[0]).toEqual value: "$", scopes: ["source.powershell", "keyword.other.variable.definition.powershell"]
       expect(tokens[1]).toEqual value: "var", scopes: ["source.powershell", "variable.other.readwrite.powershell"]

   describe "Double-quoted strings", ->
@@ -84,7 +84,7 @@

     describe "Variables within a string", ->
       tokens = null
-      expectedDollarSignScopes = ["keyword.other.powershell"]
+      expectedDollarSignScopes = ["keyword.other.variable.definition.powershell"]

       beforeEach ->
         {tokens} = grammar.tokenizeLine("\"Hi there $name `$bob\"")
@@ -278,7 +278,7 @@
       for automaticVariable in automaticVariables
         {tokens} = grammar.tokenizeLine automaticVariable
         expect(tokens[0].value).toEqual "$"
-        expect(tokens[0]).toHaveScopes ["source.powershell", "keyword.other.powershell"]
+        expect(tokens[0]).toHaveScopes ["source.powershell", "keyword.other.variable.definition.powershell"]
         if tokens[1]?
           expect(tokens[1].value).toEqual automaticVariable.substr(1)
           expect(tokens[1]).toHaveScopes ["source.powershell", "support.constant.automatic.powershell"]


Trigger resize event on editor before wrap guide specs

--- spec/wrap-guide-spec.coffee
+++ spec/wrap-guide-spec.coffee
@@ -11,6 +11,7 @@
     editor = rootView.getActiveEditor()
     wrapGuide = rootView.find('.wrap-guide').view()
     editor.width(editor.charWidth * wrapGuide.getDefaultColumn() * 2)
+    editor.trigger 'resize'

   describe "@initialize", ->
     it "appends a wrap guide to all existing and new editors", ->


Fixed test and added test for the list command

--- test/grafana-test.coffee
+++ test/grafana-test.coffee
@@ -13,4 +13,7 @@
     require('../src/grafana')(@robot)

   it 'registers a dashboard listener', ->
-    expect(@robot.respond).to.have.been.calledWith(/(?:grafana|graph|graf) (?:dash|dashboard|db) ([A-Za-z0-9\-\:_]+)(| [A-Za-z0-9\-\+]+)?(| [A-Za-z0-9\-\+]+)?/i)
+    expect(@robot.respond).to.have.been.calledWith(/(?:grafana|graph|graf) (?:dash|dashboard|db) ([A-Za-z0-9\-\:_]+)(.*)?/i)
+
+  it 'registers a list listener', ->
+    expect(@robot.respond).to.have.been.calledWith(/(?:grafana|graph|graf) list/i)


fix(install): in `fromFolder` tests stub `getCurrentProfile`

`minecraftUtils.getCurrentProfile()` is used in logs and causes errors in
Travis builds because Travis doesn't have an actual profile list file.

--- test/install.spec.coffee
+++ test/install.spec.coffee
@@ -291,6 +291,12 @@

 	describe "fromFolder", ->

+		before ->
+			sinon.stub minecraftUtils, "getCurrentProfile", -> {}
+
+		after ->
+			minecraftUtils.getCurrentProfile.restore()
+
 		it "reads and checks package config", ->
 			result = install.fromFolder "test/fixtures/invalid-mod"
 			result.should.be.an.instanceof Error


added check for xhr

added check for xhr

--- lib/assets/javascripts/turbolinks.coffee
+++ lib/assets/javascripts/turbolinks.coffee
@@ -652,7 +652,7 @@
 installJqueryAjaxSuccessPageUpdateTrigger = ->
   if typeof jQuery isnt 'undefined'
     jQuery(document).on 'ajaxSuccess', (event, xhr, settings) ->
-      return unless jQuery.trim xhr.responseText
+      return unless jQuery.trim xhr?.responseText
       triggerEvent EVENTS.UPDATE

 onHistoryChange = (event) ->


Only run scripts in the <body>

Only run scripts in the <body>

--- lib/assets/javascripts/turbolinks.coffee
+++ lib/assets/javascripts/turbolinks.coffee
@@ -212,7 +212,7 @@

 getScriptsToRun = (runScripts) ->
   selector = if runScripts is false then 'script[data-turbolinks-eval="always"]' else 'script:not([data-turbolinks-eval="false"])'
-  script for script in document.querySelectorAll(selector) when isEvalAlways(script) or not withinPermanent(script)
+  script for script in document.body.querySelectorAll(selector) when isEvalAlways(script) or not withinPermanent(script)

 isEvalAlways = (script) ->
   script.getAttribute('data-turbolinks-eval') is 'always'


Remove up.util.get (which would be overridden by up.util.cache internals, damn CS scoping!)

--- lib/assets/javascripts/up/util.js.coffee
+++ lib/assets/javascripts/up/util.js.coffee
@@ -21,11 +21,6 @@
       else
         cached = true
         cache = func(args...)
-
-  get = (url, options) ->
-    options = options or {}
-    options.url = url
-    ajax options

   ajax = (options) ->
     if options.selector
@@ -850,7 +845,6 @@
   createElementFromHtml: createElementFromHtml
   $createElementFromSelector: $createElementFromSelector
   createSelectorFromElement: createSelectorFromElement
-  get: get
   ajax: ajax
   extend: extend
   copy: copy


Added rotationAtFraction and ofsetted angle animation with start

Fixes https://github.com/motif/company/issues/6563


Remove superfluous parens.

Remove superfluous parens.

--- test/e2e/subjectListSpec.coffee
+++ test/e2e/subjectListSpec.coffee
@@ -17,7 +17,7 @@
             repeat.isElementPresent(anchorLocator).then (exists) ->
               if exists
                 repeat.all(anchorLocator).then (hyperlinks) ->
-                  sbjs = ((hyperlink.getText() for hyperlink in hyperlinks))
+                  sbjs = (hyperlink.getText() for hyperlink in hyperlinks)
                   {name: coll, subjects: sbjs}
               else
                 {name: coll, subjects: []}