MER-41: existingEntries -> existingProduct.

--- src/coffee/product-import.coffee
+++ src/coffee/product-import.coffee
@@ -68,29 +68,29 @@
     , []

-  _isExistingEntry: (entry, existingEntries) ->
-    entrySkus = @_extractUniqueSkus([entry])
-    _.find existingEntries, (existingEntry) =>
-      existingEntrySkus =  @_extractUniqueSkus([existingEntry])
-      matchingSkus = _.intersection(entrySkus,existingEntrySkus)
+  _isExistingEntry: (prodToProcess, existingProducts) ->
+    prodToProcessSkus = @_extractUniqueSkus([prodToProcess])
+    _.find existingProducts, (existingEntry) =>
+      existingProductSkus =  @_extractUniqueSkus([existingEntry])
+      matchingSkus = _.intersection(prodToProcessSkus,existingProductSkus)
       if matchingSkus.length > 0
         true
       else
         false

-  _createOrUpdate: (productsToProcess, existingEntries) ->
-    debug 'Products to process: %j', {toProcess: productsToProcess, existing: existingEntries}
+  _createOrUpdate: (productsToProcess, existingProducts) ->
+    debug 'Products to process: %j', {toProcess: productsToProcess, existing: existingProducts}

-    posts = _.map productsToProcess, (entry) =>
-      existingEntry = @_isExistingEntry(entry, existingEntries)
-      if existingEntry?
-        synced = @sync.buildActions(entry, existingEntry)
+    posts = _.map productsToProcess, (prodToProcess) =>
+      existingProduct = @_isExistingEntry(prodToProcess, existingProducts)
+      if existingProduct?
+        synced = @sync.buildActions(prodToProcess, existingProduct)
         if synced.shouldUpdate()
           @client.productsToProcess.byId(synced.getUpdateId()).update(synced.getUpdatePayload())
         else
           Promise.resolve statusCode: 304
       else
-        @client.productsToProcess.create(entry)
+        @client.productsToProcess.create(prodToProcess)

     debug 'About to send %s requests', _.size(posts)
     Promise.all(posts)


:art: Auto-Lint new tabs

:art: Auto-Lint new tabs

--- lib/linter.coffee
+++ lib/linter.coffee
@@ -37,6 +37,7 @@
       CurrentEditorLinter = new EditorLinter @, Editor
       @EditorLinters.set Editor, CurrentEditorLinter
       @Emitter.emit 'linters-observe', CurrentEditorLinter
+      CurrentEditorLinter.lint false
       Editor.onDidDestroy =>
         CurrentEditorLinter.destroy()
         @EditorLinters.delete CurrentEditorLinter


:new: Cache MessageRegexp

:new: Cache MessageRegexp

--- lib/linter.coffee
+++ lib/linter.coffee
@@ -2,6 +2,7 @@
 path = require 'path'
 {CompositeDisposable, Range, Point, BufferedProcess} = require 'atom'
 XRegExp = null
+MessageRegexp = null
 {deprecate} = require('grim')

 # These are NOOPs in linter-plus
@@ -223,8 +224,8 @@
   processMessage: (message, callback) ->
     messages = []
     XRegExp ?= require('xregexp').XRegExp
-    regex = XRegExp @regex, @regexFlags
-    XRegExp.forEach message, regex, (match, i) =>
+    MessageRegexp ?= XRegExp @regex, @regexFlags
+    XRegExp.forEach message, MessageRegexp, (match, i) =>
       msg = @createMessage match
       messages.push msg if msg.range?
     , this


Set minimum size of run /abort buttons

Set minimum size of run /abort buttons

