Added instantiated/called from here + from argument types to linter output (Fix #14)

Signed-off-by: WebFreak001 <b0a51d41aaf8d5df1e850f1ef2ec58fb1c30319f@web.de>

--- lib/dub-linter.coffee
+++ lib/dub-linter.coffee
@@ -3,7 +3,8 @@
 path = require "path"

 # path(lineNumber): (Deprecation|Warning|Error): <message>
-dubErrorFormat = /(.*?)\((\d+)(?:,(\d+))?\): (Deprecation|Warning|Error): (.*)/g;
+dubErrorFormat = /(.*?)\((\d+),(\d+)\): (Deprecation|Warning|Error): (.*)/g;
+dubErrorFormatRel = /(.*?)\((\d+),(\d+)\): (.*)/g;

 module.exports =
   class DubLinter
@@ -22,14 +23,13 @@
     lint: (textEditor) =>
       return new Promise (resolve, reject) =>
         output = ""
-        args = ["build", "--nodeps", "--combined", "-q", "--build=syntaxOnly"]
-        # --root= instead of cwd for absolute file paths
+        args = ["build", "--nodeps", "--combined", "-q"]

         if global.buildName?
           args.push "--config=" + global.buildName

         env = Object.create(process.env)
-        env.DFLAGS = "-vcolumns"
+        env.DFLAGS = "-vcolumns -o-"

         proc = new BufferedProcess
           command: @dubPath
@@ -46,15 +46,27 @@
             obj = []
             for line in lines
               match = dubErrorFormat.exec(line)
-              if match? && match.length >= 6
+              if match
                 obj.push
                   type: match[4],
                   text: match[5],
                   filePath: path.join(atom.project.getPaths()[0], match[1]),
                   range: [
                     [parseInt(match[2]) - 1, parseInt(match[3]) - 1],
-                    [parseInt(match[2]) - 1, parseInt(match[3]) - 1] # Whole line
+                    [parseInt(match[2]) - 1, parseInt(match[3]) + 300]
                   ]
+              else
+                if line.indexOf("from here") != -1 or line.indexOf("from argument types") != -1
+                  match = dubErrorFormatRel.exec(line)
+                  if match
+                    obj.push
+                      type: "error",
+                      text: match[4],
+                      filePath: path.join(atom.project.getPaths()[0], match[1]),
+                      range: [
+                        [parseInt(match[2]) - 1, parseInt(match[3]) - 1],
+                        [parseInt(match[2]) - 1, parseInt(match[3]) + 300]
+                      ]
             resolve obj

         proc.onWillThrowError ({error,handle}) ->


Adapt to run Docker apps

Adapt to run Docker apps

--- lib/executable.coffee
+++ lib/executable.coffee
@@ -28,7 +28,9 @@
     validateExecutablePath: (path) -> new Promise (resolve, reject) =>
         path = parsePath path
         try
-            agdaProcess = spawn path, ['-V']
+            args = @getProgramArgs()
+            args.push '-V'
+            agdaProcess = spawn path, args
             agdaProcess.on 'error', (error) =>
                 reject new InvalidExecutablePathError error, path
             agdaProcess.stdout.once 'data', (data) =>
@@ -37,6 +39,8 @@
                     resolve path
                 else
                     reject new InvalidExecutablePathError data.toString(), path
+            agdaProcess.stderr.once 'data', (data) =>
+                reject new InvalidExecutablePathError data.toString(), path
         catch error
             reject new InvalidExecutablePathError error, path

@@ -82,10 +86,9 @@
             resolve @agdaProcess
         else
             @getExecutablePath().then (path) =>
-
                 # Agda program arguments
                 args = @getProgramArgs()
-                args.unshift '--interaction'
+                args.push '--interaction'
                 agdaProcess = spawn path, args

                 # catch other forms of errors
@@ -156,7 +159,8 @@

     info: =>
         @getExecutablePath().then (path) =>
-            child = exec "#{path} -V", (error, stdout, stderr) =>
+            args = @getProgramArgs().join(' ')
+            child = exec "#{path} #{args} -V", (error, stdout, stderr) =>
                 if error
                     @core.panel.setContent "Error", "#{error}", 'error'
                 else


Prevent same image loading in related shows

--- collections/partner_shows.coffee
+++ collections/partner_shows.coffee
@@ -52,7 +52,7 @@
   getShowsRelatedImages: ->
     Q.allSettled(
       @map (show) ->
-        show.related().installShots.fetch data: size: 1
+        show.related().installShots.fetch data: size: 1, default: false
         show.related().artworks.fetch data: size: 5
     ).then =>
       @trigger 'shows:fetchedRelatedImages'


Switch to a shorter icon URL.

Switch to a shorter icon URL.

(Fixes coffeelint's "line too long" complaint)

--- itad_importer.user.coffee
+++ itad_importer.user.coffee
@@ -38,7 +38,7 @@
 // @version 0.1a1
 // @namespace http://isthereanydeal.com/
 // @description Adds buttons to various sites to export your game lists to ITAD
-// @icon https://s3-eu-west-1.amazonaws.com/itad/images/apple-touch-icon-57x57.png
+// @icon http://s3-eu-west-1.amazonaws.com/itad/images/banners/50x50.gif
 // @grant GM_info
 // @require https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js
 //


Don't use alert for error messages

Don't use alert for error messages

--- jarkle/client/main.coffee
+++ jarkle/client/main.coffee
@@ -65,7 +65,8 @@
         name: generateName()
     , (error) ->
       if error?
-        alert error + 'Hold on'
+        # XXX: Just log the error
+        console.log "Error creating user #{error}"

 Template.controller.rendered = ->
   if not @renderedOnce


CLI 'server' command modules serving process update

--- cli/commands/server.coffee
+++ cli/commands/server.coffee
@@ -7,7 +7,9 @@
 #
 exports.init = (args) ->
   fs      = require('fs')
+  path    = require('path')
   source  = require('../source')
+  package = require('../package')
   express = require('express')
   server  = express.createServer()
   port    = args[0] || lovelyrc.port || 3000
@@ -17,28 +19,33 @@
   base[base.length - 1] isnt '/' and base += '/'
   base += "packages"

-  # dynamically serving the main module script
-  server.get '/main.js', (req, res) ->
-    src  = if minify then source.minify() else source.compile()
-    size = Math.round(src.length/102.4)/10
-    console.log(" Compiling: ".cyan+ "/main.js (#{size}Kb #{if minify then 'minified' else 'source'})".grey)
+  #
+  # serving the modules
+  # NOTE: if the module name is the same as the current package name
+  #       then the module will be dynamically compiled out of the source
+  #
+  server.get '/:module.js', (req, res) ->
+    module = req.params.module
+
+    if module == package.name
+      src  = if minify then source.minify() else source.compile()
+      size = Math.round(src.length/102.4)/10
+      console.log(" Compiling: ".cyan+ "/#{module}.js (#{size}Kb #{if minify then 'minified' else 'source'})".grey)
+
+    else
+      src = "/#{module}/current/build/#{module}#{if minify then '' else '-src'}.js"
+      console.log(" Serving:   ".magenta + "/#{module}.js -> ~/.lovely/packages#{src}".grey)
+      src = fs.readFileSync("#{base}/#{src}").toString()
+
+
     res.charset = 'utf-8'
     res.header('Cache-Control', 'no-cache')
     res.contentType('text/javascript')
     res.send src

-  server.get '/lovely.io/:module.js', (req, res) ->
-    module = req.params.module
-    script = "#{base}/#{module}/current/build/#{module}#{if minify then '' else '-src'}.js"
-
-    console.log(" Serving:   ".magenta+ "'#{module}' module from #{script}".grey)
-
-    fs.readFile script, (err, data)->
-      res.contentType('text/javascript')
-      res.send data
-
+  # just a dummy favicon response
   server.get '/favicon.ico', (req, res) ->
-    res.send '' # just keeping it happy
+    res.send ''

   # listening all the static content in the user project
   server.get /^\/(.*?)$/, (req, res) ->
@@ -56,18 +63,29 @@
       when 'js'  then content_type = 'text/javascript'
       else            content_type = 'text/html'

-    fs.readFile "#{process.cwd()}/#{filename}", (err, data)->
-      console.log("") if extension is "html"
-      console.log(" Sending:   "+ "/#{filename} (#{content_type})".grey)
+    if path.existsSync("#{process.cwd()}/#{filename}")
+      fs.readFile "#{process.cwd()}/#{filename}", (err, data)->
+        console.log("") if extension is "html"
+        console.log(" Sending:   "+ "/#{filename} (#{content_type})".grey)

-      res.charset = 'utf-8'
-      res.contentType(content_type)
-      res.send data
+        res.charset = 'utf-8'
+        res.contentType(content_type)
+        res.send data
+    else
+      console.log("\n Sending: "+ "404 Error".red + " /#{filename} is not found".grey)
+      res.send """
+
+
+
404 Error

+
The page is not found

+
+
+      """

   server.listen(port)

-  print "Listening at: http://127.0.0.0:#{port}\n"+
+  print "Listening: http://127.0.0.0:#{port}\n"+
     "Press Ctrl+C to hung up".grey


Cache remote templates

Cache remote templates

--- client/modules/skin.coffee
+++ client/modules/skin.coffee
@@ -1,28 +1,44 @@

 config = require 'config'
+
+cache = null

 exports.registerDirective = ($injector, uri) ->

 	compile: (scope, element) ->

 		$injector.invoke [
-			'$compile', '$http'
-			($compile, $http) ->
+			'$cacheFactory', '$compile', '$http'
+			($cacheFactory, $compile, $http) ->
+
+				cache = $cacheFactory 'shrub-skin' unless cache?

 				do relink = ->
 					return unless skinKey = config.get 'packageConfig:shrub-skin:default'

 					wasVisible = element.is ':visible'

-					promise = $http.get "/skin/#{skinKey}/#{uri}"
-
-					promise.success (data, status, headers, config) ->
+					resolve = (data) ->

 						element.hide() if wasVisible
 						element.html data
 						$compile(element.contents())(scope)
+
+					if (promise = cache.get "#{skinKey}/#{uri}")

-					promise.finally -> element.show() if wasVisible
+						promise.success resolve
+						element.show() if wasVisible
+
+					else
+
+						promise = $http.get "/skin/#{skinKey}/#{uri}"
+						cache.put "#{skinKey}/#{uri}", promise
+
+						promise.success (data, status, headers, config) ->
+
+							resolve data
+
+						promise.finally -> element.show() if wasVisible

 				scope.$on 'shrub.skin.update', relink


check for reserve vals

check for reserve vals

--- bokehjs/src/coffee/mapper/color/linear_color_mapper.coffee
+++ bokehjs/src/coffee/mapper/color/linear_color_mapper.coffee
@@ -11,8 +11,9 @@
       super(attrs, options)
       @palette       = @_build_palette(@get('palette'))
       @little_endian = @_is_little_endian()
-      @reserve_color = @get('reserve_color')[0]  ##TODO: Why are these coming in as arrays?
-      @reserve_val   = @get('reserve_val')[0]
+      if @get('reserve_color')?
+        @reserve_color = @get('reserve_color')[0]  ##TODO: Why are these coming in as arrays?
+        @reserve_val   = @get('reserve_val')[0]

     v_map_screen: (data) ->


Use shorthand array creation for levels

Use shorthand array creation for levels

--- src/coffee/controller/SyllabusItemsController.coffee
+++ src/coffee/controller/SyllabusItemsController.coffee
@@ -2,7 +2,7 @@

 syllabusItemsControllerFunction = ($scope, syllabusItemsService) ->

-  levels = [0 ,1, 2, 3, 4]
+  levels = [0..4]

   $scope.init = ->
     $scope.items = syllabusItemsService.query()


Fixing lint errors

Fixing lint errors

--- lib/locale-checker.coffee
+++ lib/locale-checker.coffee
@@ -95,9 +95,9 @@
       systemChecker = new spellchecker.Spellchecker
       systemChecker.setSpellcheckerType spellchecker.ALWAYS_USE_SYSTEM
       if systemChecker.setDictionary @locale, ""
-          @log 'using Windows Spell API'
-          @spellchecker = systemChecker
-          return
+        @log 'using Windows Spell API'
+        @spellchecker = systemChecker
+        return

     # If all else fails, try the packaged en-US dictionary in the `spellcheck`
     # library.


Critical bug fix where all validation promises should be settled out of the loop scope

--- lib/model_instance.coffee
+++ lib/model_instance.coffee
@@ -29,10 +29,10 @@
                                 accessor = _s.camelize prop
                                 deffers = deffers.concat Validators[validator][validator](@, accessor, validator_options)

-                    Q.allSettled(deffers).then((result) =>
-                        @isValid = Object.keys(@errors).length is 0
-                        oper.resolve()
-                    )
+            Q.allSettled(deffers).then((result) =>
+                @isValid = Object.keys(@errors).length is 0
+                oper.resolve()
+            )
         oper.promise

     @getType = () ->


Changed the RedBlackTree so it will replace the value stored with the given key if it already exists

--- src/RedBlackTree.coffee
+++ src/RedBlackTree.coffee
@@ -143,7 +143,8 @@
   bigger  = if !this.right.isEmpty() then this.right.inorderTraversal(f)

 ###*
-  Returns a new tree with the inserted element.
+  Returns a new tree with the inserted element.  If the Tree already contains that key
+  the old value is replaced with the new value
 ###
 RedBlackNode.prototype.insert = (key,value) ->
   that = this
@@ -158,7 +159,7 @@
     else if (compare > 0)
       that.balance(c, l, k,v, __insert(r))
     else
-      tree
+      new RedBlackNode(RED, tree.left, key, value, tree.right)

   t = __insert(that)
   new RedBlackNode(BLACK, t.left, t.key, t.value, t.right)


Fixing log statement.

Fixing log statement.

--- lib/jumpy-view.coffee
+++ lib/jumpy-view.coffee
@@ -51,7 +51,7 @@
           return
       editor = atom.workspace.getActivePaneItem()
       editor.setCursorBufferPosition(location)
-      console.log "Jumpy jumped to: #{@firstChar}#{@secondChar} at (#{location})"
+      console.log "Jumpy jumped to: #{@firstChar}#{@secondChar} at (#{location.row},#{location.column})"

   findLocation: ->
       bufferPosition = @allPositions[0]["#{@firstChar}#{@secondChar}"]


Finish implementation for following lines

--- lib/log-filter.coffee
+++ lib/log-filter.coffee
@@ -83,18 +83,11 @@
       if 0 < resultsTailLength
         resultsWithTail = []
         @results.text.reverse()
-        # for lineNumber, lineIndex in @results.text
-        #   if !( lineIndex + resultsTailLength >= @results.text.length or lineNumber - resultsTailLength < @results.text[lineIndex + resultsTailLength] ) and ( lineNumber - resultsTailLength >= 0 )
-        #     resultsWithTail.push(lineNumber)
         for lineNumber, lineIndex in @results.text
-          if ( lineIndex + resultsTailLength < @results.text.length and lineNumber - resultsTailLength <= @results.text[lineIndex + resultsTailLength] ) or ( lineIndex + resultsTailLength >= @results.text.length and 0 == ( @results.text.length - lineIndex ) - ( @textEditor.getLineCount() - lineNumber ) )
+          if ( lineIndex + resultsTailLength < @results.text.length and lineNumber - resultsTailLength <= @results.text[lineIndex + resultsTailLength] ) or ( lineIndex + resultsTailLength >= @results.text.length and 0 == ( @results.text.length - lineIndex ) - ( lineNumber + 1 ) )
             resultsWithTail.push(lineNumber)
         resultsWithTail.reverse()
         @results.text = resultsWithTail
-
-      # resultsHeadLength = 2
-      # if 0 < resultsHeadLength
-      #   for num in [@results.text.length..0]

     console.log (@results.text)


Bind correct context for Ext.Logger.log

Bind correct context for Ext.Logger.log

--- src/coffee/Deft/log/Logger.coffee
+++ src/coffee/Deft/log/Logger.coffee
@@ -6,42 +6,42 @@
 Ext.define( 'Deft.log.Logger',
 	alternateClassName: [ 'Deft.Logger' ]
 	singleton: true
-
+
 	log: ( message, priority ) ->
 		return
-
+
 	error: ( message ) ->
 		@log( message, 'error' )
 		return
-
+
 	info: ( message ) ->
 		@log( message, 'info' )
 		return
-
+
 	verbose: ( message ) ->
 		@log( message, 'verbose' )
 		return
-
+
 	warn: ( message ) ->
 		@log( message, 'warn' )
 		return
-
+
 	deprecate: ( message ) ->
 		@log( message, 'deprecate' )
 		return
 ,
 	->
 		if Ext.isFunction( Ext.Logger?.log )
-			@log = Ext.Logger.log
+			@log = Ext.bind(Ext.Logger.log, Ext.Logger)
 		else if Ext.isFunction( Ext.log )
 			@log = ( message, priority = 'info' ) ->
 				if priority is 'deprecate'
-					priority = 'warn'
+					priority = 'warn'
 				Ext.log(
 					msg: message
 					level: priority
 				)
 				return
-
+
 		return
-)+)


fix coffeescript

fix coffeescript

--- src/frinkiac.coffee
+++ src/frinkiac.coffee
@@ -48,12 +48,12 @@
   robot.respond /(simpsons search|frinkiac) (.*)/i, (msg) ->
     query = msg.match[1]

-    axios getRequestConfig('search', {q: query})
+    axios(getRequestConfig('search', {q: query}))
       .then (response) ->
         if (response.data.length)
           episode = response.data[0].Episode
           timestamp = response.data[0].Timestamp
-          axios getRequestConfig('caption', {e: episode, t: timestamp})
+          axios(getRequestConfig('caption', {e: episode, t: timestamp}))
             .then (response) ->
               caption = response.data.Subtitles[0].Content
               msg.send getImageUrl(episode, timestamp, caption)


Fix API not making calls.

Fix API not making calls.

You know you have to actually call a function for it to run.

--- compiler/ContentAPI.coffee
+++ compiler/ContentAPI.coffee
@@ -237,6 +237,7 @@
                         results.push(_results...)
                         num_last_batch = _results.length
                         _makeRequest()
+        _makeRequest()

     entries: (cb) ->
         @filter


catch all errors when updating and try to restart

--- lib/update_manager.coffee
+++ lib/update_manager.coffee
@@ -87,8 +87,13 @@
   update_asar = path.join(__dirname, '../../', 'update-asar')

   download url, update_asar, (err) ->
-    return EndSession(err) if err instanceof cErrors.UpdateError
-    return EndSession(new cErrors.UpdateError('Can\'t write/download update file').causedBy(err)) if err
+    if !(err instanceof cErrors.UpdateError)
+      err = new cErrors.UpdateError('Can\'t write/download update file').causedBy(err)
+
+    if process.platform == 'win32' and !optionsParser.runnedAsAdmin()
+      return runas(process.execPath, ['--startAsAdmin'], {hide: false, admin: true})
+    else
+      return EndSession(err)

     if process.platform == 'darwin'
       osxMinor(app_asar, update_asar)


:memo: Mark Atom class as public

:memo: Mark Atom class as public

--- src/atom.coffee
+++ src/atom.coffee
@@ -14,6 +14,7 @@
 ThemeManager = require './theme-manager'
 ContextMenuManager = require './context-menu-manager'

+# Public: Atom global for dealing with packages, themes, menus, and the window.
 module.exports =
 class Atom
   constructor: ->


Apply default dimensions

Apply default dimensions

--- src/atom.coffee
+++ src/atom.coffee
@@ -227,6 +227,14 @@
     dimensions = JSON.stringify(atom.getWindowDimensions())
     localStorage.setItem("defaultWindowDimensions", dimensions)

+  applyDefaultWindowDimensions: ->
+    return unless dimensions = localStorage.getItem("defaultWindowDimensions")
+    try
+      JSON.parse(dimensions)
+    catch error
+      console.warn "Error parsing default window dimensions", error
+      localStorage.removeItem("defaultWindowDimensions")
+
   restoreWindowDimensions: ->
     workAreaSize = screen.getPrimaryDisplay().workAreaSize
     windowDimensions = @state.windowDimensions ? {}


change CLI string

change CLI string

--- lib/views/terminal.coffee
+++ lib/views/terminal.coffee
@@ -100,7 +100,7 @@

   openLab: (path = @openPath)->
     if path
-      @terminal.send('learn open ' + path.toString() + '\r')
+      @terminal.send('greyatom open ' + path.toString() + '\r')
       @openPath = null

   onBlur: (e) ->


Remove lodash dependency.

Remove lodash dependency.

--- src/base.coffee
+++ src/base.coffee
@@ -3,7 +3,6 @@
 path = require 'path'
 fs = require 'fs'
 util = require 'util'
-_ = require 'lodash'
 Configstore = require 'configstore'
 yeoman = require 'yeoman-generator'
 grunt = require 'grunt'
@@ -31,7 +30,7 @@
 		@config = new Configstore 'yeoman-generator',
 			authorName: 'John Smith'
 			authorUrl: 'http://example.com'
-		_.extend this, @config.all
+		@_.extend this, @config.all

 		# Expose useful libraries
 		@grunt = grunt
@@ -53,7 +52,7 @@
 		desc: @_.humanize(name) + ' to be invoked'
 		defaults: @options[name] or ''

-	@_hooks.push (_.defaults config, name: name)
+	@_hooks.push (@_.defaults config, name: name)

 	this


Use the auth plugin instead of the roles plugin.

--- src/greeting.coffee
+++ src/greeting.coffee
@@ -54,8 +54,8 @@

   verifyPermission = (msg, target) ->
     return true if freeForAll or msg.message.user.name is target
-    user = robot.brain.userForName target
-    if user? and user.roles? and GREETING_ROLE in user.roles
+    user = robot.brain.userForName()
+    if robot.auth.hasRole msg.message.user.name, GREETING_ROLE
       true
     else
       msg.reply "I can't do that, you're not a #{GREETING_ROLE}!"


improve format table

improve format table

--- lib/commands.coffee
+++ lib/commands.coffee
@@ -87,9 +87,26 @@

   formatTable: ->
     editor = atom.workspace.getActiveEditor()
+
+    unless editor.getSelectedText()
+      editor.moveCursorToBeginningOfPreviousParagraph()
+      editor.selectToBeginningOfNextParagraph()
     lines = editor.getSelectedText().split("\n")
+
+    range = @_findTableRange(lines, editor.getSelectedBufferRange())
     values = @_parseTable(lines)
+
+    editor.setSelectedBufferRange(range)
     editor.insertText(@_createTable(values))
+
+  _findTableRange: (lines, {start, end}) ->
+    head = lines.findIndex (line) -> line != ""
+    tail = lines[..].reverse().findIndex (line) -> line != ""
+
+    return [
+      [start.row + head, 0]
+      [end.row - tail, lines[lines.length - 1 - tail].length]
+    ]

   _parseTable: (lines) ->
     table = []


Updated file-upload with changing $response parameter to a XHR response object.

--- src/directives/file_upload.coffee
+++ src/directives/file_upload.coffee
@@ -34,7 +34,7 @@
         $scope.$apply ->
           $status        = $data.jqXHR?.status
           args           = {$event, $data, $status}
-          args.$response = $data.result if action is "Success"
+          args.$response = $data.jqXHR
           callbackFn $scope, args

     options =


Support fractional hours, minutes, etc. in since parsing

--- lib/messages.coffee
+++ lib/messages.coffee
@@ -318,9 +318,11 @@

 @parseSince = (since) ->
   try
-    match = /^\s*[+-]?\s*(\d+)\s*(\w+)\s*$/.exec since
+    match = /^\s*[+-]?\s*([\d.]+)\s*(\w+)\s*$/.exec since
     if match?
-      moment().subtract(match[1], match[2]).toDate()
+      amount = parseFloat match[1]
+      return null if isNaN amount
+      moment().subtract(amount, match[2]).toDate()
     else
       match = /^\s*(\d+)\s*:\s*(\d+)\s*$/.exec since
       if match?


commentaires

commentaires

--- lib/ocamltop.coffee
+++ lib/ocamltop.coffee
@@ -14,70 +14,57 @@

     { spawn } = require 'child_process'
     {EventEmitter} = require 'events'
-    fs = require 'fs'
-    #emitter = require 'emitter'
-    #emitter.setMaxListeners 100
-    #ls = spawn '/Users/ByTeK/.atom/packages/ocamltop/node_modules/Ocaml_Interpreteur.sh'
-    #ls.stdout.on 'data', ( data ) -> console.log "Output: #{ data }"
-    #ls.stderr.on 'data', ( data ) -> console.error "Error: #{ data }"
-    #ls.on 'close', -> console.log "'ls' has finished executing."
-
     home = @getUserHome()
     editor = atom.workspace.getActivePaneItem()

-    #editor.onDidDestroy(()->console.log "test")
+    file = editor?.buffer.file # Donne l'Objet du fichier courant
+    filePath = file?.path

-    file = editor?.buffer.file
-    filePath = file?.path
-    #directoryPath = atom.project.getPath()
+    # extrait le chemin "absolu" du fichier courant
     f = file.getPath()
+    # nom du fichier courant
     file_name = "#{ file.getBaseName() }"#.replace /.ml/, ""

     #test si ML
     strings = file_name.split "."
     if console.log strings[strings.length-1].charAt(0) == 'm' and console.log strings[strings.length-1].charAt(1) == 'l' and  strings[strings.length-1].length == 2
+      # marche pas ???
       return

+    # chemin vers le fichier tmp Interprété
     uri = "#{ home }/.atom/packages/ocamltop/temp/#{ file_name }"

-    #foo = -> fs.readFileSync filePath, 'utf8'
-    #string = foo().toString()
-    # tempStream = fs.createWriteStream(uri,\
-    #    {flags: 'w'});
-    #console.log "#{ uri }"
-
+    # exécution du scripte qui interprete le fichier .ml et ecrit dans le fichier tmp
     ocaml = spawn "#{ home }/.atom/packages/ocamltop/node_modules/Ocaml_Interpreteur.sh",["#{ f }","#{ uri }"]
     ocaml.once 'close', -> console.log "'ocaml' has finished executing."
     ocaml.exit

+    # fonction qui efface le fichier tmp quand le fichier le fichier source est fermé
     clean = ->
       rm = spawn 'rm',["-f","#{ uri }"]
       rm.once 'close', -> console.log "'rm' has finished executing."
       rm.exit
     editor.onDidDestroy(clean)

-    userPanel = atom.workspace.getActivePane()
-    previewPane = atom.workspace.paneForUri(uri)
+    userPanel = atom.workspace.getActivePane() # panel du fichier source
+    previewPane = atom.workspace.paneForUri(uri) # panel du fichier tmp

+    # si le fichier tmp est deja ouvert on le met au premier plan de son pane
     if previewPane
       previewPane.activateItemForUri(uri)
+      userPanel.activate()
+      return
+
+    # Fonction pour récupérer la main sur le fichier source
+    userPanelHandle = ->
       #@traiter(atom.workspace.getActivePaneItem().getText())
       userPanel.activate()
-      #console.log userPanel
-      return

-    userPanelHandle = ->
-        #@traiter(atom.workspace.getActivePaneItem().getText())
-        userPanel.activate()
-
+    # une fois le fichier tmp ouvert on réccupere la main sur la source
     atom.workspace.onDidOpen(userPanelHandle)

-
+    # on split le panel et on ouvre le fichier tmp
     atom.workspace.open(uri, split: 'right', searchAllPanes: true, activatePane: true).done
-    #interpreteur.onWillInsertText(->console.log "test")
-    #newPane = atom.workspace.getActivePane()
-    #interpreterPane.activateItemForUri(uri)
-    #activePane.activate()

   traiter: (texte)-> console.log "Coucou"


:art: rename typedText to insertedText

:art: rename typedText to insertedText

--- lib/operator.coffee
+++ lib/operator.coffee
@@ -550,11 +550,11 @@
 class ActivateInsertMode extends Operator
   @extend()
   complete: true
-  typedText: null
+  insertedText: null
   flashTarget: false

   initialize: ->
-    @vimState.setCheckpoint() unless @typedText?
+    @vimState.setCheckpoint() unless @insertedText?

   # This uses private APIs and may break if TextBuffer is refactored.
   # Package authors - copy and paste this code at your own risk.
@@ -567,15 +567,15 @@

   confirmChanges: (checkpoint) ->
     changes = @getChangesSinceCheckpoint(checkpoint)
-    @typedText = if (range = getInsertedRange(changes))?
+    @insertedText = if (range = getInsertedRange(changes))?
       @editor.getTextInBufferRange(range)
     else
       ""

   execute: ->
-    if @typedText?
-      return unless @typedText
-      @editor.insertText(@typedText, normalizeLineEndings: true, autoIndent: true)
+    if @insertedText?
+      return unless @insertedText
+      @editor.insertText(@insertedText, normalizeLineEndings: true, autoIndent: true)
       for cursor in @editor.getCursors() when not cursor.isAtBeginningOfLine()
         cursor.moveLeft()
     else
@@ -593,11 +593,11 @@
   @extend()

   execute: ->
-    if @typedText?
-      return unless @typedText
+    if @insertedText?
+      return unless @insertedText
       @editor.transact =>
-        @editor.insertText(@typedText, normalizeLineEndings: true)
-        toDelete = @typedText.length - @countChars('\n', @typedText)
+        @editor.insertText(@insertedText, normalizeLineEndings: true)
+        toDelete = @insertedText.length - @countChars('\n', @insertedText)
         for selection in @editor.getSelections()
           count = toDelete
           selection.delete() while count-- and not selection.cursor.isAtEndOfLine()
@@ -637,10 +637,10 @@
       when 'below' then @editor.insertNewlineBelow()
     @editor.getLastCursor().skipLeadingWhitespace()

-    if @typedText?
+    if @insertedText?
       # We'll have captured the inserted newline, but we want to do that
       # over again by hand, or differing indentations will be wrong.
-      @typedText = @typedText.trimLeft()
+      @insertedText = @insertedText.trimLeft()
       super
     else
       @vimState.activate('insert')
@@ -660,7 +660,7 @@
     @target.select()
     if @haveSomeSelection()
       @setTextToRegister @editor.getSelectedText()
-      if @target.isLinewise?() and not @typedText?
+      if @target.isLinewise?() and not @insertedText?
         for selection in @editor.getSelections()
           selection.insertText("\n", autoIndent: true)
           selection.cursor.moveLeft()
@@ -668,7 +668,7 @@
         for selection in @editor.getSelections()
           selection.deleteSelectedText()

-    return super if @typedText?
+    return super if @insertedText?

     @vimState.activate('insert')


ClampBounds docs

ClampBounds docs

--- src/clamp_bounds.coffee
+++ src/clamp_bounds.coffee
@@ -25,7 +25,7 @@
   # => 2.5 # half the player's width

   player.I.y
-  # => 320 -
+  # => 320 - ()


remove ui-state-active from button when dialog gets closed via dialog.close()

--- plugins/image.coffee
+++ plugins/image.coffee
@@ -15,6 +15,8 @@
                 modal: false
                 resizable: false
                 draggable: false
+                close: (ev, ui) ->
+                    jQuery('.image_button').removeClass('ui-state-active')
             dialog: null

         _create: ->


Background image on activeImage hover

Background image on activeImage hover

--- plugins/image.coffee
+++ plugins/image.coffee
@@ -42,7 +42,10 @@

-
+

+
+
+

                         Caption<input type=\"text\" id=\"caption\" />
@@ -100,7 +103,7 @@
                 jQuery(".#{widget.widgetName}-imageThumbnail").removeClass "#{widget.widgetName}-imageThumbnailActive"
                 jQuery(this).addClass "#{widget.widgetName}-imageThumbnailActive"

-                jQuery("##{widget.options.uuid}-#{widget.widgetName}-activeImage").attr "src", jQuery(this).attr "src"
+                jQuery(".#{widget.widgetName}-activeImage").attr "src", jQuery(this).attr "src"


Simplifiest logging levels

Simplifiest logging levels

--- lib/Bumped.default.coffee
+++ lib/Bumped.default.coffee
@@ -24,7 +24,7 @@

   logger:
     keyword: 'bumped'
-    level: 'plugin'
+    level: 'all'
     types:
       error:
         level : 0
@@ -35,18 +35,6 @@
       success:
         level : 2
         color : 'green'
-      info:
-        level : 3
-        color : 'white'
-      verbose:
-        level : 4
-        color : 'cyan'
-      debug:
-        level : 5
-        color : 'blue'
-      plugin:
-        level : 6
-        color : 'magenta'

   args: ->
     args = Args([


Move encoding methods to metadata section

--- src/file.coffee
+++ src/file.coffee
@@ -19,9 +19,9 @@
 class File
   EmitterMixin.includeInto(this)

+  encoding: 'utf8'
   realPath: null
   subscriptionCount: 0
-  encoding: 'utf8'

   ###
   Section: Construction
@@ -125,6 +125,13 @@
   setDigest: (contents) ->
     @digest = crypto.createHash('sha1').update(contents ? '').digest('hex')

+  # Public: Sets the file encoding name.
+  # * `encoding` The {String} encoding to use such as 'utf8'
+  setEncoding: (@encoding) ->
+
+  # Public: Returns the file encoding name.
+  getEncoding: -> @encoding
+
   ###
   Section: Managing Paths
   ###
@@ -135,12 +142,6 @@
   # Sets the path for the file.
   setPath: (@path) ->
     @realPath = null
-
-  # Public: Sets the file encoding name.
-  setEncoding: (@encoding) ->
-
-  # Public: Returns the file encoding name.
-  getEncoding: -> @encoding

   # Public: Returns this file's completely resolved {String} path.
   getRealPathSync: ->


Use state, not props

Use state, not props

--- src/components/app.cjsx
+++ src/components/app.cjsx
@@ -54,7 +54,7 @@

   renderExerciseOrLoad: ->
     if @state.exerciseId
-      <MPQToggle exerciseId={@props.exerciseId} />
+      <MPQToggle exerciseId={@state.exerciseId} />
     else
       <div className="input-group">
         <input type="text" className="form-control" onKeyPress={@onFindKeyPress}


Updating the help docs with the new set motors and set fan commands

--- src/help.coffee
+++ src/help.coffee
@@ -40,19 +40,26 @@
   #     """
   set:
     description: """
-      set the target temperature(s) of the printer's extruder(s)
-      or bed
+      set one or more settings on the printer. The printer's settings are
+      grouped under temp, motors and fan namespaces:
+
+      - temp: set the target temperature(s) of the printer's extruder(s) or bed
+      - motors: enable/disable the printer's motors
+      - fan: enable/disable the printer's fan
     """
-    optional_args: ["e", "b"]# Proposed Additions: ["e", "e0", "e1", "e2", "b"]
+    # optional_args: ["e", "b"]# Proposed Additions: ["e", "e0", "e1", "e2", "b"]
     examples:
       "Start heating the extruder to 220\u00B0C": "set temp e0: 220"
       "Set the extruder's target temp. to 0\u00B0C (off)": "set temp e0: 0"
       "Start heating the bed to 100\u00B0C": "set temp b: 100"
+      "Enable the printer's motors": "set motors on"
+      "Disable the printer's motors": "set motors off"
+      "Enable the printer's fan": "set fan on"
+      "Disable the printer's fan": "set fan off"
       # Proposed Additions:
       #   set temp e0:220 e1:0 b:100
       #   set temp 220
       #   set feedrate xy: 100 z: 1
-      #   set fan on
   estop:
     description: """
       Emergency stop. Stop all dangerous printer activity immediately.


fix osx application quit

fix osx application quit

--- src/main.coffee
+++ src/main.coffee
@@ -359,7 +359,7 @@
     # Emitted when the window is about to close.
     # For OSX only hides the window if we're not force closing.
     mainWindow.on 'close', (ev) ->
-        darwinHideOnly = process.platform == 'darwin' and not mainWindow?.forceClose
+        darwinHideOnly = process.platform == 'darwin' and not global.forceClose

         if darwinHideOnly
             ev.preventDefault()


Add glider spaceship example

Add glider spaceship example

--- src/main.coffee
+++ src/main.coffee
@@ -16,7 +16,12 @@

   for y in [0...CELL_ROWS]
     for x in [0...CELL_COLUMNS]
+      # Randomized
       cells.create x * 10, y * 10, cellBitmap, 0, game.rnd.between(0, 20) is 0
+      # Glider spaceship starting on the top left corner
+      # cells.create x * 10, y * 10, cellBitmap, 0,
+      #   (y == 0 && x == 2) || (y == 1 && x == 0) || (y == 1 && x == 2) ||
+      #   (y == 2 && x == 1) || (y == 2 && x == 2)
       cells.getTop().toBeKilled = false
       cells.getTop().toBeReset = false


Store parsed command line args in BrowserMain

--- src/main.coffee
+++ src/main.coffee
@@ -8,15 +8,19 @@

 class BrowserMain
   windowState: null
-  commandLineArgs: null
+  resourcePath: null

   constructor: ->
-    modifiedArgv = ['node'].concat(process.argv) # optimist assumes the first arg will be node
-    @commandLineArgs = optimist(modifiedArgv).argv
     @windowState = {}

+    @parseCommandLine()
+    @setupNodePaths()
     @handleEvents()
-    @setupNodePaths()
+
+  parseCommandLine: ->
+    modifiedArgv = ['node'].concat(process.argv) # optimist assumes the first arg will be node
+    args = optimist(modifiedArgv).argv
+    @resourcePath = args['resource-path']

   setupNodePaths: ->
     resourcePaths = [
@@ -33,7 +37,7 @@
     resourcePaths.push path.join(homeDir, '.atom', 'packages')

     resourcePaths = resourcePaths.map (relativeOrAbsolutePath) =>
-      path.resolve @commandLineArgs['resource-path'], relativeOrAbsolutePath
+      path.resolve @resourcePath, relativeOrAbsolutePath

     process.env['NODE_PATH'] = resourcePaths.join path.delimiter

@@ -52,7 +56,7 @@
       dialog.openFolder currentWindow, {}, (result, paths...) =>
         new AtomWindow
           bootstrapScript: 'window-bootstrap',
-          resourcePath: @commandLineArgs['resource-path']
+          resourcePath: @resourcePath

 class AtomWindow
   @windows = []
@@ -94,4 +98,4 @@
 delegate.browserMainParts.preMainMessageLoopRun = ->
   new AtomWindow
     bootstrapScript: 'window-bootstrap',
-    resourcePath: browserMain.commandLineArgs['resource-path']
+    resourcePath: browserMain.resourcePath


Quit the app when we're done with it. Fixes #144

--- src/main.coffee
+++ src/main.coffee
@@ -9,7 +9,6 @@
   window = new SpringseedWindow()

 app.on 'window-all-closed', ->
-  if process.platform is not 'darwin'
     app.quit()

 app.on 'activate-with-no-open-windows', ->


Normalize output

Normalize output

--- src/main.coffee
+++ src/main.coffee
@@ -38,6 +38,8 @@
                 })
             else
                 rawCode
+    if code[code.length - 1] != "\n"
+        code += "\n"
     mod = {}
     mods.push(mod)
     mod.code = code
@@ -80,7 +82,7 @@
     modsBodyStr = mods.map((mod) ->
         info = if informative then path.relative(process.cwd(), mod.rawFilePath) + " " else ""
         """
-            {
+            {\
             fun: function(exports, module, require) {

@@ -89,17 +91,15 @@
             // ***** (((

             #{mod.code}
-
             // ***** ))) file end

-            },
-            nameIndexes: #{JSON.stringify(mod.nameIndexes)},
-            result: initialModResult_386389655257694535
+            }, \
+            nameIndexes: #{JSON.stringify(mod.nameIndexes)}, \
+            result: initialModResult_386389655257694535\
             }
-
         """
-    ).join(",\n")
+    ).join(", ")
     bundleStr = """
         // This wrapper is to prevent global variable assignments. It's not to
         // prevent naming conflicts ("386389655257694535" already does), but to


redoing some changes that I already made

--- src/main.coffee
+++ src/main.coffee
@@ -27,11 +27,11 @@
   code = textarea.val()
   md = markdown(code)
   outputarea.find('.output').html(md)
-  js = ''
+  js = []
   n = 0
   $('#output .output code').parent('pre').replaceWith(-> (
     console.log('blah')
-    js += $(this).children().text()
+    js.push($(this).children().text())
     replacement = $('<div>')
     replacement.attr('id', 'js' + (n++))
     replacement


adds a version start to help with debugging when asking users for screenshots

--- src/main.coffee
+++ src/main.coffee
@@ -18,6 +18,8 @@
 tmp.setGracefulCleanup()

 app = require('electron').app
+
+console.log('Starting Yakyak v' + app.getVersion() + '...')
 app.disableHardwareAcceleration() # was using a lot of resources needlessly
 app.commandLine.appendSwitch('autoplay-policy', 'no-user-gesture-required')


jupyter: click to create cell; slightly improve

--- src/smc-webapp/jupyter/insert-cell.cjsx
+++ src/smc-webapp/jupyter/insert-cell.cjsx
@@ -21,14 +21,15 @@
         new_id = @props.actions.insert_cell(if @props.position=='below' then 1 else -1)
         if e.shiftKey or e.ctrlKey or e.altKey or e.metaKey
             @props.actions.set_cell_type(new_id, "markdown")
+        @setState(hover:false)

     render: ->
         style = {height:'6px'}
         if @state.hover
             style.backgroundColor = '#428bca'
         <div
-            style   = {style}
-            onClick = {@click}
+            style        = {style}
+            onClick      = {@click}
             onMouseEnter = {=>@setState(hover:true)}
             onMouseLeave = {=>@setState(hover:false)}
             >


add link to faq

add link to faq

--- src/smc-webapp/jupyter/top-menubar.cjsx
+++ src/smc-webapp/jupyter/top-menubar.cjsx
@@ -327,6 +327,7 @@
                 <MenuItem eventKey="help-keyboard" onClick={@command("edit keyboard shortcuts")}><Icon name='keyboard-o'/>  Keyboard Shortcuts...</MenuItem>
                 <MenuItem divider />
                 {external_link('Notebook Help', 'http://nbviewer.jupyter.org/github/ipython/ipython/blob/3.x/examples/Notebook/Index.ipynb')}
+                {external_link('Jupyter in SageMathCloud','https://github.com/sagemathinc/smc/wiki/sagejupyter')}
                 {external_link('Markdown', 'https://help.github.com/articles/basic-writing-and-formatting-syntax')}
                 <MenuItem divider />
                 {@render_links()}


Improve a comment.

Improve a comment.

--- src/mock.coffee
+++ src/mock.coffee
@@ -12,7 +12,9 @@
 #
 #   my_mock.my_method(1,2,3)
 #
-# would result in @called = true.
+# would result in @called = true.  Note that a mocked function can
+# either return a value or throw an error but not both, so either
+# @returns or @throws (or both) must be undefined.
 #
 class MethodSignature


Clean(er) removal of dead widget copies

Clean(er) removal of dead widget copies

--- app/assets/javascripts/uploadcare/widget/live.js.coffee
+++ app/assets/javascripts/uploadcare/widget/live.js.coffee
@@ -8,27 +8,24 @@
   uploadcare.initialize = (targets) ->
     for target in $(targets || '@uploadcare-uploader')
       el = $(target)
-      widget = el.data(dataAttr)
-      if widget
-        reinitialize(el, widget).api()
-      else
-        createWidget(el).api()
+      initializeWidget(el)

-  reinitialize = (el, widget) ->
-    if el[0] != widget.element[0]
-      cleanup(el, widget.template)
-      createWidget(el)
-    else
-      widget
+  initializeWidget = (el) ->
+    widget = el.data(dataAttr)
+    if !widget || el[0] != widget.element[0]
+      cleanup(el)
+      widget = new uploadcare.widget.Widget(el)
+      el.data(dataAttr, widget)
+      widget.template.content.data(dataAttr, widget.template)

-  cleanup = (el, template) ->
+    widget.api()
+
+  cleanup = (el) ->
     el.off('.uploadcare')
-    el.next('.uploadcare-widget').remove()
-
-  createWidget = (el) ->
-    widget = new uploadcare.widget.Widget(el)
-    el.data(dataAttr, widget)
-    widget
+    el = el.next('.uploadcare-widget')
+    template = el.data(dataAttr)
+    if el.length && (!template || el[0] != template.content[0])
+      el.remove()

   if uploadcare.defaults.live
     live = ->


Minor

Minor

--- src/quip.coffee
+++ src/quip.coffee
@@ -34,8 +34,9 @@

   websocketUrl: (error, response) =>
     if error
+      @robot.logger.error error
+      @robot.logger.error @retries
       if @retries < 10
-        @robot.logger.error error
         @retries++
         @logger.info "Trying again in %ds", @retries * 1000
         setTimeout =>


Update server.coffee

Update server.coffee

--- components/backend/server.coffee
+++ components/backend/server.coffee
@@ -5,7 +5,7 @@
     # load/setup modules
     dir =  __dirname+'/modules/'
     fs.readdir dir, (err, files)->
-      if err then throw err
+      return console.log err if err
       files.forEach (file)->
         fs.lstat dir+file, (err, stats)->
           if !err && stats.isDirectory()


Binded mouseenter and mouseleave events to resize tab handles when mouse outed from handle container.

--- components/tabs/KDTabView.coffee
+++ components/tabs/KDTabView.coffee
@@ -29,6 +29,13 @@

     @hideHandleCloseIcons() if options.hideHandleCloseIcons
     @hideHandleContainer()  if options.hideHandleContainer
+
+    @blockTabHandleResize = no
+
+    @tabHandleContainer.on "mouseenter", => @blockTabHandleResize = yes
+
+    @tabHandleContainer.on "mouseleave", => @blockTabHandleResize = no
+

   # ADD/REMOVE PANES
   createPanes:(paneTitlesArray = @getOptions().tabNames)->


Pull FormService out of CommentForm for now

--- lineman/app/components/thread_page/comment_form/comment_form.coffee
+++ lineman/app/components/thread_page/comment_form/comment_form.coffee
@@ -3,16 +3,18 @@
   restrict: 'E'
   templateUrl: 'generated/components/thread_page/comment_form/comment_form.html'
   replace: true
-  controller: ($scope, FormService, Records, CurrentUser) ->
+  controller: ($scope, FlashService, Records, CurrentUser) ->
     group = $scope.comment.discussion().group()
     discussion = $scope.comment.discussion()

-    $scope.submit = FormService.submit $scope, $scope.comment,
-      flashSuccess: 'comment_form.messages.created'
-      successCallback: =>
-        $scope.comment.body = ''
-        $scope.comment.newAttachmentIds = []
-        $scope.comment.parentId = null
+    $scope.submit = ->
+      $scope.isDisabled = true
+      $scope.comment.save().then ->
+        $scope.isDisabled = false
+        $scope.comment = Records.comments.build(discussion_id: discussion.id)
+        FlashService.success('comment_form.messages.created')
+      , ->
+        $scope.isDisabled = false

     $scope.$on 'replyToCommentClicked', (event, parentComment) ->
       $scope.comment.parentId = parentComment.id


This var is being unused

This var is being unused

--- src/metadata.coffee
+++ src/metadata.coffee
@@ -5,8 +5,6 @@
 builtins     = require 'builtins'

 module.exports = class Metadata
-  packageFile: JSON.parse(fs.readFileSync(path.join(__dirname, '..', 'package.json'), 'utf-8'))
-
   constructor: (@dependencies, @parser) ->

   generate: (@root) ->


Fixed host_address_inc edge case

Fixed host_address_inc edge case

--- src/natives/classes/java.net.Inet6AddressImpl.coffee
+++ src/natives/classes/java.net.Inet6AddressImpl.coffee
@@ -11,7 +11,7 @@
   next_host_address[3] = 0 if next_host_address[3] > 255
   next_host_address[2] = 0 if next_host_address[2] > 255
   next_host_address[1] = 0 if next_host_address[1] > 255
-  if next_host_address[1] > 250
+  if next_host_address[0] > 250
     error 'Out of addresses'
     next_host_address[0] = 240

@@ -38,7 +38,6 @@

     rs.call_bytecode cdata, cdata.method_lookup(rs, '<init>(Ljava/lang/String;I)V'), [ hostname, host_allocate_address() ], success, failure

-
   o 'getLocalHostName()Ljava/lang/String;', (rs, _this) ->
     rs.init_string 'localhost'


Fixing context-menu

Fixing context-menu

In Settings Page visible "Optimize CSS" menu

--- menus/cssnano.cson
+++ menus/cssnano.cson
@@ -1,5 +1,5 @@
 'context-menu':
-    'atom-workspace': [{
+    'atom-text-editor': [{
         label: 'Optimize CSS',
         command: 'cssnano:process'
     }]


Shared SRs.

Shared SRs.

--- src/spec.coffee
+++ src/spec.coffee
@@ -106,8 +106,9 @@

           SRs: @dynamic [],
             SR:
-              enter: (value) ->
-                if value.$pool is @value.UUID
+              update: (value) ->
+                remove @field, value.UUID
+                if value.$shared and value.$pool is @value.UUID
                   @field.push value.UUID
               exit: (value) -> remove @field, value.UUID

@@ -401,6 +402,10 @@

           $VDIs: get('VDIs')

+          # FIXME: only here for pools.
+          $pool: get '$pool'
+          $shared: get 'shared'
+
       PBD:

         test: test


Modified in browser at pixie.strd6.com

Modified in browser at pixie.strd6.com

--- src/text.coffee
+++ src/text.coffee
@@ -1,6 +1,7 @@
 Score = (I={}) ->
   Object.reverseMerge I,
     duration: 40
+    font
     points: 500
     alpha: 1


Fix: runner can takeScreenShot from phantomjs too

--- src/selenium.coffee
+++ src/selenium.coffee
@@ -16,6 +16,6 @@
   _setupRunner: ->
     do @runner
       .setSleepOnError if @_config.browser.browserName isnt 'phantomjs' then @_config.onError.sleep else undefined
-      .setTakeScreenShotOnFail if @_config.browser.browserName isnt 'phantomjs' then @_config.onError.takeScreenShot else false
+      .setTakeScreenShotOnFail @_config.onError.takeScreenShot
       .start


FIx FileSystem.flush() and FileSystem.close()

--- system/FileSystem.coffee
+++ system/FileSystem.coffee
@@ -14,9 +14,8 @@
 # along with CoffeeScript OS.  If not, see <http://www.gnu.org/licenses/>.

 define [
-  "../lib/local-storage/LocalStorage",
-  "../lib/dojox/uuid/generateTimeBasedUuid"
-], (LocalStorage, makeUuid) ->
+  "../lib/local-storage/LocalStorage"
+], (LocalStorage) ->
   class FileSystem # Implements a simple filesystem on top of LocalStorage.
     constructor: ->
       if not localStorage? # Make sure Web Storage is available.
@@ -98,10 +97,15 @@
         return null

     flush: (handle) ->
-      @store.put @handles[handle]
+      return false if not @exists @handles[handle].loc # Don't throw when the file doesn't exist.
+      try
+        @store.put @handles[handle]
+      catch
+        return false
+      return true

     close: (handle) ->
-      flush handle
+      @flush handle
       delete @handles[handle]

     read: (handle) ->


Fix bug with numbers in xlsx sheets

Fix bug with numbers in xlsx sheets

Numbers were getting treated as numeric keys, which led to symbols with
numeric instead of string keys, making `Context.includes` fail.

--- src/svgtiler.coffee
+++ src/svgtiler.coffee
@@ -271,6 +271,7 @@
         value = Symbol.parse key, value
       @map[key] = value
   lookup: (key) ->
+    key = key.toString()  ## Sometimes get a number, e.g., from XLSX
     if key of @map
       @map[key]
     else if @function?


Fixed GC msg split limit

Fixed GC msg split limit

--- lib/atox-toxWorker.coffee
+++ lib/atox-toxWorker.coffee
@@ -436,11 +436,10 @@
   sendToGC: (e) ->
     #return @stub 'sendToGC' # TODO -- rework for new tox API
     try
-      BigMessage.send e.msg, @consts.TOX_MAX_MESSAGE_LENGTH, (msg) =>
+      BigMessage.send e.msg, 1360, (msg) => # @consts.TOX_MAX_MESSAGE_LENGTH is to big
         @TOX.old().sendGroupchatMessageSync e.gID, "#{msg}"
     catch err
-      @err "Failed to send MSG to group chat #{e.gID}"
-      console.log err
+      return @handleExept err

   setGCtitle: (params) ->
     try


fixed boundAll to deal with null bounds

fixed boundAll to deal with null bounds

--- src/tree.coffee
+++ src/tree.coffee
@@ -79,18 +79,24 @@
 boundAll: (boundaries...) ->
     # return null if boundaries.length is 0 or nonexistant.
     if !boundaries.length? then return null
-    # initialize to first point
-    [xMin, yMin] = [@boundaries[0][0].x, @boundaries[0][0].y]
-    [xMax, yMax] = [@boundaries[0][1].x, @boundaries[0][1].y]
-    for bounds in boundaries
-        [xMin, yMin] = [
-            Math.min(xMin, bounds[0].x)
-            Math.min(yMin, bounds[0].y)
-        ]
-        [xMax, yMax] = [
-            Math.max(xMax, bounds[1].x)
-            Math.max(yMax, bounds[1].y)
-        ]
+    # declare these to fix scope
+    [xMin, yMin] = [null, null]
+    [xMax, yMax] = [null, null]
+    for bounds in boundaries when bounds?
+        # initialize min/max to first non-null bounds
+        if !xMin?   # if one is null, all others are too
+            [xMin, yMin] = [bounds[0].x, bounds[0].y]
+            [xMax, yMax] = [bounds[1].x, bounds[1].y]
+        # min/max have been initialized, check if they should change
+        else
+            [xMin, yMin] = [
+                Math.min(xMin, bounds[0].x)
+                Math.min(yMin, bounds[0].y)
+            ]
+            [xMax, yMax] = [
+                Math.max(xMax, bounds[1].x)
+                Math.max(yMax, bounds[1].y)
+            ]
     return [new Vector(xMin, yMin), new Vector(xMax, yMax)]

 # A representation of the Pythagoras tree in its own coordinate system.


fixing patternmatched assigns within assigns within calls

--- nodes.coffee
+++ nodes.coffee
@@ -604,7 +604,8 @@
   # See: http://wiki.ecmascript.org/doku.php?id=harmony:destructuring
   compile_pattern_match: (o) ->
     val_var: o.scope.free_variable()
-    assigns: [@idt() + val_var + ' = ' + @value.compile(o) + ';']
+    value: if @value.is_statement() then ClosureNode.wrap(@value) else @value
+    assigns: [@idt() + val_var + ' = ' + value.compile(o) + ';']
     o.top: true
     o.as_statement: true
     for obj, i in @variable.base.objects


check existence of this.context. Avoid build error

https://github.com/jashkenas/coffee-script/issues/1541

with thanks to analyst74 whose bug report made the fix trivial =)

--- nodes.coffee
+++ nodes.coffee
@@ -917,7 +917,7 @@
   children: ['variable', 'value']

   isStatement: (o) ->
-    o?.level is LEVEL_TOP and "?" in @context
+    o?.level is LEVEL_TOP and @context? and "?" in @context

   assigns: (name) ->
     @[if @context is 'object' then 'value' else 'variable'].assigns name


dynakeys: `{(x), y}` now compiles correctly

--- nodes.coffee
+++ nodes.coffee
@@ -588,15 +588,22 @@
     obj  = o.scope.freeVariable 'obj'
     code = "#{obj} = #{ new Obj(@properties.slice 0, idx).compile o }, "
     for prop, i in @properties.slice idx
-      if prop instanceof Assign
-        key   = prop.variable.compile o, LEVEL_PAREN
-        code += "#{obj}[#{key}] = #{ prop.value.compile o, LEVEL_LIST }, "
-        continue
       if prop instanceof Comment
         code += prop.compile(o) + ' '
         continue
-      [sub, ref] = prop.base.cache o, LEVEL_LIST, ref
-      code += "#{obj}[#{sub}] = #{ref}, "
+      if prop instanceof Assign
+        acc = prop.variable.base
+        key = acc.compile o, LEVEL_PAREN
+        val = prop.value.compile o, LEVEL_LIST
+      else
+        acc = prop.base
+        [key, val] = acc.cache o, LEVEL_LIST, ref
+        ref = val
+      key = if acc instanceof Literal and IDENTIFIER.test key
+        '.' + key
+      else
+        '[' + key + ']'
+      code += "#{obj}#{key} = #{val}, "
     code += obj
     if o.level <= LEVEL_PAREN then code else "(#{code})"


fix another long ternary in the lib

fix another long ternary in the lib

--- nodes.coffee
+++ nodes.coffee
@@ -1451,12 +1451,12 @@

   compileNode: (o) ->
     code = @expression.compile o, LEVEL_OP
-    code = if IDENTIFIER.test(code) and not o.scope.check code
-        [cmp, cnj] = if @negated then ['===', '||'] else ['!==', '&&']
-        "typeof #{code} #{cmp} \"undefined\" #{cnj} #{code} #{cmp} null"
+    if IDENTIFIER.test(code) and not o.scope.check code
+      [cmp, cnj] = if @negated then ['===', '||'] else ['!==', '&&']
+      code = "typeof #{code} #{cmp} \"undefined\" #{cnj} #{code} #{cmp} null"
     else
       # do not use strict equality here; it will break existing code
-      "#{code} #{if @negated then '==' else '!='} null"
+      code = "#{code} #{if @negated then '==' else '!='} null"
     if o.level <= LEVEL_COND then code else "(#{code})"

 #### Parens


be consistent about triple-equals-equality.

--- nodes.coffee
+++ nodes.coffee
@@ -1418,9 +1418,9 @@
     code = @expression.compile o, LEVEL_OP
     code = if IDENTIFIER.test(code) and not o.scope.check code
       if @negated
-        "typeof #{code} == \"undefined\" || #{code} === null"
+        "typeof #{code} === \"undefined\" || #{code} === null"
       else
-        "typeof #{code} != \"undefined\" && #{code} !== null"
+        "typeof #{code} !== \"undefined\" && #{code} !== null"
     else
       sym = if @negated then '==' else '!='
       "#{code} #{sym} null"


Added singlequotes around input of removebyname


Having some fun

Having some fun

--- src/worldcup.coffee
+++ src/worldcup.coffee
@@ -62,3 +62,14 @@

   robot.respond /(who).*(win).*(world).*(cup)/i, (msg) ->
     msg.send "BRASIL!!!"
+
+  robot.respond /(worldcup|wc) ( yellow|red) (.*)/i, (msg) ->
+    color = msg.match[2]
+    person = msg.match[3]
+
+    if color == "yellow"
+      msg.send "http://www.transpoplanner.com/wp-content/uploads/2014/01/b809cfee40_yellow-card1.jpg"
+      msg.send "#{person}: one more and you're out"
+    else if color == "red"
+      msg.send "http://img.thesun.co.uk/aidemitlum/archive/01689/red_main_1689473a.jpg"
+      msg.send "#{person}: you're out"


Fix bug: not bubbling event

Fix bug: not bubbling event

--- src/observable/observable_base.coffee
+++ src/observable/observable_base.coffee
@@ -168,7 +168,7 @@
       @_createTrack 'setter' if options.bubbling
     else
       @_update prop if options.notify
-      @_update() if options.notify
+      @_update() if options.bubbling

     val

@@ -212,11 +212,12 @@
     { obj, prop } = @getTerminalParent keypath
     obj._removeFromCollection prop

-  _update: (prop) -> @_fire prop, 'update'
+  _update: (prop) ->
+    @_fire prop, 'update'
+    @_parentObj._update @_parentProp if @_hasParent

   update: (keypath) ->
     { obj, prop } = @getTerminalParent keypath
-    @_parentObj._update @_parentProp if @_hasParent
     obj._update prop

   _observe: (prop, callback) ->


Ensure that sentence selection splits by other punctuation marks

--- annotran/static/scripts/annotator/plugin/sentenceselection.coffee
+++ annotran/static/scripts/annotator/plugin/sentenceselection.coffee
@@ -29,7 +29,7 @@

   prepareData: (target) ->
     desiredText = $(target).text()
-    desiredText = desiredText.split('.')
+    desiredText = desiredText.split(/[.!?]/)

     offset_to_use = 0
     counter = 0


List values can be saved WIP

List values can be saved WIP

--- app/assets/javascripts/admin/views/home/add_integration.js.coffee
+++ app/assets/javascripts/admin/views/home/add_integration.js.coffee
@@ -115,8 +115,8 @@
     # enabled = $(".enabled:checked").map ->
     #   $(@).val()
     #
-    # for consumerName of @parametersByConsumer()
-    #   @enabledMappings.push consumerName
+    for consumerName of @parametersByConsumer()
+      @enabledMappings.push consumerName

     @model.signup parameters, @enabledMappings, error: @displayErrors
     $.modal.close()


ComputeProviders: pass stack id to postCreate method of provider

--- workers/social/lib/social/models/computeproviders/computeprovider.coffee
+++ workers/social/lib/social/models/computeproviders/computeprovider.coffee
@@ -101,7 +101,7 @@
             return callback err  if err

             provider.postCreate {
-              postCreateOptions, machine, meta
+              postCreateOptions, machine, meta, stack: stack._id
             }, (err)=>

               return callback err  if err


Tell effective_resources about col actions actions

--- app/assets/javascripts/effective_datatables/inline_crud.js.coffee
+++ app/assets/javascripts/effective_datatables/inline_crud.js.coffee
@@ -8,7 +8,7 @@

   return true if ('' + $action.data('inline')) == 'false'

-  $params =  $.param({_datatable_id: $table.attr('id'), _datatable_cookie: $table.data('cookie') })
+  $params =  $.param({_datatable_id: $table.attr('id'), _datatable_cookie: $table.data('cookie'), _datatable_action: true })
   settings.url += (if settings.url.indexOf('?') == -1 then '?' else '&') + $params

   if $action.closest('.effective-datatables-inline-row').length > 0


scrolling back in action

scrolling back in action

--- app/assets/javascripts/backbone/helpers/channels.js.coffee
+++ app/assets/javascripts/backbone/helpers/channels.js.coffee
@@ -18,13 +18,11 @@

   @scrollToLatestMessage: (channelId)->
     console.log("scrolling to last message");
-    $('document').scrollTop($('document').height()+900)
-    #@channel_activities_el(channelId).parent().scrollTop(100000)
+    $(document).scrollTop($(document).height()+9000)

   @currentScrollPosition: (channelId)->
     console.log("current scroll position");
-    $('document').scrollTop()
-    #@channel_activities_el(channelId).parent().scrollTop()
+    $(document).scrollTop()

   @channel_activities_el: (channelId)->
     $("#channel-activities-#{channelId}")


add extend to affiliates to the sort by shared of the volumes

--- web/party/profile.coffee
+++ web/party/profile.coffee
@@ -191,7 +191,7 @@
       volumeSort =
         switch b
           when 'name' then (a,b) -> stringSort(a.volume.displayName, b.volume.displayName)
-          when 'access' then (a,b) -> b.volume.accessPreset - a.volume.accessPreset || b.volume.permission - a.volume.permission || stringSort(a.volume.displayName, b.volume.displayName)
+          when 'access' then (a,b) -> b.volume.accessPreset - a.volume.accessPreset || b.self.children - a.self.children || b.volume.permission - a.volume.permission || stringSort(a.volume.displayName, b.volume.displayName)
           when 'permission' then (a,b) -> b.volume.permission - a.volume.permission || stringSort(a.volume.displayName, b.volume.displayName)
       volumes.individual.sort(volumeSort)
       volumes.collaborator.sort(volumeSort)


don't explicitly import coffeescript file

--- src/smc-project/console_server.coffee
+++ src/smc-project/console_server.coffee
@@ -42,7 +42,7 @@

 message        = require('smc-util/message')
 misc_node      = require('smc-util-node/misc_node')
-{secret_token_filename} = require('./common.coffee')
+{secret_token_filename} = require('./common')

 port_manager = require('./port_manager')
 misc = require('smc-util/misc')


add comments

add comments

--- src/smc-webapp/editor_codemirror.cjsx
+++ src/smc-webapp/editor_codemirror.cjsx
@@ -66,9 +66,44 @@

 default_store_state =
     style :
-        border : '1px solid grey'
+        border     : '1px solid grey'
+        font-family: 'monospace !important'
     value : ''
     options : {}
+###
+        mode                      : required
+        read_only                 : false
+        line_numbers              : @props.editor_settings.line_numbers
+        first_line_number         : @props.editor_settings.first_line_number
+        show_trailing_whitespace  : @props.editor_settings.show_trailing_whitespace
+        indent_unit               : @props.editor_settings.indent_unit
+        tab_size                  : @props.editor_settings.tab_size
+        smart_indent              : @props.editor_settings.smart_indent
+        electric_chars            : @props.editor_settings.electric_chars
+        undo_depth                : @props.editor_settings.undo_depth
+        match_brackets            : @props.editor_settings.match_brackets
+        auto_close_brackets       : @props.editor_settings.auto_close_brackets
+        auto_close_xml_tags       : @props.editor_settings.auto_close_xml_tags
+        line_wrapping             : @props.editor_settings.line_wrapping
+        style_active_line         : 15    # @props.editor_settings.style_active_line  # (a number between 0 and 127)
+        spaces_instead_of_tabs    : @props.editor_settings.spaces_instead_of_tabs
+        match_xml_tags            : @props.editor_settings.match_xml_tags
+        code_folding              : @props.editor_settings.code_folding
+        bindings                  : @props.editor_settings.bindings  # 'standard', 'vim', or 'emacs'
+        theme                     : @props.editor_settings.theme
+        track_revisions           : @props.editor_settings.track_revisions
+        delete_trailing_whitespace: editor_settings.strip_trailing_whitespace  # delete on save
+        public_access             : false
+
+        # I'm making the times below very small for now.  If we have to adjust these to reduce load, due to lack
+        # of capacity, then we will.  Or, due to lack of optimization (e.g., for big documents). These parameters
+        # below would break editing a huge file right now, due to slowness of applying a patch to a codemirror editor.
+
+        cursor_interval           : 1000   # minimum time (in ms) between sending cursor position info to hub -- used in sync version
+        sync_interval             : 500    # minimum time (in ms) between synchronizing text with hub. -- used in sync version below
+
+        completions_size          : 20    # for tab completions (when applicable, e.g., for sage sessions)
+######

 exports.init_redux = init_redux = (redux, project_id, filename) ->
     name = redux_name(project_id, filename)
@@ -99,6 +134,8 @@
             style       : rtypes.object
             scroll_info : rtypes.object
             doc         : rtypes.object
+        account :
+            editor_settings  : rtypes.object

     propTypes :
         actions     : rtypes.object
@@ -128,6 +165,50 @@

         @cm.on('change', @_cm_change)
         @cm.on('scroll', @_cm_scroll)
+######
+        options =
+            mode                    : {name:opts.mode, globalVars: true}
+            readOnly                : opts.read_only
+            lineNumbers             : opts.line_numbers
+            firstLineNumber         : opts.first_line_number
+            showTrailingSpace       : opts.show_trailing_whitespace
+            indentUnit              : opts.indent_unit
+            tabSize                 : opts.tab_size
+            smartIndent             : opts.smart_indent
+            electricChars           : opts.electric_chars
+            undoDepth               : opts.undo_depth
+            matchBrackets           : opts.match_brackets
+            autoCloseBrackets       : opts.auto_close_brackets
+            autoCloseTags           : opts.auto_close_xml_tags
+            lineWrapping            : opts.line_wrapping
+            styleActiveLine         : opts.style_active_line
+            indentWithTabs          : not opts.spaces_instead_of_tabs
+            showCursorWhenSelecting : true
+            extraKeys               : extraKeys
+            cursorScrollMargin      : 40
+            autofocus               : false
+
+        if opts.match_xml_tags
+            options.matchTags = {bothTags: true}
+
+        if opts.code_folding
+             extraKeys["Ctrl-Q"] = (cm) -> cm.foldCodeSelectionAware()
+             options.foldGutter  = true
+             options.gutters     = ["CodeMirror-linenumbers", "CodeMirror-foldgutter"]
+
+        if opts.bindings? and opts.bindings != "standard"
+            options.keyMap = opts.bindings
+            #cursorBlinkRate: 1000
+
+        if opts.theme? and opts.theme != "standard"
+            options.theme = opts.theme
+######
+        cm = CodeMirror.fromTextArea(node, options)
+        cm.save = () => @click_save_button()
+
+        if opts.bindings == 'vim'
+            # annoying due to api change in vim mode
+            cm.setOption("vimMode", true)

     _cm_change: ->
         console.log("_cm_change")


Master: Pass callbacks to our startup functions

--- src/streammachine/modes/master.coffee
+++ src/streammachine/modes/master.coffee
@@ -52,9 +52,9 @@
                     cb null, "OK"

         if nconf.get("handoff")
-            @_handoffStart()
+            @_handoffStart cb
         else
-            @_normalStart()
+            @_normalStart cb

     #----------


Note updated

Note updated

--- site/app.coffee
+++ site/app.coffee
@@ -687,9 +687,9 @@
       wx = w/3
       if w < 600
         wx = w/5
-      ctx.fillText('NOTE: %ILI is not meaningfully comparable between states,', wx, h-24-24 * Math.max(0.7, w / 1000))
-      ctx.fillText('due to differences in reporter types. Color intensity is similar to,', wx, h-24-12 * Math.max(0.7, w / 1000))
-      ctx.fillText('but not identical to, CDC’s Flu Activity Level.', wx, h-24)
+      ctx.fillText('NOTE 1: %ILI is not meaningfully comparable between states, due to differences in reporter types.', wx, h-18-24 * Math.max(0.7, w / 1000))
+      #ctx.fillText('due to differences in reporter types. Color intensity is similar to,', wx, h-24-12 * Math.max(0.7, w / 1000))
+      ctx.fillText('NOTE 2: Color intensity is roughly proportional to CDC’s Flu Activity Level.', wx, h-24)
     return 0

   renderChart: () ->


Basic hash search functionality completed!

--- src/scripts/search-virus-total.coffee
+++ src/scripts/search-virus-total.coffee
@@ -14,9 +14,28 @@
 #   Scott J Roberts - @sroberts

 VIRUS_TOTAL_API_KEY = process.env.VIRUS_TOTAL_API_KEY
+vt_file_report_url = "https://www.virustotal.com/vtapi/v2/file/report"

 module.exports = (robot) ->
   robot.respond /virustotal (.*)/i, (msg) ->
-    # If there's strings generate rule with strings
+    # First paramater is the file hash to look for
+    search_resource = msg.match[1].toLowerCase()

-    # If there aren't then just generate a template
+    parameters = {
+      "apikey": VIRUS_TOTAL_API_KEY,
+      "resource": search_resource
+    }
+
+    data = "apikey=#{encodeURIComponent VIRUS_TOTAL_API_KEY}&resource=#{encodeURIComponent search_resource}"
+
+    robot.http(vt_file_report_url)
+      .post(data) (err, res, body) ->
+        vt_json = JSON.parse(body)
+
+        summary = """ VirusTotal Result: #{vt_json.resource}
+        - Scanned at: #{vt_json.scan_date}
+        - Results:    #{vt_json.positives}/#{vt_json.total}
+        - Link:       #{vt_json.permalink}
+        """
+
+        msg.send summary


Fix missing supers

Fix missing supers

--- src/smc-hub/postgres-synctable.coffee
+++ src/smc-hub/postgres-synctable.coffee
@@ -187,7 +187,9 @@

 class ProjectAndUserTracker extends EventEmitter
-    constructor: (@_db, cb) ->
+    constructor: (_db, cb) ->
+        super()
+        @_db = _db
         dbg = @_dbg('constructor')
         dbg("Initializing Project and user tracker...")
         @setMaxListeners(10000)  # every changefeed might result in a listener on this one object.
@@ -444,7 +446,13 @@
 You must recreate it.
 ###
 class Changes extends EventEmitter
-    constructor: (@_db, @_table, @_select, @_watch, @_where, cb) ->
+    constructor: (_db, _table, _select, _watch, _where, cb) ->
+        super()
+        @_db     = _db
+        @_table  = _table
+        @_select = _select
+        @_watch  = _watch
+        @_where  = _where
         @dbg = @_dbg("constructor")
         @dbg("select=#{misc.to_json(@_select)}, watch=#{misc.to_json(@_watch)}, @_where=#{misc.to_json(@_where)}")
         try
@@ -672,7 +680,15 @@
             return true

 class SyncTable extends EventEmitter
-    constructor: (@_db, @_table, @_columns, @_where, @_where_function, @_limit, @_order_by, cb) ->
+    constructor: (_db, _table, _columns, _where, _where_function, _limit, _order_by, cb) ->
+        super()
+        @_db             = _db
+        @_table          = _table
+        @_columns        = _columns
+        @_where          = _where
+        @_where_function = _where_function
+        @_limit          = _limit
+        @_order_by       = _order_by
         t = SCHEMA[@_table]
         if not t?
             @_state = 'error'


then fix what https://github.com/sagemathinc/cocalc/pull/3385 breaks

--- src/smc-webapp/tasks/hashtag-bar.cjsx
+++ src/smc-webapp/tasks/hashtag-bar.cjsx
@@ -73,7 +73,7 @@
     render: ->
         <Row>
             <Col md={12}>
-                <ButtonGroup style={padding:'5px', overflowY: 'auto'}>
+                <ButtonGroup style={padding:'5px', overflowY: 'auto', maxHeight:'8em'}>
                     {@render_hashtags()}
                 </ButtonGroup>
             </Col>


removed commented out codes

removed commented out codes

--- src/test/tests/testDriverUtils.coffee
+++ src/test/tests/testDriverUtils.coffee
@@ -1,37 +1,3 @@
-# # driver runner
-# simpleDriver = require('../../simpleDriver')
-
-# # Simple
-# diamondsData = require('../../../data/diamonds.js')
-# simpleFn = simpleDriver(diamondsData)
-
-# simpleFn([
-#   { operation: 'split', name: 'Carat', bucket: 'continuous', size: 0.1, offset: 0.005, attribute: 'carat' }
-#   { operation: 'apply', name: 'Count', aggregate: 'count' }
-#   { operation: 'combine', sort: { prop: 'Count', compare: 'natural', direction: 'descending' }, limit: 5 }
-#   { operation: 'split', name: 'Cut', bucket: 'identity', attribute: 'cut' }
-#   { operation: 'apply', name: 'Count', aggregate: 'count' }
-#   { operation: 'combine', sort: { prop: 'Cut', compare: 'natural', direction: 'descending' } }
-# ], (err, result) ->
-#   throw err if err
-#   createTabular = (node, history) ->
-#     newHistory = {}
-#     for k, v of history
-#       newHistory[k] = v
-#     # Base case
-
-#     for k, v of node.prop
-#       newHistory[k] = v
-
-#     if node.splits?
-#       return node.splits.map((split) -> createTabular(split, newHistory))
-#     else
-#       return [newHistory]
-
-#   console.log JSON.stringify(result, null, 2)
-#   console.log JSON.stringify(createTabular(result, {}), null, 2)
-# )
-
 driverUtil = require('../../driverUtil')
 data = require('../data')


BaseGame should check cmd BEFORE checking round.

--- js/token-poker/base-game.coffee
+++ js/token-poker/base-game.coffee
@@ -30,6 +30,7 @@
   sendCommand: (playerName, args) ->
     try
       commandResults = []
+      return if !this.matchedGameCommand(args)
       # TODO: remove coupling into TimedRound class
       # smell - because we're caching plays, but now can no longer just
       # allow the Round instance to throw when it's too soon, so now
@@ -37,7 +38,6 @@
       # if we ever wanted a non-Timed round - this is wrong. We're
       # screwing with the nature of things.
       @round.throwIfNotRestartable() if @round.restartDelaySecondsLeft() > 0
-      return if !this.matchedGameCommand(args)
       playerCommands = @playCache.sendCommand(playerName, args)
       this.ensureRoundStarted()
       for playerCommand in playerCommands


quick update to how logging is configured

--- src/mist-client-js.coffee
+++ src/mist-client-js.coffee
@@ -15,11 +15,11 @@
     # add event capabilities
     Eventify.extend(@)

-    # add logging capabilities
+    # add logging capabilities; logs are disabled by default
     @dash = new dash()
     @dash.setPrefix("Mist")
-    @dash.setLevel(@options.logLevel || "DEBUG")
-    if @options.logsEnabled then @dash.enableLogs()
+    @dash.setLevel(@options.logging.level || "INFO")
+    if @options.logging.enabled then @dash.enableLogs()

     #
     # @on "mist:authenticate.done",     (key, data, args...) => @dash.debug key, data, args


LRSListView now normalises content view into array of views at initialise.

--- src/view.coffee
+++ src/view.coffee
@@ -381,6 +381,10 @@

 		# Check if content is provided and if we have views already (it is assumed initialize is not called anymore after proper initialization).
 		if content and @views.content
+
+			# Normalize content views to array if there is only one.
+			@views.content = [@views.content] unless Array.isArray(@views.content)
+
 			# Yes; it's preloaded content. Use it.
 			@setPreloadedContent(content)
 		else
@@ -406,11 +410,8 @@
 			# Set default to null.
 			view = null

-			# Normalize content views to array if there is only one.
-			views = if Array.isArray(@views.content) then @views.content else [@views.content]
-
 			# Iterate all our content views.
-			for v in views
+			for v in @views.content
 				# If the data-id attribute is the object's id, it belongs to the object; set view and break from loop.
 				if v.el.getAttribute('data-id') is object.id
 					view = v


Redirect user to `/oauth/404` if client does not exists or is inactive

--- oauth.coffee
+++ oauth.coffee
@@ -47,6 +47,11 @@

 		@app.all '/oauth/token', debugMiddleware, @oauth.grant()

+		@app.get '/oauth/authorize', debugMiddleware, Meteor.bindEnvironment (req, res, next) ->
+			if not self.model.Clients.findOne({ active: true, clientId: req.query.client_id })?
+				return res.redirect '/oauth/404'
+
+			next()

 		@app.post '/oauth/authorize', debugMiddleware, Meteor.bindEnvironment (req, res, next) ->
 			if not req.body.token?


Fix zapier not posting with form-urlencoded and transform query to body.

--- oauth.coffee
+++ oauth.coffee
@@ -45,7 +45,15 @@
 				console.log '[OAuth2Server]', req.method, req.url
 			next()

-		@app.all '/oauth/token', debugMiddleware, @oauth.grant()
+		fixZapierNotUsingFormUrlencodedType = (req, res, next) ->
+			if not req.is('application/x-www-form-urlencoded') and req.method is 'POST' and req.get('user-agent') is 'Zapier'
+				if self.config.debug is true
+					console.log '[OAuth2Server]', 'Transforming a request for Zapier. To form-urlencoded and query to body.'
+				req.headers['content-type'] = 'application/x-www-form-urlencoded'
+				req.body = req.query
+			next()
+
+		@app.all '/oauth/token', debugMiddleware, fixZapierNotUsingFormUrlencodedType, @oauth.grant()

 		@app.get '/oauth/authorize', debugMiddleware, Meteor.bindEnvironment (req, res, next) ->
 			client = self.model.Clients.findOne({ active: true, clientId: req.query.client_id })


Fix es6 function folding

Fix es6 function folding

fixes #5

--- lib/fold-functions.coffee
+++ lib/fold-functions.coffee
@@ -86,7 +86,9 @@
       if foldable
         hasFoldableLines = true

-      isFunction = @hasScopeAtBufferRow(editor, row, 'meta.function')
+      isFunction = @hasScopeAtBufferRow(editor, row,
+      'meta.function', 'meta.method.js',
+      'storage.type.arrow.js', 'entity.name.function.constructor.js')
       if foldable and isFunction and not isCommented
         if @indentLevel == null
           @indentLevel = thisIndentLevel
@@ -103,7 +105,13 @@
   unfold: ->
     @fold('unfold')

-  hasScopeAtBufferRow: (editor, row, scope) ->
+  hasScopeAtBufferRow: (editor, row, scopes...) ->
+    for scope in scopes
+      if this._hasScopeAtBufferRow(editor, row, scope)
+        return true
+    false
+
+  _hasScopeAtBufferRow: (editor, row, scope) ->
     found = false
     text = editor.lineTextForBufferRow(row).trim()
     if text.length > 0


Update Atom keymap

Update Atom keymap

--- keymap.cson
+++ keymap.cson
@@ -1,2 +1,29 @@
-'atom-workspace, atom-workspace atom-text-editor':
-  'ctrl-alt-m': 'markdown-preview:toggle'
+'.editor:not(.mini)':
+  'ctrl-shift-M': 'markdown-preview:toggle'
+
+# Default Keymaps for Markdown Writer
+# https://atom.io/packages/markdown-writer
+#
+# Wiki: https://github.com/zhuochun/md-writer/wiki/Settings-for-Keymaps
+#
+".platform-darwin atom-text-editor:not([mini])":
+  "shift-cmd-K": "markdown-writer:insert-link"
+  "shift-cmd-I": "markdown-writer:insert-image"
+  "cmd-i":       "markdown-writer:toggle-italic-text"
+  "cmd-b":       "markdown-writer:toggle-bold-text"
+  "cmd-'":       "markdown-writer:toggle-code-text"
+  "cmd-k":       "markdown-writer:toggle-keystroke-text"
+  "cmd-h":       "markdown-writer:toggle-strikethrough-text"
+  'cmd->':       "markdown-writer:toggle-blockquote"
+  'cmd-"':       "markdown-writer:toggle-codeblock-text"
+  "ctrl-alt-1":  "markdown-writer:toggle-h1"
+  "ctrl-alt-2":  "markdown-writer:toggle-h2"
+  "ctrl-alt-3":  "markdown-writer:toggle-h3"
+  "ctrl-alt-4":  "markdown-writer:toggle-h4"
+  "ctrl-alt-5":  "markdown-writer:toggle-h5"
+  "shift-cmd-O": "markdown-writer:toggle-ol"
+  "shift-cmd-U": "markdown-writer:toggle-ul"
+  "cmd-j cmd-p": "markdown-writer:jump-to-previous-heading"
+  "cmd-j cmd-n": "markdown-writer:jump-to-next-heading"
+  "cmd-j cmd-d": "markdown-writer:jump-to-reference-definition"
+  "cmd-j cmd-t": "markdown-writer:jump-to-next-table-cell"


Escape slashes on windows

Escape slashes on windows

--- src/scope-selector.coffee
+++ src/scope-selector.coffee
@@ -1,5 +1,5 @@
 fs = require 'fs'
-
+path = require 'path'
 PEG = require 'pegjs'

 parser = null
@@ -7,6 +7,7 @@
 createParser = ->
   unless parser?
     matchersPath = require.resolve('./scope-selector-matchers')
+    matchersPath = matchersPath.replace(/\\/g, '\\\\')  if path.sep is '\\'
     matchers = "{ var matchers= require('#{matchersPath}'); }"
     patternPath = require.resolve('../grammars/scope-selector-pattern.pegjs')
     patternContents = "#{matchers}\n#{fs.readFileSync(patternPath, 'utf8')}"


remove ussd from directives action_type

remove ussd from directives action_type

--- static/coffee/flows/directives.coffee
+++ static/coffee/flows/directives.coffee
@@ -153,12 +153,8 @@
       if currentLanguage
         iso_code = currentLanguage.iso_code

-      if action.type in ['send', 'reply', 'say', 'ussd']
-        # TODO: check this for translation
-        if action.type is 'ussd'
-          action._translation = action.msg.message
-        else
-          action._translation = action.msg[iso_code]
+      if action.type in ['send', 'reply', 'say']
+        action._translation = action.msg[iso_code]

         # translated recording for IVR
         if action.recording


Update editor.coffee

Update editor.coffee

Delete new and unused regions when reverting to snapshot

--- src/scripts/editor.coffee
+++ src/scripts/editor.coffee
@@ -675,17 +675,21 @@
                 child.unmount()

             # Handle fixtures vs. standard regions
-            if region.children.length is 1 and region.children[0].isFixed() and snapshot.regions[name] != undefined
-                wrapper = @constructor.createDiv()
-                wrapper.innerHTML = snapshot.regions[name]
-                domRegions.push(wrapper.firstElementChild)
-                region.domElement().parentNode.replaceChild(
-                    wrapper.firstElementChild,
-                    region.domElement()
-                    )
+            if snapshot.regions[name] != undefined
+                if region.children.length is 1 and region.children[0].isFixed()
+                    wrapper = @constructor.createDiv()
+                    wrapper.innerHTML = snapshot.regions[name]
+                    domRegions.push(wrapper.firstElementChild)
+                    region.domElement().parentNode.replaceChild(
+                        wrapper.firstElementChild,
+                        region.domElement()
+                        )
+                else
+                    domRegions.push(region.domElement())
+                    region.domElement().innerHTML = snapshot.regions[name]
             else
-                domRegions.push(region.domElement())
-                region.domElement().innerHTML = snapshot.regions[name]
+                region.domElement().remove();
+                delete @_regions[name]

         # Resync the DOM regions, this is required as fixture will replace the
         # existing DOM region element (regions wont).


Remove enclosing brackets around gitlab push notifiers

The presence of the brackets is inconsistent with the rest of the
messages, and in some services it causes the residing url to break (as
the closing parenthesis is seen as part of the url)

--- src/scripts/gitlab.coffee
+++ src/scripts/gitlab.coffee
@@ -12,7 +12,7 @@
 #   Put http://<HUBOT_URL>:<PORT>/gitlab/system as your system hook
 #   Put http://<HUBOT_URL>:<PORT>/gitlab/web as your web hook (per repository)
 #   You can also append "?targets=%23room1,%23room2" to the URL to control the
-#   message destination.  Using the "target" parameter to override the
+#   message destination.  Using the "target" parameter to override the
 #   GITLAB_CHANNEL configuration value.
 #
 # Commands:
@@ -80,9 +80,9 @@
           branch = hook.ref.split("/")[2..].join("/")
           # if the ref before the commit is 00000, this is a new branch
           if /^0+$/.test(hook.before)
-            message = "#{bold(hook.user_name)} pushed a new branch (#{bold(branch)}) to #{bold(hook.repository.name)} (#{underline(hook.repository.homepage)})"
+            message = "#{bold(hook.user_name)} pushed a new branch (#{bold(branch)}) to #{bold(hook.repository.name)} #{underline(hook.repository.homepage)}"
           else
-            message = "#{bold(hook.user_name)} pushed #{bold(hook.total_commits_count)} commits to #{bold(branch)} in #{bold(hook.repository.name)} (#{underline(hook.repository.homepage + '/compare/' + hook.before.substr(0,9) + '...' + hook.after.substr(0,9))})"
+            message = "#{bold(hook.user_name)} pushed #{bold(hook.total_commits_count)} commits to #{bold(branch)} in #{bold(hook.repository.name)} #{underline(hook.repository.homepage + '/compare/' + hook.before.substr(0,9) + '...' + hook.after.substr(0,9))}"
           robot.send user, message
         # not code? must be a something good!
         else


Remove debug code

Remove debug code

--- src/scripts/loader.coffee
+++ src/scripts/loader.coffee
@@ -5,9 +5,6 @@
   'backbone'
   'cs!router'
 ], (module, $, _, Backbone, router) ->
-
-  console.log module
-  console.log module.config()

   init = () ->
     external = new RegExp('^((f|ht)tps?:)?//')


Improved reply all detection.

Improved reply all detection.

--- app/assets/javascripts/app/controllers/ticket_zoom/article_actions.coffee
+++ app/assets/javascripts/app/controllers/ticket_zoom/article_actions.coffee
@@ -90,7 +90,25 @@
         localRecipients = emailAddresses.parseAddressList(article.cc)
         if localRecipients
           recipients = recipients.concat localRecipients
-      if recipients.length > 1
+
+      # remove system addresses
+      localAddresses = App.EmailAddress.all()
+      forgeinRecipients = []
+      recipientUsed = {}
+      for recipient in recipients
+        localRecipientAddeess = recipient.address.toString().toLowerCase()
+        if !recipientUsed[localRecipientAddeess]
+          recipientUsed[localRecipientAddeess] = true
+          localAddess = false
+          for address in localAddresses
+            if localRecipientAddeess is address.email.toString().toLowerCase()
+              recipientUsed[localRecipientAddeess] = true
+              localAddess = true
+          if !localAddess
+            forgeinRecipients.push recipient
+
+      # check if reply all is neede
+      if forgeinRecipients.length > 1
         actions.push {
           name: 'reply all'
           type: 'emailReplyAll'


line is already a variable

line is already a variable

--- app/graph_drawing.coffee
+++ app/graph_drawing.coffee
@@ -539,7 +539,7 @@
           .data((d) -> d.scatterValues)
           .enter().append('line').each (d) ->
             if d.value
-              line = d3.select(@)
+              l = d3.select(@)
                 .attr('x1', d.x)
                 .attr('x2', d.x)
                 .attr('y1', 0)
@@ -547,10 +547,10 @@
                 .attr('stroke', lineColor)
                 .style('stroke-width', lineWidth)
               if hover
-                line
+                l
                   .style('stroke-opacity', 0)
               else
-                line
+                l
                   .style('stroke-opacity', lineOpacity)

     addTarget = (target, hover) ->


removed debug code

removed debug code

--- app/js/views/fact.coffee
+++ app/js/views/fact.coffee
@@ -75,7 +75,6 @@
     setTimeout (=> @highlighter.dehighlight()), duration

   destroy: ->
-    console.info "DESTROY!!! MUHAHAHAHAHA"
     for el in @elements
       $el = $(el)
       unless $el.is('.fl-first')


Update es-419.coffee

Update es-419.coffee

Finished! :D

--- app/locale/es-419.coffee
+++ app/locale/es-419.coffee
@@ -23,7 +23,7 @@
     profile: "Perfil"
     stats: "Estadísticas"
     code: "Código"
-    admin: "Admin" # Only shows up when you are an admin
+    admin: "Administrador" # Only shows up when you are an admin
     home: "Inicio"
     contribute: "Contribuir"
     legal: "Legal"
@@ -122,7 +122,7 @@
     secondary: "Secundario"
     armor: "Armadura"
     accessories: "Accesorios"
-    misc: "Misc"
+    misc: "Misceláneo"
     books: "Libros"

   common:
@@ -255,7 +255,7 @@
     victory_new_item: "Objeto Nuevo"
     victory_viking_code_school: "Santo cielo, Holy smokes, el nivel que acabas de pasar era dificil! Si todavía no eres un desarrollador de software, deberías serlo. Acabas de conseguir una aceptación por vía rápida con la Escuela Vikinga de Có, donde tú puedes llevar tus habilidades al siguiente nivel y convertirteen un desarrollador web profesional en 14 semanas."
     victory_become_a_viking: "Conviértete en un Vikingo"
-#    victory_bloc: "¡Buen trabajo! Tus habilidades están mejorando, y alguien ya se dió cuenta. Si has considerado convertirte en un desarrollador de software, este podría ser tu día de suerte. Bloc es un online bootcamp que te pairs 1-on-1 with an expert mentor who will help train you into a professional developer! By beating A Mayhem of Munchkins, you're now eligible for a $500 price reduction with the code: CCRULES"
+    victory_bloc: "¡Buen trabajo! Tus habilidades están mejorando, y alguien ya se dió cuenta. Si has considerado convertirte en un desarrollador de software, este podría ser tu día de suerte. Bloc es un campo de entrenamiento online que te conecta 1 a 1 con un mentor experto que te ayudará a entrenarte para convertirte ¡En un desarrollador profesional! Al vencer A Mayhem of Munchkins, eres elegible para una reducción de $500 USD usando el código: CCRULES"
     victory_bloc_cta: "Conoce a tu mentor – aprende acerca de Bloc"
     guide_title: "Guía"
     tome_minion_spells: "Hechizos de tus Secuaces" # Only in old-style levels.
@@ -605,7 +605,7 @@
     title: "CodeCombat para Profesores"
     intro_1: "CodeCombat es un juego online que enseña a programar.Los estudiantes escriben código en idiomas de programación real."
     intro_2: "No se necesita experiencia previa!"
-    free_title: "¿Cuanto cuesta?"
+    free_title: "¿Cuánto cuesta?"
     cost_china: "CodeCombat es gratis en China por los primeros cinco niveles, despues cuesta $9.99(dólares) por mes para tener acceso a 120+ niveles que son exclusivos en nuestros servidores en China." # {change}
     free_1: "CodeCombat Basic es GRATIS! Hay 70+ niveles gratis que cubren cada concepto." # {change}
     free_2: "Una suscripción mensual le da acceso a tutoriales en vídeo y niveles extra para practicar."


hub/client: only send email invitation to collaborators when there is actually an mesg.email body set in the message

--- src/smc-hub/client.coffee
+++ src/smc-hub/client.coffee
@@ -1182,6 +1182,16 @@
                         cb           : cb

                 (cb) =>
+                    # only send an email when there is an mesg.email body to send.
+                    # we want to make it explicit when they're sent, and implicitly disable it for API usage.
+                    if not mesg.email?
+                        locals.done = true
+                    cb()
+
+                (cb) =>
+                    if locals.done
+                        cb(); return
+
                     {one_result} = require('./postgres')
                     @database._query
                         query : "SELECT email_address FROM accounts"
@@ -1191,7 +1201,7 @@
                             cb(err)

                 (cb) =>
-                    if (not locals.email_address)
+                    if (not locals.email_address) or locals.done
                         cb(); return

                     # INFO: for testing this, you have to reset the invite field each time you sent yourself an invitation


Include stack for uncaught exceptions

Include stack for uncaught exceptions

--- src/task-bootstrap.coffee
+++ src/task-bootstrap.coffee
@@ -28,7 +28,8 @@
   global.window = global

 handleEvents = ->
-  process.on 'uncaughtException', (error) -> console.error(error.message)
+  process.on 'uncaughtException', (error) ->
+    console.error(error.message, error.stack)
   process.on 'message', ({args}) ->
     isAsync = false
     async = ->


Adds a comment explaining the awkwardness of the post attachment image fallback

--- models/post.coffee
+++ models/post.coffee
@@ -71,6 +71,11 @@
     @images().first() or
     @attachmentImage()

+  # This takes care of attachments that don't implement
+  # the usual images interface (i.e. post videos or post links).
+  # They *do* often have a single imageSrc, so this returns the
+  # usual methods on a bare object so they can be called normally
+  # (Useful for post thumbnails)
   attachmentImage: ->
     if @attachments().length
       src = _.first(@attachments()).imageSrc()


Fix PostType parsing when fragment is a uri

--- src/tent-client.js.coffee
+++ src/tent-client.js.coffee
@@ -1,7 +1,7 @@
 #= require ./marbles/http/middleware/hawk
 #= require_self

-TYPE_URI_REGEX = /^(.+)\/v(\d+)(?:#(.+)?)?$/
+TYPE_URI_REGEX = /^(.+?)\/v(\d+)(?:#(.+)?)?$/
 URI_TEMPLATE_REGEX = /\{([^\}]+)\}/g

 class @TentClient


up teams

up teams

--- models/team.coffee
+++ models/team.coffee
@@ -37,7 +37,7 @@
 TeamSchema.static 'canRegister', (next) ->
   Team.count null, (err, count) ->
     return next err if err
-    max = 290 + 1 # +1 because team fortnight labs doesn't count
+    max = 295 + 1 # +1 because team fortnight labs doesn't count
     next null, count < max, max - count

 TeamSchema.static 'uniqueName', (name, next) ->


introducing new raw, command escaping

introducing new raw, command escaping


groups: disable options for the group VMs temporarily

--- client/landing/app/Applications/Groups.kdapplication/AppController.coffee
+++ client/landing/app/Applications/Groups.kdapplication/AppController.coffee
@@ -450,16 +450,16 @@
                   { title : "Visible in group listings",    value : "visible" }
                   { title : "Hidden in group listings",     value : "hidden" }
                 ]
-              "Group VM"             :
-                label                : "Create a shared server for the group"
-                itemClass            : KDOnOffSwitch
-                name                 : "group-vm"
-                defaultValue         : no
-              "Member VM"            :
-                label                : "Create a server for each group member"
-                itemClass            : KDOnOffSwitch
-                name                 : "member-vm"
-                defaultValue         : no
+#              "Group VM"             :
+#                label                : "Create a shared server for the group"
+#                itemClass            : KDOnOffSwitch
+#                name                 : "group-vm"
+#                defaultValue         : no
+#              "Member VM"            :
+#                label                : "Create a server for each group member"
+#                itemClass            : KDOnOffSwitch
+#                name                 : "member-vm"
+#                defaultValue         : no

     modal = new KDModalViewWithForms modalOptions


only show create group button if logged in - we should have this check on server side too btw.

--- client/landing/app/Applications/Groups.kdapplication/AppController.coffee
+++ client/landing/app/Applications/Groups.kdapplication/AppController.coffee
@@ -302,14 +302,15 @@
         @openGroup group

   putAddAGroupButton:->
-    {facetsController} = @feedController
-    innerNav = facetsController.getView()
-    innerNav.addSubView addButton = new KDButtonView
-      tooltip   :
-        title   : "Create a Group"
-      style     : "small-gray"
-      iconOnly  : yes
-      callback  : => @showGroupSubmissionView()
+    if KD.isLoggedIn()
+      {facetsController} = @feedController
+      innerNav = facetsController.getView()
+      innerNav.addSubView addButton = new KDButtonView
+        tooltip   :
+          title   : "Create a Group"
+        style     : "small-gray"
+        iconOnly  : yes
+        callback  : => @showGroupSubmissionView()

   _createGroupHandler =(formData)->


#790 remove node count from statistics view

--- app/assets/javascripts/admin/views/statistic/achievement_view.coffee
+++ app/assets/javascripts/admin/views/statistic/achievement_view.coffee
@@ -17,10 +17,6 @@
           Number of Users
           <%= numberOfUsers %>

-

-          Number of Nodes
-          <%= numberOfNodes %>
-

   """)


Updates queued attribute when button is clicked

--- app/assets/javascripts/backbone/apps/movies/list/list_view.js.coffee
+++ app/assets/javascripts/backbone/apps/movies/list/list_view.js.coffee
@@ -16,7 +16,8 @@
     template: 'movies/list/templates/_movie'
     tagName: 'tr'
     events:
-      'click' : 'toggleWatched'
+      'click .watched-btn' : 'toggleWatched'
+      'click .queued-btn' : 'toggleQueued'
       'mouseenter' : 'showOverlay'
       'mouseleave' : 'hideOverlay'

@@ -33,16 +34,20 @@
         this.model.set(watched: false).save()
       else
         this.model.set(watched: true).save()
+
+    toggleQueued: ->
+      if this.model.get('queued') is true
+        this.model.set(queued: false).save()
+      else
+        this.model.set(queued: true).save()
+

     showOverlay: ->
-      # this.$el.find('.main').toggleClass('no-display')
-      this.$el.find('.overlay').toggleClass('no-display')
+      this.$el.find('.overlay').fadeIn(500)

     hideOverlay: ->
-      this.$el.find('.overlay').toggleClass('no-display')
-      # this.$el.find('.main').toggleClass('no-display')
-      # this.$el.find('.overlay').toggleClass('no-display')
+      this.$el.find('.overlay').fadeOut(500)

   class List.MovieCollectionView extends Marionette.CompositeView
     template: 'movies/list/templates/_movies'


Modified in browser at pixie.strd6.com

Modified in browser at pixie.strd6.com

--- test/clamp_bounds.coffee
+++ test/clamp_bounds.coffee
@@ -6,6 +6,6 @@
   player.I.x = - 400
   player.update()

-  equals
+  equals player.I

 module()


Modified in browser at pixie.strd6.com

Modified in browser at pixie.strd6.com

--- test/clamp_bounds.coffee
+++ test/clamp_bounds.coffee
@@ -6,6 +6,6 @@
   player.I.x = - 400
   player.update()

-  equals player.I.x, player.I.width /
+  equals player.I.x, player.I.width / 2

 module()


Fix URL

Fix URL

--- app/assets/javascripts/rglossa/views/cwb/metadata_select_view.coffee
+++ app/assets/javascripts/rglossa/views/cwb/metadata_select_view.coffee
@@ -35,12 +35,13 @@

   createSelect: ->
+    prefix = DS.RESTAdapter.prototype.namespace || ''
     @$().select2
       width: '100%'
       multiple: true
       placeholder: 'Click to select'
       ajax:
-        url: "metadata_categories/#{@get('content.id')}/metadata_values"
+        url: "#{prefix}/metadata_categories/#{@get('content.id')}/metadata_values"
         dataType: 'json'

         data: (term, page) =>


don't passthru click event

don't passthru click event

--- app/assets/javascripts/states/main/views/_date_time_picker.js.coffee
+++ app/assets/javascripts/states/main/views/_date_time_picker.js.coffee
@@ -10,7 +10,9 @@
         text: "input.natural"

     events:
-      "click calendar": ->
+      "click calendar": (e) ->
+        e.stopPropagation()
+        e.preventDefault()
         @ui.calendar.datepicker("show")

       "keyup natural.text": _.debounceR 250, (e) ->


cleanup

cleanup

--- app/assets/javascripts/states/monitoring/views/add_on_call.js.coffee
+++ app/assets/javascripts/states/monitoring/views/add_on_call.js.coffee
@@ -4,22 +4,19 @@
   class exports.AddOnCall extends Stark.View
     el: "div.monitoring_content"
     template: "monitoring/add_on_call"
-    events: {
+    events:
       "click #submit": (e) ->
         oncall = new Bixby.model.OnCall()
-        oncall.set {
+        oncall.set
           name:             @$("#name").val()
           rotation_period:  @$("#rotation_period").val()
           handoff_day:      @$("#handoff_day").val()
           handoff_hour:     @$("#handoff_hour").val()
           handoff_min:      @$("#handoff_min").val()
-        }
         oncall.set_users @$("#users").val()

-        view = @
-        Backbone.multi_save oncall, (err, results) ->
-          view.transition "monitoring", { host: view.host }
-    }
+        Backbone.multi_save oncall, (err, results) =>
+          @transition "monitoring", { host: @host }

     after_render: ->
       @$("select#users").select2()