--- web/scripts/referenceUI.coffee
+++ web/scripts/referenceUI.coffee
@@ -168,7 +168,7 @@
     run = jQuery '<img>', {
         id: 'runCode',
         src: '/img/freeware/button_play_green-48px.png',
-        css: {'max-height':'19%', 'display':'block'},
+        css: {'max-height':'19%', 'display':'block', 'min-height': '24px'},
         alt: 'Run Button',
         title:'Run the program',
         click: (e) ->
@@ -186,7 +186,7 @@
     abort = jQuery '<img>', {
         id: 'abortCode',
         src: '/img/freeware/button_stop_red-48px.png',
-        css: {'max-height':'19%', 'display':'block'},
+        css: {'max-height':'19%', 'display':'block', 'min-height': '24px'},
         alt: 'Abort Button',
         title: 'Stop the currently running program',
         click: (e) ->


not-occured-stage-push-null

not-occured-stage-push-null

--- lib/simulate.coffee
+++ lib/simulate.coffee
@@ -201,66 +201,96 @@
     sortieProgress = []

     # Air battle
+    tempList = []
     if req.api_kouku?
       if req.api_kouku.api_stage3?
-        sortieProgress.push new Stage StageType.AerialCombat, simulateAerialCombat sortieShip, enemyShip, req.api_kouku.api_stage3
+        tempList.concat simulateAerialCombat sortieShip, enemyShip, req.api_kouku.api_stage3
       if req.api_kouku.api_stage3_combined?
-        sortieProgress.push new Stage StageType.AerialCombat, simulateAerialCombat combinedShip, enemyShip, req.api_kouku.api_stage3_combined
+        tempList.concat simulateAerialCombat combinedShip, enemyShip, req.api_kouku.api_stage3_combined
+    tempList = null if tempList.length == 0
+    sortieProgress.push new Stage StageType.AerialCombat, tempList

     # Second air battle
+    tempList = []
     if req.api_kouku2?
       if req.api_kouku2.api_stage3?
-        sortieProgress.push new Stage StageType.AerialCombat, simulateAerialCombat sortieShip, enemyShip, req.api_kouku2.api_stage3
+        tempList.concat simulateAerialCombat sortieShip, enemyShip, req.api_kouku2.api_stage3
       if req.api_kouku2.api_stage3_combined?
-        sortieProgress.push new Stage StageType.AerialCombat, simulateAerialCombat combinedShip, enemyShip, req.api_kouku2.api_stage3_combined
+        tempList.concat simulateAerialCombat combinedShip, enemyShip, req.api_kouku2.api_stage3_combined
+    tempList = null if tempList.length == 0
+    sortieProgress.push new Stage StageType.AerialCombat, tempList

     # Support battle
+    tempList = []
     if req.api_support_info?
-      sortieProgress.push new Stage StageType.Support, simulateSupportFire enemyShip, req.api_support_info
+      tempList.concat simulateSupportFire enemyShip, req.api_support_info
+    tempList = null if tempList.length == 0
+    sortieProgress.push new Stage StageType.Support, tempList

     # Opening battle
+    tempList = []
     if req.api_opening_atack?
       if isCombined
-        sortieProgress.push new Stage StageType.TorpedoSalvo, simulateTorpedoSalvo combinedShip, enemyShip, req.api_opening_atack
-      else
-        sortieProgress.push new Stage StageType.TorpedoSalvo, simulateTorpedoSalvo sortieShip, enemyShip, req.api_opening_atack
+        tempList.concat simulateTorpedoSalvo combinedShip, enemyShip, req.api_opening_atack
+      else
+        tempList.concat simulateTorpedoSalvo sortieShip, enemyShip, req.api_opening_atack
+    tempList = null if tempList.length == 0
+    sortieProgress.push new Stage StageType.TorpedoSalvo, tempList

     # First hougeki battle
+    tempList = []
     if req.api_hougeki1?
       if isCombined && !isWater
-        sortieProgress.push new Stage StageType.Shelling, simulateShelling combinedShip, enemyShip, req.api_hougeki1, false
-      else
-        sortieProgress.push new Stage StageType.Shelling, simulateShelling sortieShip, enemyShip, req.api_hougeki1, false
+        tempList.concat simulateShelling combinedShip, enemyShip, req.api_hougeki1, false
+      else
+        tempList.concat simulateShelling sortieShip, enemyShip, req.api_hougeki1, false
+    tempList = null if tempList.length == 0
+    sortieProgress.push new Stage StageType.Shelling, tempList

     # Combined fleet raigeki
+    tempList = []
     if req.api_raigeki? && isCombined && !isWater
-      sortieProgress.push new Stage StageType.TorpedoSalvo, simulateTorpedoSalvo combinedShip, enemyShip, req.api_raigeki
+      tempList.concat simulateTorpedoSalvo combinedShip, enemyShip, req.api_raigeki
+    tempList = null if tempList.length == 0
+    sortieProgress.push new Stage StageType.TorpedoSalvo, tempList

     # Second hougeki battle
+    tempList = []
     if req.api_hougeki2?
-      sortieProgress.push new Stage StageType.Shelling, simulateShelling sortieShip, enemyShip, req.api_hougeki2, false
+      tempList.concat simulateShelling sortieShip, enemyShip, req.api_hougeki2, false
+    tempList = null if tempList.length == 0
+    sortieProgress.push new Stage StageType.Shelling, tempList

     # Combined hougeki battle
+    tempList = []
     if req.api_hougeki3?
       if isCombined && isWater
-        sortieProgress.push new Stage StageType.Shelling, simulateShelling combinedShip, enemyShip, req.api_hougeki3, false
-      else
-        sortieProgress.push new Stage StageType.Shelling, simulateShelling sortieShip, enemyShip, req.api_hougeki3, false
+        tempList.concat simulateShelling combinedShip, enemyShip, req.api_hougeki3, false
+      else
+        tempList.concat simulateShelling sortieShip, enemyShip, req.api_hougeki3, false
+    tempList = null if tempList.length == 0
+    sortieProgress.push new Stage StageType.Shelling, tempList

     # Raigeki battle
+    tempList = []
     if req.api_raigeki?
       if isCombined
         if isWater
-          sortieProgress.push new Stage StageType.TorpedoSalvo, simulateTorpedoSalvo combinedShip, enemyShip, req.api_raigeki
-      else
-        sortieProgress.push new Stage StageType.TorpedoSalvo, simulateTorpedoSalvo sortieShip, enemyShip, req.api_raigeki
+          tempList.concat simulateTorpedoSalvo combinedShip, enemyShip, req.api_raigeki
+      else
+        tempList.concat simulateTorpedoSalvo sortieShip, enemyShip, req.api_raigeki
+    tempList = null if tempList.length == 0
+    sortieProgress.push new Stage StageType.TorpedoSalvo, tempList

     # Night battle
+    tempList = []
     if req.api_hougeki?
       if isCombined
-        sortieProgress.push new Stage StageType.Shelling, simulateShelling combinedShip, enemyShip, req.api_hougeki, true
-      else
-        sortieProgress.push new Stage StageType.Shelling, simulateShelling sortieShip, enemyShip, req.api_hougeki, true
+        tempList.concat simulateShelling combinedShip, enemyShip, req.api_hougeki, true
+      else
+        tempList.concat simulateShelling sortieShip, enemyShip, req.api_hougeki, true
+    tempList = null if tempList.length == 0
+    sortieProgress.push new Stage StageType.Shelling, tempList

     sortieProgress


add parsing for Ok end Err

add parsing for Ok end Err

--- lib/sm-state.coffee
+++ lib/sm-state.coffee
@@ -45,14 +45,14 @@
         { name: 'newRootStructureMsg', from: 'readingUpdateFunctionState', to: 'waitingState' } ,
         { name: 'readModuleString', from: 'waitingState', to: 'readingModuleString' } ,
       ] } )
-
+
     return

   _parseUpateFunction: =>
     lines = @structure.specialFunctions.update.split('\n')
     lineCheckRegExp = new RegExp("^\ *(\\S)")
     caseStartRegExp = new RegExp("case\ +\\(.+\,.+\\)\ +of")
-    transitionHeaderRegExp = new RegExp("\\(\ *(\\w+State).*\,\ *([A-Z]\\w+)\.*\\)\ *\-\>")
+    transitionHeaderRegExp = new RegExp("\\(\ *(\\w+State).*\,\ *([A-Z]\\w+)(\\ +\\(\\ *[Ok|Err].*\\ *\\))?\.*\\)\ *\-\>")
     transitionFinRegExp = new RegExp("\\{.+\\|.*state\\ *\\=\\ *(\\w+State).*\\}")

     getIndent = (line) ->
@@ -74,12 +74,19 @@
               transitions.push(state.transition)
               state = null

+            msg = match[2]
+            if match[3]
+              if match[3].indexOf('Ok') isnt -1
+                msg += ' Ok'
+              if match[3].indexOf('Err') isnt -1
+                msg += ' Err'
+
             state = {
               indent: indent
               match: match
               transition: {
                 from: match[1]
-                msg: match[2]
+                msg: msg
                 to: null
               }
             }


white backgroundcolor for fullscreen

white backgroundcolor for fullscreen

--- framer/Components/DeviceComponent.coffee
+++ framer/Components/DeviceComponent.coffee
@@ -92,7 +92,6 @@
 		@phone.backgroundColor = "transparent"
 		@phone.classList.add("DevicePhone")

-		@screen.backgroundColor = "black"
 		@screen.classList.add("DeviceScreen")
 		@screen.clip = true

@@ -136,6 +135,8 @@
 			@content.scale = contentScaleFactor
 			@_positionKeyboard()

+			@screen.backgroundColor = "white"
+
 		else
 			backgroundOverlap = 100

@@ -160,6 +161,8 @@
 			@screen.center()

 			@setHand(@selectedHand) if @selectedHand && @_orientation == 0
+
+			@screen.backgroundColor = "black"

 	_shouldRenderFullScreen: ->


pass options context object in views

pass options context object in views

--- lib/ui/views.coffee
+++ lib/ui/views.coffee
@@ -6,7 +6,7 @@
 getlazy = client.import 'getlazy'

 module.exports = views =
-  dom: ({tag, attrs, contents}) ->
+  dom: ({tag, attrs, contents}, opts) ->
     view = document.createElement tag
     for k, v of attrs
       if v instanceof Array then v = v.join ' '
@@ -15,7 +15,7 @@
       if contents.constructor isnt Array
         contents = [contents]
       for child in contents
-        view.appendChild @render child
+        view.appendChild @render child, opts
     view

   html: ({content}) ->
@@ -23,32 +23,32 @@
     view.innerHTML = content
     view = if view.children.length == 1 then view.children[0] else view

-  tree: ({head, children, expand}) ->
-    @ink.tree.treeView(@render(head),
-                       children.map((x)=>@render @tags.div [x]),
+  tree: ({head, children, expand}, opts) ->
+    @ink.tree.treeView(@render(head, opts),
+                       children.map((x)=>@render(@tags.div([x]), opts)),
                        expand: expand)

-  lazy: ({head, id}) ->
+  lazy: ({head, id}, opts) ->
     conn = client.conn
-    view = @ink.tree.treeView @render(head), [],
+    view = @ink.tree.treeView @render(head, opts), [],
       onToggle: once =>
         return unless client.conn == conn
         getlazy(id).then (children) =>
           body = view.querySelector ':scope > .body'
-          children.map((x) => @render x).forEach (x) ->
+          children.map((x) => @render(x, opts)).forEach (x) ->
             body.appendChild x

   subtree: ({label, child}) ->
-    @render if child.type == "tree"
+    @render (if child.type == "tree"
       type: "tree"
       head: @tags.span [label, child.head]
       children: child.children
       # children: child.children.map((x) => @tags.span "gutted", x)
     else
-      @tags.span "gutted", [label, child]
+      @tags.span "gutted", [label, child]), opts

-  copy: ({view, text}) ->
-    view = @render view
+  copy: ({view, text}, opts) ->
+    view = @render view, opts
     atom.commands.add view,
       'core:copy': (e) ->
         atom.clipboard.write text
@@ -110,9 +110,9 @@
     number:  (a...) -> views.number a...
     code:    (a...) -> views.code a...

-  render: (data) ->
+  render: (data, opts = {}) ->
     if @views.hasOwnProperty(data.type)
-      @views[data.type](data)
+      @views[data.type](data, opts)
     else if data?.constructor is String
       new Text data
     else


prefer python3

prefer python3

--- lib/wakatime.coffee
+++ lib/wakatime.coffee
@@ -278,9 +278,12 @@
     if not locations?
       locations = [
         __dirname + path.sep + 'python' + path.sep + 'pythonw',
+        'python3',
         'pythonw',
         'python',
+        '/usr/local/bin/python3',
         '/usr/local/bin/python',
+        '/usr/bin/python3',
         '/usr/bin/python',
       ]
       i = 26


fix if-statement

fix if-statement

--- app/controllers/classifier.coffee
+++ app/controllers/classifier.coffee
@@ -421,7 +421,7 @@
       @el.find('#ukirt-url').attr("href", ukirtUrl)
       @el.find(".K1").display("block")
       @el.find(".K2").display("none")
-    else if
+    else
       @el.find('#manitude').html   (metadata.magnitudes["kepler"])
       @el.find(".K1").display("none")
       @el.find(".K2").display("block")


remove simuation classifier

remove simuation classifier

--- app/controllers/classifier.coffee
+++ app/controllers/classifier.coffee
@@ -373,10 +373,7 @@
       jsonFile = @subject.selected_light_curve.location.replace("http://www.planethunters.org/", "https://s3.amazonaws.com/zooniverse-static/planethunters.org/")
     else
       jsonFile = @subject.selected_light_curve.location
-      console.log jsonFile
-
-
-    jsonFile = 'offline/simulation_feedback_example.json'
+
     # console.log 'jsonFile: ', jsonFile

     # handle ui elements


Check availability of path.

Check availability of path.

In some cases (like editing the config.cson) path can to something line atom://config

--- lib/runner.coffee
+++ lib/runner.coffee
@@ -52,8 +52,9 @@
     workingDirectoryProvided = cwd? and cwd isnt ''
     paths = atom.project.getPaths()
     if not workingDirectoryProvided and paths?.length > 0
-      cwd = if fs.statSync(paths[0]).isDirectory() then paths[0] else path.join(paths[0], '..')
-
+      try
+        cwd = if fs.statSync(paths[0]).isDirectory() then paths[0] else path.join(paths[0], '..')
+
     cwd

   stop: ->
@@ -102,7 +103,11 @@
     project_path = ''
     paths = atom.project.getPaths()
     if paths.length > 0
-      project_path = if fs.statSync(paths[0]).isDirectory() then paths[0] else path.join(paths[0], '..')
+      fs.stat(paths[0], (err, stats) ->
+        if !err
+          project_path = if stats.isDirectory() then paths[0] else path.join(paths[0], '..')
+      )
+
     args = (@fillVarsInArg arg, codeContext, project_path for arg in args)

     if not @scriptOptions.cmd? or @scriptOptions.cmd is ''


Stop propagation of keydown events when console is open. Fixes #13

--- app/scripts/views/console.coffee
+++ app/scripts/views/console.coffee
@@ -19,7 +19,6 @@
     rawTemplate: template

     events:
-      "keydown": "onKeyDown"
       "click .settings": "openSettings"

     initialize: ->
@@ -29,6 +28,8 @@

       @keepFocused()
       @escapeClose()
+
+      document.addEventListener "keydown", @onKeyDown, true

       App.on "load.commands sync.commands",  =>
         return unless @$input
@@ -73,7 +74,9 @@
     openSettings: ->
       Extension.trigger "open.settings"

-    onKeyDown: (e) ->
+    onKeyDown: (e) =>
+      return unless App.open
+      e.stopPropagation()
       preventDefault = true
       unless App.loading
         switch e.which


Bad state, bad

Bad state, bad

--- lib/script.coffee
+++ lib/script.coffee
@@ -10,4 +10,4 @@
     @scriptView.destroy()

   serialize: ->
-    scriptViewState: @scriptViewState.serialize()
+    scriptViewState: @scriptView.serialize()


measuring was off

measuring was off


send ddgof error from client if there is a configured ddog api key

--- lib/server.coffee
+++ lib/server.coffee
@@ -13,6 +13,36 @@
 catch err
 	canprogress = false
 	refreshrate = 5
+
+ddogevent = (datadogapikey,title, text, alert_type, tags = [], priority = "normal")->
+	post_data = JSON.stringify ({
+		title:title,
+		text:text,
+		priority:priority,
+		tags:tags,
+		alert_type:alert_type
+	})
+	post_req = require("https").request {
+			hostname: 'app.datadoghq.com',
+			port    : '443',
+			path    : "/api/v1/events?api_key=#{datadogapikey}",
+			method  : 'POST',
+			headers : {
+				'Content-Type': 'application/json',
+				'Cache-Control': 'no-cache',
+				'Content-Length': post_data.length
+			}
+		},(res)->
+			body = ''
+			res.on 'data', (chunk)->
+				body += chunk;
+			res.on 'end', ->
+				jsonresponse = JSON.parse(body)
+				console.log("Got a response: ", jsonresponse)
+	post_req.on 'error', (e)->
+		console.error "problem with ddog post: #{e.message}"
+	post_req.write(post_data)
+	post_req.end()

 main = ->
 	col = {}
@@ -681,6 +711,8 @@
 							console.log 'stdout', cmd, stdout
 						if error
 							console.log 'error', c._id, cmd1, cmd, error
+							cmdname = (c.exec.split("/").pop()).split(" ")[0]
+							ddogevent options.datadogapikey,"zmquer: #{os.hostname()}: #{cmdname}", c.error, "#{c._id} error", tags = ["host:#{os.hostname()}","cmd:#{cmd1}"], priority = "normal" if options.datadogapikey?
 						#check if there is a file output
 						file_ret = if fs.existsSync(env.TMPDIR + c._id + '_out.json') then fs.readFileSync(process.env.TMPDIR + c._id + '_out.json', 'utf8') else null
 						#sending back the status


Add Gherkin (Cucumber) to grammars.coffee

--- lib/grammars.coffee
+++ lib/grammars.coffee
@@ -95,3 +95,8 @@
     command: "coffee"
     "Selection Based": (code) -> ['-e', code]
     "File Based": (filename) -> [filename]
+
+  Gherkin:
+    command: "cucumber"
+    #"Selection Based": (code) -> ['-e', code]
+    "File Based": (filename) -> [filename]


Use child_process.exec to chmod atom cli

--- src/app/window.coffee
+++ src/app/window.coffee
@@ -1,6 +1,6 @@
 fs = require 'fs'
 $ = require 'jquery'
-ChildProcess = require 'child-process'
+ChildProcess = nodeRequire 'child_process'
 require 'jquery-extensions'
 require 'underscore-extensions'
 require 'space-pen-extensions'