Added support to override logic for setting session and reactive variables when binding.

--- src/Templates.coffee
+++ src/Templates.coffee
@@ -50,9 +50,9 @@
           value = parseFloat(value)
           unless Numbers.isDefined(value)
             value = null
-          else if Numbers.isDefined(min) && value < min
+          else if Numbers.isDefined(min) and value < min
             value = min
-          else if Numbers.isDefined(max) && value > max
+          else if Numbers.isDefined(max) and value > max
             value = max
         value
       getValue: -> $(this).val()
@@ -88,18 +88,23 @@
     reactiveVar ?= new ReactiveVar()
     options = _.extend({
       template: Template.instance()
+      setSession: (name, value) -> Session.set(name, value)
+      setReactiveVariable: (reactiveVar, value) -> reactiveVar.set(value)
+      getSession: (name) -> Session.get(name)
+      getReactiveVariable: (reactiveVar) -> reactiveVar.get()
     }, options)
     options.template.autorun ->
-      value = Session.get(sessionVarName)
-      reactiveValue = Tracker.nonreactive -> reactiveVar.get()
+      value = options.getSession(sessionVarName)
+      reactiveValue = Tracker.nonreactive -> options.getReactiveVariable(reactiveVar)
       # Prevent setting undefined on an existing reactive variable value if the session has not
       # yet been set.
-      unless value == undefined and reactiveValue? then reactiveVar.set(value)
+      unless value == undefined and reactiveValue?
+        options.setReactiveVariable(reactiveVar, value)
     options.template.autorun ->
-      value = reactiveVar.get()
+      value = options.getReactiveVariable(reactiveVar)
       # Since the reactive variable was only set if the session was defined, the session can be
       # safely set with the reactive variable value.
-      Session.set(sessionVarName, value)
+      options.setSession(sessionVarName, value)
     reactiveVar

   get: (templateOrName) ->


Run URI handlers in last non-spec window

--- src/main-process/atom-application.coffee
+++ src/main-process/atom-application.coffee
@@ -191,8 +191,8 @@
   getAllWindows: () =>
     @windows.all().slice()

-  getLastFocusedWindow: () =>
-    @windows.getLastFocusedWindow()
+  getLastFocusedWindow: (predicate) =>
+    @windows.getLastFocusedWindow(predicate)

   # Creates server to listen for additional atom application launches.
   #
@@ -672,8 +672,10 @@
         resourcePath = @devResourcePath

     windowInitializationScript ?= require.resolve('../initialize-application-window')
-    if @getLastFocusedWindow()?
-      @getLastFocusedWindow().sendURIMessage url
+    lastNonSpecWindow = @getLastFocusedWindow (win) -> !win.isSpecWindow()
+    if lastNonSpecWindow?
+      lastNonSpecWindow.sendURIMessage url
+      lastNonSpecWindow.focus()
     else
       windowDimensions = @getDimensionsForNewWindow()
       win = new AtomWindow(this, @fileRecoveryService, {resourcePath, windowInitializationScript, devMode, safeMode, windowDimensions, env})


modify error message

modify error message

--- web-app/src/app/result/result-model.coffee
+++ web-app/src/app/result/result-model.coffee
@@ -23,4 +23,4 @@
       jqxhr.fail =>
         @set
           loading: false
-          error: 'An error occurred.'+          error: 'Server returned an error.'


fullpieagent testing

fullpieagent testing

--- widgets/fullpie_agent/fullpie_agent.coffee
+++ widgets/fullpie_agent/fullpie_agent.coffee
@@ -114,7 +114,7 @@
       color i
     #@path.transition().duration(1500).attrTween 'd', that.pieTween
     path.transition()
-        .duration(1500)
+        .duration(1000)
         #.attrTween("d", pieTween)
         .attrTween("d", (d,i) ->
             console.log("d",d)


Agent pie: edit label transition

Agent pie: edit label transition

--- widgets/fullpie_agent/fullpie_agent.coffee
+++ widgets/fullpie_agent/fullpie_agent.coffee
@@ -309,7 +309,7 @@
             #.attr('stroke-width', 1)
             .attr('marker-end', 'url(#circ)')
             #.style('opacity', 0)
-        #pointers.exit().remove()
+        pointers.exit().remove()

         pointers.transition().duration(2000).attr('d', (d) ->
                 console.log('label transition d: ',d)
@@ -319,7 +319,6 @@
                     return 'M' + (d.r - 2) + ',' + d.b + 'L' + (d.l + 2) + ',' + d.b + ' ' + d.cx + ',' + d.cy
             )
             #.style('opacity', 1)
-        pointers.exit().remove()

         # Display total count
         totalTickets = 0


removing reference to underscore from footer.coffee

--- src/scripts/modules/footer/footer.coffee
+++ src/scripts/modules/footer/footer.coffee
@@ -1,5 +1,4 @@
 define (require) ->
-  _ = require('underscore')
   settings = require('settings')
   BaseView = require('cs!helpers/backbone/views/base')
   template = require('hbs!./footer-template')
@@ -9,7 +8,7 @@
   return class FooterView extends BaseView
     template: template
     templateHelpers: () ->
-      location.origin = socialMedia.locationOriginPolyFillForIe()
+      location.origin = socialMedia.locationOrigin()

       return {
         share: socialMedia.socialMediaInfo('','An OpenStax College book')


set missing enter/leave timeouts

set missing enter/leave timeouts

--- tutor/src/components/task/review.cjsx
+++ tutor/src/components/task/review.cjsx
@@ -40,7 +40,11 @@
         />
       .value()

-    <ReactCSSTransitionGroup transitionName="homework-review-problem">
+    <ReactCSSTransitionGroup
+      transitionName="homework-review-problem"
+      transitionEnterTimeout={300}
+      transitionLeaveTimeout={300}
+    >
       {stepsList}
     </ReactCSSTransitionGroup>


need to get/re-set for list attrs

need to get/re-set for list attrs

--- bokehjs/src/coffee/common/tool_manager.coffee
+++ bokehjs/src/coffee/common/tool_manager.coffee
@@ -66,12 +66,15 @@
       gestures = @get('gestures')

       for tool in @get('tools')
-
         if tool instanceof InspectTool.Model
-          @get('inspectors').push(tool)
+          inspectors = @get('inspectors')
+          inspectors.push(tool)
+          @set('inspectors', inspectors)

         else if tool instanceof ActionTool.Model
-          @get('actions').push(tool)
+          actions = @get('actions')
+          actions.push(tool)
+          @set('actions', actions)

         else if tool instanceof GestureTool.Model
           et = tool.get('event_type')


Fix ship type

Fix ship type

--- plugins/owned-list/parts/ship-info/views/ship-info-checkbox-area.cjsx
+++ plugins/owned-list/parts/ship-info/views/ship-info-checkbox-area.cjsx
@@ -1,27 +1,26 @@
 {React, ReactBootstrap, jQuery} = window
 {Panel, Button, Input, Col, Grid} = ReactBootstrap
 Divider = require './divider'
-shipTypes = ['', '海防艦', '駆逐艦', '軽巡洋艦', '重雷装巡洋艦', '重巡洋艦', '航空巡洋艦', '軽空母', '戦艦', '航空戦艦', '正規空母',
-             '潜水艦', '潜水空母', '水上機母艦', '揚陸艦', '装甲空母', '工作艦', '潜水母艦', '練習巡洋艦']
-
+shipTypes = ['', '海防艦', '駆逐艦', '軽巡洋艦', '重雷装巡洋艦', '重巡洋艦', '航空巡洋艦', '軽空母', '戦艦', '戦艦', '航空戦艦', '正規空母',
+             '超弩級戦艦', '潜水艦', '潜水空母', '補給艦', '水上機母艦', '揚陸艦', '装甲空母', '工作艦', '潜水母艦', '練習巡洋艦']
 ShipInfoCheckboxArea = React.createClass
   getInitialState: ->
-    checked: [false, false, true, true, true, true, true, true, true, true, true, true,
+    checked: [false, true, true, true, true, true, true, true, true, true, true, true,
               true, true, true, true, true, true, true, true, true, true, true, true]
     order: 0
     sortKey: 'id'
   handleClickAscend: ->
     @setState
       order: 0
-    @props.sortRules(@state.sortKey, @state.order)
+    @props.sortRules(@state.sortKey, 0)
   handleClickDescend: ->
     @setState
       order: 1
-    @props.sortRules(@state.sortKey, @state.order)
+    @props.sortRules(@state.sortKey, 1)
   handleKeyChange: (e) ->
     @setState
       sortKey: e.target.value
-    @props.sortRules(@state.sortKey, @state.order)
+    @props.sortRules(e.target.value, @state.order)
   handleClickCheckbox: (index) ->
     checkboxes = []
     {checked} = @state
@@ -65,7 +64,7 @@
       <Grid id='ship-info-filter'>
       {
         for shipType, index in shipTypes
-          continue if index < 2
+          continue if index < 1 || shipType == shipTypes[index - 1]
           <Col key={index} xs={2}>
             <Input type='checkbox' label={shipType} key={index} value={index} onChange={@handleClickCheckbox.bind(@, index)} checked={@state.checked[index]} />
           </Col>


Add data InPort

Add data InPort

--- spec/SendRequest.coffee
+++ spec/SendRequest.coffee
@@ -5,21 +5,26 @@
 describe 'SendRequest component', ->
   c = null
   url = null
+  data = null
   start = null

   beforeEach ->
     c = SendRequest.getComponent()
     url = noflo.internalSocket.createSocket()
+    data = noflo.internalSocket.createSocket()
     start = noflo.internalSocket.createSocket()
     request = noflo.internalSocket.createSocket()

     c.inPorts.url.attach url
+    c.inPorts.data.attach data
     c.inPorts.start.attach start
     c.outPorts.request.attach request

   describe 'when instantiated', ->
     it 'should have a "url" inport', ->
       chai.expect(c.inPorts.url).to.be.an 'object'
+    it 'should have a "data" inport', ->
+      chai.expect(c.inPorts.data).to.be.an 'object'
     it 'should have a "start" inport', ->
       chai.expect(c.inPorts.start).to.be.an 'object'
     it 'should have a "request" outport', ->


Experiment with longer timeout on Mac CI

--- spec/spec-helper.coffee
+++ spec/spec-helper.coffee
@@ -45,8 +45,7 @@

 jasmine.getEnv().addEqualityTester(_.isEqual) # Use underscore's definition of equality for toEqual assertions

-if process.platform is 'win32' and process.env.JANKY_SHA1
-  # Use longer timeout on Windows CI
+if process.env.JANKY_SHA1
   jasmine.getEnv().defaultTimeoutInterval = 60000
 else
   jasmine.getEnv().defaultTimeoutInterval = 5000


:fire: old code, and expose rawKeystroke

--- spec/spec-helper.coffee
+++ spec/spec-helper.coffee
@@ -73,38 +73,14 @@
       key = key[key.length - 1] if key.startsWith('shift-')
       key if key.length is 1

-# --[START] I want to use this in future
-newKeydown = (key, target) ->
+keydown = (key, target) ->
   target ?= document.activeElement
   event = buildKeydownEventFromKeystroke(key, target)
   atom.keymaps.handleKeyboardEvent(event)

-  # unless event.defaultPrevented
-  #   editor = atom.workspace.getActiveTextEditor()
-  #   target = getHiddenInputElementForEditor(editor)
-  #   char = ' ' if key is 'space'
-  #   char ?= characterForKeyboardEvent(event)
-  #   target.dispatchEvent(buildTextInputEvent(char)) if char?
-
-newKeystroke = (keystrokes, target) ->
+rawKeystroke = (keystrokes, target) ->
   for key in normalizeKeystrokes(keystrokes).split(/\s+/)
-    newKeydown(key, target)
-# --[END] I want to use this in future
-
-keydown = (key, options) ->
-  event = buildKeydownEvent(key, options)
-  atom.keymaps.handleKeyboardEvent(event)
-
-_keystroke = (keys, event) ->
-  if keys in ['escape', 'backspace']
-    keydown(keys, event)
-  else
-    for key in keys.split('')
-      if key.match(/[A-Z]/)
-        event.shift = true
-      else
-        delete event.shift
-      keydown(key, event)
+    keydown(key, target)

 isPoint = (obj) ->
   if obj instanceof Point
@@ -361,7 +337,7 @@

     for k in toArray(keys)
       if _.isString(k)
-        newKeystroke(k, target)
+        rawKeystroke(k, target)
       else
         switch
           when k.input?
@@ -370,6 +346,6 @@
             @vimState.searchInput.editor.insertText(k.search)
             atom.commands.dispatch(@vimState.searchInput.editorElement, 'core:confirm')
           else
-            newKeystroke(k, target)
-
-module.exports = {getVimState, getView, dispatch, TextData, withMockPlatform}
+            rawKeystroke(k, target)
+
+module.exports = {getVimState, getView, dispatch, TextData, withMockPlatform, rawKeystroke}


fixes bug with setting event versions in commit store

--- source/infrastructure/commit_store.coffee
+++ source/infrastructure/commit_store.coffee
@@ -28,6 +28,7 @@

       newVersion = currentVersion + 1

+      @_setEventVersion(event, newVersion) for event in changes.events
       # serialize events and commands
       serializedChanges = events: [], commands: []
       serializedChanges.events.push(EJSON.stringify(event)) for event in changes.events
@@ -78,6 +79,7 @@
           event = EJSON.parse(event)
         catch error
           throw new Error "while parsing commit\nevent:#{event}\nerror:#{error}"
-        event.version = commit.version
         events.push event
     return events
+
+  _setEventVersion: (event, version) -> event.version = version


Add tests for persisting new data

Add tests for persisting new data

--- specs/access/async-properties.spec.coffee
+++ specs/access/async-properties.spec.coffee
@@ -4,7 +4,7 @@
 should = require('should')
 path = require('path')

-db = event = null
+db = event = newEvent =  null
 specRoot = path.resolve(__dirname, '..')

 before (done) ->
@@ -54,3 +54,25 @@
             event.promotion (err, promotion) ->
                 promotion.should.eql("Uh oh! Promotion is over!")
                 done()
+
+    it 'init a new event', () ->
+        newEvent = db.event { name: 'Test event', date: new Date(), promotionId: 2 }
+
+    it 'get promotion, async', (done) ->
+        newEvent.promotion (err, promotion) ->
+            return done(err) if err
+            promotion.should.eql(h.testData.promotions[1].name)
+            done()
+
+    it 'setPersisting', (done) ->
+        data = {
+            name: "Yeah, i change the name again"
+            promotion: "Win a MAC PRO!"
+        }
+        newEvent.setPersisting data, (err) ->
+            return done(err) if err
+            newEvent.id.should.be.eql(h.testData.events.length + 1)
+            newEvent.promotion (err, promotion) ->
+                return done(err) if err
+                promotion.should.eql("Win a MAC PRO!")
+                done()


collision

collision

--- src/collision.coffee
+++ src/collision.coffee
@@ -10,23 +10,23 @@
   Bounds objects have x, y, width and height properties.

-     player = GameObject
-       x: 0
-       y: 0
-       width: 10
-       height: 10
-
-     enemy = GameObject
-       x: 5
-       y: 5
-       width: 10
-       height: 10
-
-     Collision.rectangular(player, enemy)
-  => true
-
-     Collision.rectangular(player, {x: 50, y: 40, width: 30, height: 30})
-  => false
+  player = GameObject
+    x: 0
+    y: 0
+    width: 10
+    height: 10
+
+  enemy = GameObject
+    x: 5
+    y: 5
+    width: 10
+    height: 10
+
+  Collision.rectangular(player, enemy)
+  # => true
+
+  Collision.rectangular(player, {x: 50, y: 40, width: 30, height: 30})
+  # => false

   @name rectangular


support slashes in gist urls

support slashes in gist urls

--- app/app.coffee
+++ app/app.coffee
@@ -191,7 +191,7 @@
   mixins: [AppAwareMixin]
   render: ->
     {imports, module_names} = @context.app
-    gist = @props.params.gist
+    gist = @props.params.splat
     Notebook.NotebookComponent {context: {app: @context.app}, imports, module_names, init: (notebook) ->
       Notebook.run_without_input_cell notebook, null, (ctx) ->
         GitHub.context_fns.gist.fn ctx, gist, run: true
@@ -289,7 +289,7 @@
           this.transitionTo 'notebook'
       Route {name: 'notebook', handler: NewNotebookComponent}
       Route {path: '/notebook/raw/*', name: 'raw_notebook', handler: Base64EncodedNotebookCellComponent, addHandlerKey: true}
-      Route {path: '/notebook/gist/:gist', name: 'gist_notebook', handler: GistNotebookComponent, addHandlerKey: true}
+      Route {path: '/notebook/gist/*', name: 'gist_notebook', handler: GistNotebookComponent, addHandlerKey: true}
       Route {path: '/builder', handler: BuilderAppComponent}
       Route {path: '/help', name: 'help-index', handler: HelpComponent}
       Route {path: '/help/:key', name: 'help', handler: HelpComponent, addHandlerKey: true}


:wrench: ignore duplicate key errors

:wrench: ignore duplicate key errors

--- app/bot.coffee
+++ app/bot.coffee
@@ -39,7 +39,7 @@
         fav.save callback
     ], (err)->
       return cb err if cb
-      throw err if err
+      throw err if err and err.code != 11000  # ignore duplicate key errors

   get_keywords: ()->
     return @keywords


reactivate textChat

reactivate textChat

--- src/core/room.coffee
+++ src/core/room.coffee
@@ -28,7 +28,7 @@
 class _Room
     # Initialize a nodemailer module and a list of modules
     # with default values.
-    constructor : (@modulesList = ['userList']) -> # [ 'userList', 'textChat', 'camera', 'notification', 'tutorial' ]
+    constructor : (@modulesList = [ 'userList' , 'textChat' ]) -> # [ 'camera', 'notification', 'tutorial' ]
         @transport = nodemailer.createTransport('Sendmail');
         @token  = Token


IDE: Select all characters on rename input of terminal

--- client/ide/lib/views/tabview/idetabhandleview.coffee
+++ client/ide/lib/views/tabview/idetabhandleview.coffee
@@ -95,6 +95,7 @@
       @setClass 'edit-mode'
       @titleInput.setValue title
       @titleInput.setFocus()
+      @titleInput.selectAll()
       windowController.addLayer this
     else
       @unsetClass 'edit-mode'


minor

minor

--- client/landing/app/MainApp/ApplicationManager.coffee
+++ client/landing/app/MainApp/ApplicationManager.coffee
@@ -181,10 +181,11 @@
     callback()

   quitAll:->
+
     for own name, apps of @appControllers
-      @quit app  for app in apps
-
-  get:(name)-> @appControllers[name]?.first or null
+      @quit app  for app in apps.instances
+
+  get:(name)->

     if apps = @appControllers[name]
       apps.instances[apps.lastActiveIndex] or apps.instances.first


teams: verify slug util added

teams: verify slug util added

--- client/landing/site.landing/coffee/core/utils.coffee
+++ client/landing/site.landing/coffee/core/utils.coffee
@@ -280,6 +280,15 @@
       url         : "/-/validate/username"
       type        : 'POST'
       data        : { username }
-      xhrFields   : withCredentials : yes
       success     : callbacks.success
       error       : callbacks.error
+
+
+  verifySlug : (name, callbacks = {}) ->
+
+    $.ajax
+      url         : "/-/teams/verify-domain"
+      type        : 'POST'
+      data        : { name }
+      success     : callbacks.success
+      error       : callbacks.error


Add Given_/When_/Then_ describe, as well as it versions

--- cakes.coffee
+++ cakes.coffee
@@ -10,13 +10,18 @@
 	describe(message, callback)
 	return

-dic = (type, label, args)->  # Dictate to describe() or it()
+dic = (type, label, args, padding=false)->  # Dictate to describe() or it()
+
 	if type in ['describe', 'it']
 		if args.length == 1
 			args[1] = args[0]
 			label = ''

-		global[type] label.replace('%s', args[0]), args[1]
+		if padding
+			describe '|'.green, ->
+				global[type] label.replace('%s', args[0]), args[1]
+		else
+			global[type] label.replace('%s', args[0]), args[1]

 ###
@@ -29,13 +34,22 @@

 exports.Given = ->
-	dic 'it', "Given:".yellow+" %s", arguments
+	dic 'it', "Given:".yellow+" %s", arguments, true

 exports.When = ->
-	dic 'it', " When:".yellow+" %s", arguments
+	dic 'it', " When:".yellow+" %s", arguments, true

 exports.Then = ->
-	dic 'it', " Then:".yellow+" %s", arguments
+	dic 'it', " Then:".yellow+" %s", arguments, true
+
+exports.Given_ = ->
+	dic 'describe', " Given:".yellow+" %s", arguments, true
+
+exports.When_ = ->
+	dic 'describe', "  When:".yellow+" %s", arguments, true
+
+exports.Then_ = ->
+	dic 'describe', "  Then:".yellow+" %s", arguments, true

 exports.And = ->


used spaces instead of tabs; added itemViewOptions

--- core/app/backbone/views/suggested_topics_view.coffee
+++ core/app/backbone/views/suggested_topics_view.coffee
@@ -1,8 +1,9 @@
 #=require ./suggested_topic_view.coffee

 class window.SuggestedTopicsView extends Backbone.Marionette.CompositeView
-	template: "activities/empty"
+  template: "activities/empty"

-	itemViewContainer: "ul"
+  itemViewContainer: "ul"

-	itemView: SuggestedTopicView+  itemView: SuggestedTopicView
+  itemViewOptions: => addToCollection : window.Channels


Remove containers on completion

Remove containers on completion

--- app/libs/runner.coffee
+++ app/libs/runner.coffee
@@ -93,19 +93,20 @@
 										container: container
 										volume: shared

-								return done null, response
+								done null, response
+								removeContainer container, shared

-
-removeContainer = (container, volume, done) ->
+removeContainer = (container, volume) ->
 	if container
-		container.remove force: true, (err, data) =>
-			logger.warn "Failed to remove container #{container}" if err
+		container.remove force: true, (err, data) ->
+			if err
+				logger.warn "Failed to remove container #{container.id}"
+			else
+				logger.info "Removed container #{container.id}"

 	fs.remove volume, (err) ->
 		logger.warn "Failed to remove tmp directory #{volume}" if err

-	done null
-

 exports.getWinrate = getWinrate
 exports.removeContainer = removeContainer


CA - disable html cache

CA - disable html cache

--- app/scripts/app.coffee
+++ app/scripts/app.coffee
@@ -148,8 +148,14 @@
 .factory('httpInterceptor', ['$q', '$rootScope', ($q, $rootScope) ->
         return {
             request: (config) ->
+                # disable html cache
+                if(config.url.match(".html") && !config.cached)
+                  config.url +="?"+new Date().getTime().toString().slice(-2)
+                  config.cached = true
+                # broadcast message on save model
                 if(config.method == "PUT" || config.method == "PATCH")
                     $rootScope.$broadcast('data:write')
+                #
                 $rootScope.$broadcast('loading:start')
                 return config || $q.when(config)
             response: (response)  ->


check for single-/double quotes in fixPrefix

--- lib/atom-ternjs-provider.coffee
+++ lib/atom-ternjs-provider.coffee
@@ -35,7 +35,7 @@
         return true

     fixPrefix: (prefix) ->
-        return '' if prefix.match(/(\s|;|\.)$/) or prefix.replace(/\s/g, '').length is 0
+        return '' if prefix.match(/(\s|;|\.|\"|\')$/) or prefix.replace(/\s/g, '').length is 0
         prefix

     onDidInsertSuggestion: ({editor, triggerPosition, suggestion}) ->
@@ -83,7 +83,7 @@
                     console.log err

     fixCompletion: (obj) ->
-        if obj.type == 'string'
+        if obj.type is 'string'
             obj.name = obj.name.replace /(^"|"$)/g, ''

         obj.type = obj.type?.replace('->', ':')


Don't cover up the tab bar

Don't cover up the tab bar

This prevents the tab bar from receiving events when there are no editors
open such as double clicking to create a new untitled buffer.

--- lib/background-tips-view.coffee
+++ lib/background-tips-view.coffee
@@ -20,7 +20,10 @@
     setTimeout @start, @constructor.startDelay

   attach: ->
-    atom.workspaceView.getActivePane().append(this)
+    pane = atom.workspaceView.getActivePane()
+    top = pane.children('.item-views').position()?.top ? 0
+    @css('top', top)
+    pane.append(this)

   updateVisibility: ->
     if @shouldBeAttached()


Properly zero pad single digit days

Properly zero pad single digit days

--- src/flips-cli.coffee
+++ src/flips-cli.coffee
@@ -24,7 +24,7 @@
         month = "#{date.getMonth() + 1}"
         month = "0#{month}" if month.length is 1
         day = "#{date.getDate()}"
-        day = "0#{day}" if date.length is 1
+        day = "0#{day}" if day.length is 1
         date = "#{month}/#{day}/#{date.getFullYear()}"
         owner = form.getOwner()
         console.log date, "$#{humanize.intcomma(Math.floor(profit))} #{Names.normalize(owner.name)} #{owner.title}"


remove semicolon

remove semicolon

--- bootstrap-tour.coffee
+++ bootstrap-tour.coffee
@@ -249,7 +249,7 @@
     # Print message in console
     _debug: (text) ->
       if @_options.debug
-        window.console.log "Bootstrap Tour '#{@_options.name}' | #{text}";
+        window.console.log "Bootstrap Tour '#{@_options.name}' | #{text}"

     # Check if step path equals current document path
     _redirect: (path, currentPath) ->


Fixed cake::printTasks to be backward compatible with node v0.4

--- src/cake.coffee
+++ src/cake.coffee
@@ -58,7 +58,8 @@

 # Display the list of Cake tasks in a format similar to `rake -T`
 printTasks = ->
-  cakefilePath = path.join path.relative(__originalDirname, process.cwd()), 'Cakefile'
+  relative = path.relative or path.resolve
+  cakefilePath = path.join relative(__originalDirname, process.cwd()), 'Cakefile'
   console.log "#{cakefilePath} defines the following tasks:\n"
   for name, task of tasks
     spaces = 20 - name.length


updated diff regex

updated diff regex

regex now works with files that are escaped
with a newline character

--- src/diff.coffee
+++ src/diff.coffee
@@ -22,7 +22,7 @@
     diffs = []

     while lines.length && lines[0]
-      [m, a_path, b_path] = ///^diff\s--git\sa/(.+?)\sb/(.+)$///.exec lines.shift()
+      [m, a_path, b_path] = ///^diff\s--git\s"?a/(.+?)"?\s"?b/(.+)"?$///.exec lines.shift()

       if /^old mode/.test lines[0]
         [m, a_mode] = /^old mode (\d+)/.exec lines.shift()


New looping on Coffee Script

New looping on Coffee Script

--- Ackermann.coffee
+++ Ackermann.coffee
@@ -2,10 +2,12 @@
   if m == 0 then return n + 1
   else if m > 0 then return ack(m - 1, 1)
   else if m > 0 and n > 0 then return ack(m - 1, ack(m, n - 1))
-i = 0
-while i > -1
-  j = i
-  while j > -1
-    console.log ack(i,j)
-    j--
-  i++
+
+while true
+    m = i
+    while m > -1
+        print(ack(m, n))
+        m--
+        n++
+    i++
+    n = 0


Whoops

Whoops

--- config.coffee
+++ config.coffee
@@ -3,8 +3,8 @@
     paths:
         public: 'public'

-    paths:
-        public: '/user/www/deploy'
+    # paths:
+    #     public: '/user/www/deploy'

     files:


feat(brunch): allow custom paths for `app.js`

--- config.coffee
+++ config.coffee
@@ -16,8 +16,13 @@
   files:
     javascripts:
       joinTo:
-        # Non-spec scripts are application code
-        'app.js': /^app\/(?!.+\.spec\.)/
+        'app.js': (file) ->
+          # Non-spec scripts are application code
+          file.match(/^app\/(?!.+\.spec\.)/)? or
+          [
+            # Include path to specific scripts. Perfect for building AngularJS
+            # modules
+          ].indexOf(file) > -1
         # Specs are compiled into another file by themselves
         'spec.js': /^app\/.+\.spec\./
         # Vendor code


Fixed syntax error

Fixed syntax error

Line 57 should not include braces, which throws a syntax error that prevented the plugin from being loaded.

--- index.cjsx
+++ index.cjsx
@@ -54,7 +54,7 @@
   name: 'quest-info'
   priority: 2
   displayName: <FontAwesome key={0} name='indent' /> {__('Quest Information')}
-  description: {__ 'Plugin Description'}
+  description: __ 'Plugin Description'
   author: '马里酱'
   link: 'https://github.com/malichan'
   version: '1.3.0'


Add more banned names ~ we need to move those to a collection at some point

--- workers/social/lib/social/models/user.coffee
+++ workers/social/lib/social/models/user.coffee
@@ -23,10 +23,10 @@
     else
       message: err.message

-  @bannedUserList = ['abrt','amykhailov','apache','about','visa',
-                     'cthorn','daemon','dbus','dyasar','ec2-user',
+  @bannedUserList = ['abrt','amykhailov','apache','about','visa','shared-',
+                     'cthorn','daemon','dbus','dyasar','ec2-user','http',
                      'games','ggoksel','gopher','haldaemon','halt','mail',
-                     'nfsnobody','nginx','nobody','node','operator',
+                     'nfsnobody','nginx','nobody','node','operator','https',
                      'root','rpcuser','saslauth','shutdown','sinanlocal',
                      'sshd','sync','tcpdump','uucp','vcsa','zabbix',
                      'search','blog','activity','guest','credits','about',
@@ -39,7 +39,7 @@
                      'sync','syslog','tomcat','tomcat55','uucp','what',
                      'www-data','fuck','porn','p0rn','porno','fucking',
                      'fucker','admin','postfix','puppet','main','invite',
-                     'administrator','members','register','activate',
+                     'administrator','members','register','activate','shared',
                      'groups','blogs','forums','topics','develop','terminal',
                      'term','twitter','facebook','google','framework', 'kite']


reduce size of packaged file

reduce size of packaged file

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

 deploy_options = {
     dir: path.join __dirname, 'app'
-    asar: false
+    asar: true
     icon: path.join __dirname, 'src', 'icons', 'icon'
     out: outdeploy
     overwrite: true


add a task for compiling just the notification css

--- gulpfile.coffee
+++ gulpfile.coffee
@@ -24,6 +24,8 @@
 pluginBuildDir = './dist'
 pluginName = 'jquery.notifyr.js'
 pluginNameMin = 'jquery.notifyr.min.js'
+pluginCssName = 'jquery.notifyr.css'
+pluginCssNameMin = 'jquery.notifyr.min.css'
 banner = "/*!\n
         #{pak.name} v#{pak.version} (#{pak.homepage})\n
         Copyright (c) #{new Date().getFullYear()} #{pak.author}\n
@@ -41,7 +43,7 @@
       'example'
       'assets'
       'dist' # for serving compiled plugin
-      'node_modules' # for serving jquery
+      'node_modules' # for serving jquery & requirejs
     ]
     port: port
     livereload: true
@@ -79,6 +81,18 @@

 gulp.task 'compile-css', ->
   gulp
+    .src('./src/sass/notifications.scss')
+    .pipe(sass({
+      outputStyle: 'expanded' #compact; :expanded;
+      includePaths: ['']
+      errLogToConsole: false
+      onError: (e) -> log e.message
+    }))
+    .pipe(rename(pluginCssName))
+    .pipe(gulp.dest(pluginBuildDir))
+
+gulp.task 'compile-dev-css', ->
+  gulp
     .src('./src/sass/styles.scss')
     .pipe(sass({
       outputStyle: 'nested' #compressed
@@ -87,7 +101,7 @@
       onError: (e) -> log e.message
     }))
     .pipe(autoprefixer({
-      browsers: ['last 2 versions', 'Firefox >= 26', 'Explorer >= 8']
+      browsers: ['last 3 versions', 'Firefox >= 26', 'Explorer >= 8']
       cascade: false
     }))
     .pipe(gulp.dest(sassBuildDir))
@@ -95,7 +109,7 @@
 gulp.task 'refresh', (callback) ->
   run(
     'compile-js',
-    'compile-css',
+    'compile-dev-css',
     'browserify',
     'html',
     callback


move main.js to body

move main.js to body

--- gulpfile.coffee
+++ gulpfile.coffee
@@ -97,12 +97,12 @@
         dangerouslySetInnerHTML:
           __html: 'var INITIAL_PROPS=' + JSON.stringify(props) + ';'
       )
-      React.DOM.script(src: '/scripts/main.js')
     React.DOM.body null,
       React.DOM.div
         id: 'app-container'
         dangerouslySetInnerHTML:
           __html: React.renderToString(React.createFactory(AppView)(props))
+      React.DOM.script(src: '/scripts/main.js')
   fse.outputFileSync file, doctype + html

 ignoreError = (stream) ->


Enable uglify

Enable uglify

--- gulpfile.coffee
+++ gulpfile.coffee
@@ -81,14 +81,12 @@
 			filename: "build/framer.js"
 			sourceMapFilename: "[file].map"
 			pathinfo: false
-
-		# Uglify is disabled because it messes up the source maps in Safari.
 		plugins: [
 			new webpack.optimize.DedupePlugin(),
-			# new webpack.optimize.UglifyJsPlugin({
-			# 	mangle: false,
-			# 	compress: {warnings: false}
-			# })
+			new webpack.optimize.UglifyJsPlugin({
+				mangle: false
+				compress: {warnings: true}
+			})
 		]

 	webpackDev("webpack:release", config, callback)


add gulp js build for autocomplete

add gulp js build for autocomplete


:memo: Char limit includes ellipsis

:memo: Char limit includes ellipsis

--- lib/notification-issue.coffee
+++ lib/notification-issue.coffee
@@ -6,7 +6,7 @@
 CommandLogger = require './command-logger'
 UserUtilities = require './user-utilities'

-TITLE_CHAR_LIMIT = 100 # Truncate issue title to 100 characters
+TITLE_CHAR_LIMIT = 100 # Truncate issue title to 100 characters (including ellipsis)

 module.exports =
 class NotificationIssue


Remove debug output

Remove debug output

--- lib/suggestion-builder.coffee
+++ lib/suggestion-builder.coffee
@@ -46,7 +46,6 @@
       label

   getFirstClass: (data) =>
-    console.log(@scopes)
     data
       .filter (line) ->
         line.contains('::')
@@ -103,19 +102,15 @@

   getSuggestions: =>
     if @isIn(@typeScope)
-      console.log('typeScope')
       @getMatches @symbols
     else if @isIn(@moduleScope)
-      console.log('moduleScope')
       @genSpaceSearch()
         .then(@getModule)
     else if @isIn(@preprocessorScope)
-      console.log('preprocessorScope')
       @genSpaceSearch()
         .then(@getPreprocessor)
     #should be last as least sepcialized
     else if @isIn(@sourceScope)
-      console.log('sourceScope')
       if(@prefix=='_')
         @genTypeSearch()
           .then(@addModules)
@@ -124,6 +119,4 @@
       else
         @getMatches @symbols
     else
-      console.log('unkScope')
-      console.log(@scopes)
       []


Change startup message

Change startup message

--- bin/www.coffee
+++ bin/www.coffee
@@ -76,7 +76,8 @@
   else
     console.log chalk.cyan 'SiseTV is now running'
   app.set 'ip', ip
-  console.log chalk.cyan "Visit #{chalk.magenta 'http://' + ip + ':' + (app.get 'port') + '/admin'} to see it"
+  console.log chalk.cyan "Visit #{chalk.magenta 'http://' + ip + ':' + (app.get 'port') + '/admin'} for the administration interface"
+  console.log chalk.cyan "Point the browsers on your information display computers to #{chalk.magenta 'http://' + ip + ':' + (app.get 'port')}"


Normalize path for Windows users

Normalize path for Windows users

--- src/requisite.coffee
+++ src/requisite.coffee
@@ -32,6 +32,7 @@
   alias = do ->
     base = dirname(filename).length
     (filename) ->
+      filename = filename.replace(/\\/g, '/')
       if /node_modules/i.test filename
         idx = filename.indexOf '/node_modules'
         base = idx


Update atom.clipboard.read() call for new return value

--- src/selection.coffee
+++ src/selection.coffee
@@ -528,7 +528,7 @@
     return if @isEmpty()
     text = @editor.buffer.getTextInRange(@getBufferRange())
     if maintainClipboard
-      text = atom.clipboard.read().text + '\n' + text
+      text = "#{atom.clipboard.read()}\n#{text}"
     else
       metadata = { indentBasis: @editor.indentationForBufferRow(@getBufferRange().start.row) }


Document View::command and View::preempt

I just delegate through to the jquery-extensions because we might use
those methods in non-view objects

--- src/space-pen.coffee
+++ src/space-pen.coffee
@@ -146,6 +146,27 @@
   end: ->
     @prevObject ? jQuery(null)

+  # Public: Calls the given handler when commandName is triggered on the {View}.
+  #
+  # This is enhanced version of jQuery's `::on` method. It listens for a custom
+  # DOM event and adds metadata to the DOM to maintain a list of all commands.
+  #
+  # commandName - A namespaced {String} describing the command, such as
+  #               `find-and-replace:toggle`.
+  # selector - An optional selector {String} to filter the descendants of the
+  #            elements that trigger the event.
+  # options - An optional options {Object} with an `data` key.
+  # handler - A {Function} to execute when the command is triggered.
+  command: (commandName, selector, options, handler) ->
+    super(commandName, selector, options, handler)
+
+  # Public: Force an event handler to be called before all others. Mimics the
+  #
+  # eventName - A event name {String}.
+  # handler - A {Function} to execute when the eventName is triggered.
+  preempt: (eventName, handler) ->
+    super(eventName, handler)
+
 class Builder
   constructor: ->
     @document = []


Tweaks to browser.coffee

Tweaks to browser.coffee

--- browser.coffee
+++ browser.coffee
@@ -2,17 +2,18 @@

 CoffeeScript = require './coffee-script'

+# Use standard JavaScript `eval` to eval code.
 CoffeeScript.eval = (code, options) ->
   eval CoffeeScript.compile code, options

-unless window?
-  CoffeeScript.run = (code, options) ->
-    (Function CoffeeScript.compile code, options)()
-  return
+# Running code does not provide access to this scope.
+CoffeeScript.run = (code, options) ->
+  (Function CoffeeScript.compile code, options)()

-CoffeeScript.run  = (code, options) ->
-  setTimeout CoffeeScript.compile code, options
+# If we're not in a browser environment, we're finished with the public API.
+return unless window?

+# Load a remote script from the current domain via XHR.
 CoffeeScript.load = (url, options) ->
   xhr = new (window.ActiveXObject or XMLHttpRequest)('Microsoft.XMLHTTP')
   xhr.open 'GET', url, true
@@ -30,7 +31,7 @@
       if script.src
         CoffeeScript.load script.src
       else
-        CoffeeScript.run script.innerHTML
+        setTimeout -> CoffeeScript.run script.innerHTML
   null
 if window.addEventListener
   addEventListener 'DOMContentLoaded', processScripts, false


Fix a typo in `browser.coffee`.

Fix a typo in `browser.coffee`.

--- browser.coffee
+++ browser.coffee
@@ -34,7 +34,7 @@
     if xhr.readyState is 4
       error = result = null
       if xhr.status is 200
-        try result = CoffeeScript.run xhr.responseText catch error then error = exception
+        try result = CoffeeScript.run xhr.responseText catch exception then error = exception
       else
         error = new Error "An error occurred while loading the script `#{url}`."
       callback? error, result


for consistency

for consistency

--- lib/base.coffee
+++ lib/base.coffee
@@ -228,6 +228,9 @@
   emitDidRestoreCursorPositions: ->
     @vimState.emitter.emit('did-restore-cursor-positions')

+  emitDidFailToSetTarget: ->
+    @vimState.emitter.emit('did-fail-to-set-target')
+
   # Class methods
   # -------------------------
   @init: (service) ->


work in progress on integrating markdown with gui code

--- src/main.coffee
+++ src/main.coffee
@@ -53,17 +53,19 @@
 execute = (code) -> (
   md = markdown(code);
   outputarea.html(md);
-  js = '';
+  js = [];
   n = 0;
   $('#outputarea code').parent('pre').replaceWith(-> (
-    js += $(this).children().text()
+    js.push($(this).children().text())
     replacement = $('<div>')
     replacement.attr('id', 'js' + (n++))
     replacement
   ))

-  f = eval('(function() {' + js + '})')
-  run(f, $('#js0'))
+  n = 0
+  for j in js
+    f = eval('(function() {' + j + '})')
+    run(f, $('#js' + (n++)))
 )

 showOrHideCode = (-> (


Snap to grid

Snap to grid

--- src/main.coffee
+++ src/main.coffee
@@ -86,6 +86,10 @@
 		actualPiece.group.bringToFront()

 	tool.onMouseUp = (event) ->
+
+		# Possibly snap to grid
+		if actualPiece.zone.contains event.point
+			actualPiece.group.position = background.position

 		# Reset
 		piece.group.strokeWidth = 0 for piece in pieces


More friendly

More friendly

--- src/main.coffee
+++ src/main.coffee
@@ -47,17 +47,21 @@
     mod.rawFilePath = filePath
     filePathIndexesInMods[filePath] = mods.length - 1

-    # The function wrapper is just to prevent parsing error. It is temporary and won't be kept
+    # The function wrapper is just to prevent some parsing error. It is temporary and won't be kept
     # in the output.
     # If the wrapper is missing, the outermost `return` in code (if any) will be treated
-    # as illegal while parsing.
+    # as illegal so will cause parsing error.
     # An alternative way is to use the `tolerant` option, but I think `tolerant` is not better
     # than this.
-    parsed = esprima.parse("""
-        (function(exports, module, require) {
-        #{code}
-        })();
-    """)
+    parsed =
+        try
+            esprima.parse("""
+                (function(exports, module, require) {
+                #{code}
+                })();
+            """)
+        catch
+            throw new Error("Syntax error in \"#{filePath}\".")

     checkTreeNode = (node) ->
         if not (typeof node == "object" and node != null)


use cmd+alt+I to open inspector

use cmd+alt+I to open inspector

--- src/main.coffee
+++ src/main.coffee
@@ -17,6 +17,21 @@
     @app.on 'ready', @appReady.bind(@)
   appReady: ->
     menus = []
+    menus.push
+      label: 'YakYak'
+      submenu: [
+        { label: 'About YakYak', selector: 'orderFrontStandardAboutPanel:' }
+        { type: 'separator' }
+        #{ label: 'Preferences...', accelerator: 'Command+,', click: => @openConfig() }
+        { type: 'separator' }
+        { label: 'Hide Atom', accelerator: 'Command+H', selector: 'hide:' }
+        { label: 'Hide Others', accelerator: 'Command+Shift+H', selector: 'hideOtherApplications:' }
+        { label: 'Show All', selector: 'unhideAllApplications:' }
+        { type: 'separator' }
+        { label: 'Open Inspector', accelerator: 'Command+Alt+I', click: => @inspectorOpen() }
+        { type: 'separator' }
+        { label: 'Quit', accelerator: 'Command+Q', click: -> app.quit() }
+      ]
     menus.push
       label: 'Edit'
       submenu:[
@@ -38,7 +53,6 @@
       "min-width": 620
       "min-height": 420
     @mainWindow.on 'closed', => @mainWindow = null
-    @mainWindow.openDevTools detach: true
     # and load the index.html of the app. this may however be yanked
     # away if we must do auth.
     @loadAppWindow()
@@ -54,6 +68,8 @@
     @client.on 'chat_message', @clientonchatmessage
     ipc.on 'conversation:select', @conversationSelect
     ipc.on 'message:send', @messageSend
+  inspectorOpen: () =>
+    @mainWindow.openDevTools detach: true
   conversationSelect: (event, id) =>
     @model.conversationCurrent = id
     @refresh()


Don't fail when the default config file does not exist

--- src/main.coffee
+++ src/main.coffee
@@ -1,4 +1,5 @@
 # 3rd-party libs
+fs         = require('fs')
 path       = require('path')
 async      = require('async')
 {inspect}  = require('util')
@@ -9,7 +10,9 @@
 # Config
 config = require('jsconfig')
 version = require('./version')
-config.defaults path.join(__dirname,"..","config.js")
+defaultConfigFile = path.join(__dirname,"..","config.js")
+if fs.existsSync(defaultConfigFile)
+    config.defaults defaultConfigFile

 process.title = "buddycloud-server #{version}"

@@ -27,7 +30,7 @@
     stdout: ['logging.stdout', [off, "Log to stdout"]]
     version: [off, "Display version"]

-config.load "/etc/buddycloud-server/config.js", (args, opts) ->
+config.load (args, opts) ->

     if opts.version
         console.log version
@@ -38,6 +41,8 @@
             opts.config = path.join(process.cwd(), opts.config)
         # Always reload config for -c argument
         config.merge(opts.config)
+    else if fs.existsSync("/etc/buddycloud-server/config.js")
+        config.merge("/etc/buddycloud-server/config.js")

     # Kludge:
     if opts.stdout


Completed CoffeeScript

Completed CoffeeScript

--- palindrome.coffee
+++ palindrome.coffee
@@ -1,21 +1,16 @@
-[word, palindrome, freq, numberOfOdds] = ["rraacce", "", {}, 0]
-
-for letter in word.split("")
-  if freq[letter] += 1
-  else freq[letter] = 1
-
-for letter, amount of freq
-  numberOfOdds++ if amount % 2 != 0
-
-isPalindrome = (x) -> if x == x.split("").reverse().join "" then true else false
-cannotBePalindrome = (x) -> if numberOfOdds > 1 then true else false
 makePalindrome = (x) ->
-  if isPalindrome(x) then console.log("String given is already a palindrome.")
-  else if cannotBePalindrome(x) then console.log("String given cannot be made into a palindrome.")
-  else for letter, amount of freq
-    if amount % 2 != 0 then (palindrome = letter) && (freq[letter]--)
+  [palindrome, freq, numberOfOdds] = ["", {}, 0]
+  isPalindrome = (x) -> if x == x.split("").reverse().join "" then true else false
+  cannotBePalindrome = (x) -> if numberOfOdds > 1 then true else false
+  for letter in x.split("")
+    if freq[letter] then freq[letter] += 1 else freq[letter] = 1
+  for letter, amount of freq
+    numberOfOdds++ if amount % 2 != 0
+  if isPalindrome(x) then console.log("#{x} is already a palindrome.")
+  else if cannotBePalindrome(x) then console.log("#{x} cannot be made into a palindrome.")
+  else
+    for letter, amount of freq
+      if amount % 2 != 0 then (palindrome = letter) && (freq[letter]--)
     for letter, amount of freq
       if amount != 0 then palindrome = (Array(Math.floor(amount / 2) + 1).join(letter)) + palindrome + (Array(Math.floor(amount / 2) + 1).join(letter))
-  console.log("Palindrome: #{palindrome}")
-
-makePalindrome(word)
+    console.log("#{x} as a palindrome: #{palindrome}")


Updated reference to define

Updated reference to define

--- src/molo.coffee
+++ src/molo.coffee
@@ -196,4 +196,4 @@

     root.molo.define name, requires, defines

-  define 'root', -> root
+  root.molo.define 'root', -> root


fix(auto-update): mistakenly used remote.dialog

I forgot that the `AutoUpdateManager` is run from the main process

--- src/browser/auto-update-manager.coffee
+++ src/browser/auto-update-manager.coffee
@@ -125,7 +125,7 @@

   onUpdateNotAvailable: =>
     autoUpdater.removeListener 'error', @onUpdateError
-    remote.dialog.showMessageBox
+    dialog.showMessageBox
       type: 'info'
       buttons: ['OK']
       icon: @iconURL()


cleanup

cleanup

--- lib/eval.coffee
+++ lib/eval.coffee
@@ -23,10 +23,7 @@
     editor = atom.workspace.getActiveTextEditor()
     for sel in editor.getSelections()
       client.msg 'eval', @evalData(editor, sel), ({start, end, result}) =>
-        if result.type
-          view = result.view
-        else
-          view = result
+        view = if result.type then result.view else result
         view = @ink.tree.fromJson(view)[0]
         @ink.links.linkify view
         r = @ink?.results.showForLines editor, start-1, end-1,


Tabview: separated scroll adjustment to own methods

--- src/components/tabs/tabpaneview.coffee
+++ src/components/tabs/tabpaneview.coffee
@@ -34,17 +34,14 @@
     @active = yes
     @emit "KDTabPaneActive"

-    KD.utils.defer =>
-      @getElement().scrollTop         = @lastScrollTops.self
-      @parent?.getElement().scrollTop = @lastScrollTops.parent
+    @applyScrollTops()

   hide:->

     return  unless @active

-    @lastScrollTops.parent = @parent?.getElement().scrollTop or 0
-    @lastScrollTops.self   = @getElement().scrollTop
+    @setScrollTops()

     @setClass "kdhiddentab"
     @unsetClass "active"
@@ -54,6 +51,20 @@

     @active = no
     @emit "KDTabPaneInactive"
+
+
+
+  setScrollTops: ->
+
+    @lastScrollTops.parent = @parent?.getElement().scrollTop or 0
+    @lastScrollTops.self   = @getElement().scrollTop
+
+
+  applyScrollTops: ->
+
+    KD.utils.defer =>
+      @getElement().scrollTop         = @lastScrollTops.self
+      @parent?.getElement().scrollTop = @lastScrollTops.parent

   setTitle:(title)->


adding in class selectors for easier testing

--- src/components/task-plan/homework.cjsx
+++ src/components/task-plan/homework.cjsx
@@ -192,9 +192,9 @@
     total = numSelected + 3

     if @props.canReview and numSelected
-      button = <BS.Button bsStyle="primary" onClick={@props.reviewClicked}>Review</BS.Button>
+      button = <BS.Button bsStyle="primary" className="-review-exercises"  onClick={@props.reviewClicked}>Review</BS.Button>
     else if @props.canAdd
-      button = <BS.Button bsStyle="primary" onClick={@props.addClicked}>Add</BS.Button>
+      button = <BS.Button bsStyle="primary" className="-add-exercises" onClick={@props.addClicked}>Add</BS.Button>

     <BS.Panel className bsStyle="default">
       <BS.Grid>
@@ -308,6 +308,7 @@
       TocActions.load(courseId)
       return Loading...

+    selected = TaskPlanStore.getTopics(planId)
     chapters = _.map(TocStore.get(), @renderChapterPanels)
     buttonStyle = if selected?.length then 'primary' else 'disabled'
     shouldShowExercises = selected?.length and @state.showProblems
@@ -315,7 +316,7 @@
     if not @state.showProblems
       footer =

-          <BS.Button bsStyle={buttonStyle} onClick={@selectProblems}>Show Problems</BS.Button>
+          <BS.Button className="-show-problems" bsStyle={buttonStyle} onClick={@selectProblems}>Show Problems</BS.Button>
           <BS.Button bsStyle="link" onClick={hide}>Cancel</BS.Button>


Fix some formatting issues on Windows

Fix some formatting issues on Windows

--- lib/ghci.coffee
+++ lib/ghci.coffee
@@ -25,7 +25,7 @@
       @[i](opts[i])

     handleError = (error) =>
-      @emitter.emit 'response', "GHCI crashed" + EOL + "#{error}"
+      @emitter.emit 'response', "GHCI crashed\n#{error}"
       console.error error
       @ghci = null
       @emitter.emit 'exit', -1
@@ -81,13 +81,13 @@
               @responseBuffer.slice(0, -2)

           # TODO: Show that command finished
-          @emitter.emit 'error', @errorBuffer.join(EOL) + EOL
+          @emitter.emit 'error', @errorBuffer.join('\n') + '\n'
           @errorBuffer = []
           if @response
-            @emitter.emit 'response', @responseBuffer.join(EOL) + EOL
+            @emitter.emit 'response', @responseBuffer.join('\n') + '\n'
             @response = false
           else
-            @emitter.emit 'message', @responseBuffer.join(EOL) + EOL
+            @emitter.emit 'message', @responseBuffer.join('\n') + '\n'
           @responseBuffer = []
       @process.stderr.on 'data', buffered (lines) =>
         lines.forEach (line) ->
@@ -96,7 +96,7 @@
       @process.on 'exit', (code) =>
         @ghci = null
         if code isnt 0
-          @emitter.emit 'error', @errorBuffer.join(EOL) + EOL
+          @emitter.emit 'error', @errorBuffer.join('\n') + '\n'
         @emitter.emit 'exit', code
         @disposables.dispose()

@@ -151,7 +151,7 @@
       else
         tkill @ghci.pid, 'SIGINT'
     @finished = true
-    @emitter.emit 'response', 'Interrupted' + EOL
+    @emitter.emit 'response', 'Interrupted\n'

   writeLines: (lines) =>
     return false unless @isActive()
@@ -168,17 +168,14 @@
       @ghci.stderr.pause()
       @errorBuffer = []
       @responseBuffer = []
-      @ghci.stdin.write ":{#{EOL}"
-      lines.forEach (line) =>
-        @ghci.stdin.write line + EOL
+      @ghci.stdin.write ":{#{EOL}#{lines.join(EOL)}#{EOL}:}#{EOL}"
       @emitter.emit 'input', lines.join('\n') + '\n'
-      @ghci.stdin.write ":}#{EOL}"
       @ghci.stdout.resume()
       @ghci.stderr.resume()
       return true
     else
-      @ghci.stdin.write lines.join(EOL)
-      @emitter.emit 'response', "> \"#{lines.join('\\n')}\"#{EOL}"
+      @ghci.stdin.write lines.join('\n')
+      @emitter.emit 'input', "\"#{lines.join('\\n')}\"\n"
       return true

   historyBack: (current) ->


account: account page opens again, kitelist fix (greetings to cihangir)

--- client/landing/app/Applications/Account.kdapplication/account/accMyKiteList.coffee
+++ client/landing/app/Applications/Account.kdapplication/account/accMyKiteList.coffee
@@ -28,13 +28,13 @@
     ##################### Events ############################
     list.on "DeleteKiteSubmitted", @bound "deleteKite"

-    list.on "UpdateKiteSubmitted", @bound "updateDatabase"
+    list.on "UpdateKiteSubmitted", @bound "updateKite"

     list.on "CreateKiteSubmitted", @bound "createKite"

     @on "KiteDeleted", list.bound "removeItem"

-    @on "KiteUpdated", list.bound ""
+    # @on "KiteUpdated", list.bound ""

     @on "KiteCreated", (itemData)=>
       list.addItem itemData, null, {type : "slideDown", duration : 100}


cleanup BEFORE aggressive refactoring. excercise DONE

--- lib/main.coffee
+++ lib/main.coffee
@@ -28,25 +28,31 @@
       'quick-highlight:clear': => @clear()

     debouncedhighlightSelection = null
-    settings.observe 'highlightSelectionDelay', (delay) =>
-      debouncedhighlightSelection = _.debounce(@highlightSelection.bind(this), delay)
+    highlightSelection = @highlightSelection.bind(this)
+    settings.observe 'highlightSelectionDelay', (delay) ->
+      debouncedhighlightSelection = _.debounce(highlightSelection, delay)
+
+    refreshEditor = @refreshEditor.bind(this)

     @subscribe atom.workspace.observeTextEditors (editor) =>
       editorSubs = new CompositeDisposable
-      editorSubs.add editor.onDidStopChanging =>
-        return unless atom.workspace.getActiveTextEditor() is editor
-        URI = editor.getURI()
-        for e in getVisibleEditors() when (e.getURI() is URI)
-          @refreshEditor(e)
+      editorSubs.add editor.onDidStopChanging ->
+        if editor is atom.workspace.getActiveTextEditor()
+          URI = editor.getURI()
+          isChangedEditor = (editor) -> editor.getURI() is URI
+          getVisibleEditors()
+            .filter(isChangedEditor)
+            .forEach(refreshEditor)

       editorElement = editor.element
-      editorSubs.add(editor.element.onDidChangeScrollTop => @refreshEditor(editor))
+      refresh = @refreshEditor.bind(this, editor)
+      editorSubs.add(editorElement.onDidChangeScrollTop(refresh))

       # [FIXME]
       # @refreshEditor depends on editorElement.getVisibleRowRange() but it return
       # [undefined, undefined] when it called on editorElement which is not attached yet.
       # So we separately need to cover this case from Atom v1.1.0
-      editorSubs.add(editorElement.onDidAttach => @refreshEditor(editor))
+      editorSubs.add(editorElement.onDidAttach(refresh))

       editorSubs.add editor.onDidChangeSelectionRange ({selection}) =>
         if selection.isLastSelection() and not @isLocked()
@@ -178,7 +184,6 @@
       for marker in markers
         marker.destroy()
     @markersByEditor.clear()
-
     @colorByKeyword.clear()
     @colorIndex = null


main: Remove unused require

main: Remove unused require

--- lib/main.coffee
+++ lib/main.coffee
@@ -1,7 +1,6 @@
 {CompositeDisposable} = require 'atom'

 fs = require 'fs'
-zmq = require 'zmq'
 _ = require 'lodash'
 stripAnsi = require 'strip-ansi'
 {MessagePanelView, PlainMessageView} = require 'atom-message-panel'


Adding instructions to the webpack config

--- webpack.config.coffee
+++ webpack.config.coffee
@@ -4,6 +4,14 @@

 isProduction = process.env.FRIG_ENV == "production"
 minimize = process.env.FRIG_MIN == "minimize"
+
+unless isProduction
+  console.log(
+    "\nPlease use npm link and the Frig examples for debugging "+
+    "Frigging Bootstrap."+
+    "\n\nSee the Frig's HACKING.md for further details.\n"
+  )
+  process.exit()

 module.exports =
   entry: "./src/javascripts/index.js"


feat: add deactivate function

feat: add deactivate function

--- lib/main.coffee
+++ lib/main.coffee
@@ -60,3 +60,6 @@
         console.log CSON.stringify rootGrammar
       helper.writeGrammarFile rootGrammar, 'language-ignore-slug.cson', do ->
         atom.commands.dispatch 'body', 'window:reload'
+
+    deactivate: ->
+      @subscriptions.dispose()


Removed the onDidStartUsingLevels and onDidStopUsingLevels functions

--- lib/main.coffee
+++ lib/main.coffee
@@ -50,7 +50,8 @@
         @languageRegistry.addLanguage @language

         @usingLevels = true
-        @onDidStartUsingLevels()
+        @setUpConfigManagement()
+        process.env['LRB_WHITELIST_PATH'] = path.join @pkgLanguageDirPath, 'whitelist'
       catch error
         atom.notifications.addError "Failed to load the language from the #{@pkgName} package",
           detail: "#{error}"
@@ -62,17 +63,8 @@
       atom.grammars.removeGrammar @dummyGrammar
       @languageRegistry.removeLanguage @language
       @usingLevels = false
-      @onDidStopUsingLevels()
-    return
-
-  onDidStartUsingLevels: ->
-    @setUpConfigManagement()
-    process.env['LRB_WHITELIST_PATH'] = path.join @pkgLanguageDirPath, 'whitelist'
-    return
-
-  onDidStopUsingLevels: ->
-    @configSubscription.dispose()
-    delete process.env['LRB_WHITELIST_PATH']
+      @configSubscription.dispose()
+      delete process.env['LRB_WHITELIST_PATH']
     return

   config:


fix  'in' to 'of' for object iteration. #4

--- lib/main.coffee
+++ lib/main.coffee
@@ -32,10 +32,10 @@
       @rowDeltaToRemember = newValue

     atom.commands.add 'atom-workspace',
-      'cursor-history:next':  => @next()
-      'cursor-history:prev':  => @prev()
-      'cursor-history:clear': => @clear()
-      'cursor-history:dump':  => @dump()
+      'cursor-history:next':         => @next()
+      'cursor-history:prev':         => @prev()
+      'cursor-history:clear':        => @clear()
+      'cursor-history:dump':         => @dump()
       'cursor-history:toggle-debug': => @toggleConfig('debug')

     @subscriptions.add atom.workspace.observeTextEditors (editor) =>
@@ -147,9 +147,6 @@
       options =
         searchAllPanes: settings.get('searchAllPanes')

-        # initialLine: point.row
-        # initialColumn: point.column
-
       atom.workspace.open(URI, options).done (editor) =>
         editor.scrollToBufferPosition(point, center: true)
         editor.setCursorBufferPosition(point)
@@ -158,10 +155,10 @@
     @history.dump direction

   deactivate: ->
-    @subscriptions.dispose()
-    for key, disposables in @editorSubscriptions
+    for editorID, disposables of @editorSubscriptions
       disposables.dispose()
     @editorSubscriptions = null
+    @subscriptions.dispose()
     settings.dispose()
     @history?.destroy()
     @history = null


Send the status code with the HTTP request size metric

--- http.coffee
+++ http.coffee
@@ -17,7 +17,7 @@
 				routePath = req.route.path.toString().replace(/\//g, '_').replace(/\:/g, '').slice(1)
 				Metrics.timing("http_request", responseTimeMs, null, {method:req.method, status_code: res.statusCode, path:routePath})
 				if requestSize
-					Metrics.summary("http_request_size_bytes", requestSize, {method:req.method, path:routePath})
+					Metrics.summary("http_request_size_bytes", requestSize, {method:req.method, status_code: res.statusCode, path:routePath})
 				remoteIp = req.ip || req.socket?.socket?.remoteAddress || req.socket?.remoteAddress
 				reqUrl = req.originalUrl || req.url
 				referrer = req.headers['referer'] || req.headers['referrer']


fix top buttons

fix top buttons

--- static/js/app.coffee
+++ static/js/app.coffee
@@ -4,10 +4,12 @@
 shell = require 'shell'

 # Window buttons
-for action in ['close', 'minimize']
+addButtonListener = (action) ->
   document.querySelector("#btn-#{action}").addEventListener 'click', (e) ->
     e.preventDefault()
     ipc.send('do-native-action', action)
+
+addButtonListener(action) for action in ['close', 'minimize']

 # Show window UI
 document.body.classList.add('ready')


.#state.coffeeをコミットしてたので削除

.#state.coffeeをコミットしてたので削除


AJAX style.

AJAX style.

--- _includes/coffeescript/scripts.coffee
+++ _includes/coffeescript/scripts.coffee
@@ -5,6 +5,6 @@

     switch event.keyCode
       when 37
-        window.location.href = $previous unless $previous is undefined
+        $('#guest').load($previous + ' #guest') unless $previous is undefined
       when 39
-        window.location.href = $next unless $next is undefined+        $('#guest').load($next + ' #guest') unless $next is undefined


oops. shifted parameters

oops. shifted parameters

--- commands/timer.coffee
+++ commands/timer.coffee
@@ -76,7 +76,7 @@

 brain.addPattern 'reminder',
     match: [/remind\s(\w+)\s(?:to|of|about)\s(.+)\sin\s(.+)/i]
-    fn: (user, m, cb) -> setReminder m[4], m[3], (if m[1] == 'me' then user else m[1]), cb
+    fn: (user, m, cb) -> setReminder m[3], m[2], (if m[1] == 'me' then user else m[1]), cb

 brain.addPattern 'sayTimer',
     match: [/say\s(.+)\sin\s(.+)/i]


fix(iframe): allowDefault for events within message iFrames, just not link clicks

--- src/components/evented-iframe.cjsx
+++ src/components/evented-iframe.cjsx
@@ -85,10 +85,11 @@
   # iFrame, the mouseup never fires in the parent window.

   _onIFrameClick: (e) =>
-    e.preventDefault()
     e.stopPropagation()
     target = @_getContainingTarget(e, {with: 'href'})
-    atom.windowEventHandler.openLink(target: target) if target
+    if target
+      e.preventDefault()
+      atom.windowEventHandler.openLink(target: target)

   _onIFrameMouseEvent: (event) =>
     node = React.findDOMNode(@)


Add Jenneviere

Add Jenneviere

--- js/outer/about.coffee
+++ js/outer/about.coffee
@@ -32,7 +32,8 @@
             "David drank the automated testing kool-aid years ago. After introducing and championing (and constantly fiddling with) continuous integration tools at his last N jobs, he came to Circle to do the same on a much larger scale."]
     ,
       name: "Jenneviere Villegas"
-      visible: false
+      photo: "jenneviere"
+      visible: true
       role: "Operations"
       github: "jenneviere"
       twitter: "jenneviere"


Session functions

Session functions

--- src/predefined.coffee
+++ src/predefined.coffee
@@ -216,7 +216,7 @@
 #        [ ] NSAPI
 #    [ ] Session Extensions
 #        [ ] Msession
-#        [ ] Sessions
+#        [x] Sessions
 #        [ ] Session PgSQL
 #    [x] Text Processing
 #        [x] BBCode
@@ -3838,4 +3838,25 @@
     'calculhmac': 'function'
     'nthmac': 'function'
     'signeurlpaiement': 'function'
-}+
+    # Session
+    'session_name': 'function'
+    'session_module_name': 'function'
+    'session_save_path': 'function'
+    'session_id': 'function'
+    'session_regenerate_id': 'function'
+    'session_decode': 'function'
+    'session_encode': 'function'
+    'session_start': 'function'
+    'session_destroy': 'function'
+    'session_unset': 'function'
+    'session_set_save_handler': 'function'
+    'session_cache_limiter': 'function'
+    'session_cache_expire': 'function'
+    'session_set_cookie_params': 'function'
+    'session_get_cookie_params': 'function'
+    'session_write_close': 'function'
+    'session_status': 'function'
+    'session_register_shutdown': 'function'
+    'session_commit': 'function'
+}


initialization: temporarily disable

initialization: temporarily disable

--- workers/social/lib/social/init.coffee
+++ workers/social/lib/social/init.coffee
@@ -43,27 +43,29 @@
   fin = dash continuation, kodingAdmins.map (userData) -> ->

     JUser.createUser userData, (err, user, account) ->
+      JUser.emit 'UserCreated', user
       error err  if err
       adminAccounts.push account
       fin()

 init = ->
   console.log 'init'
-  initGuests()
+  # initGuests()

 exports.init = (koding) ->
+  console.warn 'Initialization code is temporarily disabled.'
   # JGroup = require './models/group'
   # JGroup.count (err, count) ->
   #   return console.error err  if err
   #   initKodingGroup()  if count is 0
   # If we need to create initialize the DB, do it now:
-  counter = (require 'koding-counter') {
-    db          : koding.getClient()
-    counterName : 'dbinit'
-  }
-  counter.reset -> counter.count (err, count) ->
-    throw err  if err
-    if count is 0
-      counter.next (err, seq) ->
-        throw err  if err
-        init()+  # counter = (require 'koding-counter') {
+  #   db          : koding.getClient()
+  #   counterName : 'dbinit'
+  # }
+  # counter.reset -> counter.count (err, count) ->
+  #   throw err  if err
+  #   if count is 0
+  #     counter.next (err, seq) ->
+  #       throw err  if err
+  #       init()


Specify allowed x-site CORS origins. Re: #9

--- servers/api/middleware/cors.coffee
+++ servers/api/middleware/cors.coffee
@@ -1,10 +1,15 @@
+nconf = require("nconf")
+
 module.exports.middleware = (config = {}) ->
+
+  origins = [nconf.get('url:www'), nconf.get('url:raw')].join(" ")
+
   (req, res, next) ->
     # Just send the headers all the time. That way we won't miss the right request ;-)
     # Other CORS middleware just wouldn't work for me
     # TODO: Minimize these headers to only those needed at the right time

-    res.header("Access-Control-Allow-Origin", req.headers.origin or "*")
+    res.header("Access-Control-Allow-Origin", origins)
     res.header("Access-Control-Allow-Methods", "OPTIONS,GET,PUT,POST,DELETE")
     res.header("Access-Control-Allow-Headers", "Authorization, User-Agent, Referer, X-Requested-With, Proxy-Authorization, Proxy-Connection, Accept-Language, Accept-Encoding, Accept-Charset, Connection, Content-Length, Host, Origin, Pragma, Accept-Charset, Cache-Control, Accept, Content-Type")
     res.header("Access-Control-Expose-Headers", "Link")


Use connection file in ./hydrogen/connection.json

--- lib/config-manager.coffee
+++ lib/config-manager.coffee
@@ -9,7 +9,7 @@
     fileStoragePath: path.join(__dirname, '..', 'kernel-configs')

     writeConfigFile: (onCompleted) ->
-        customKernelConnectionPath = path.join atom.project.rootDirectories[0].path, 'hydrogen', 'kernel', 'hydrogen-kernel.json'
+        customKernelConnectionPath = path.join atom.project.rootDirectories[0].path, 'hydrogen', 'connection.json'
         fs.access customKernelConnectionPath, (err) =>
             if err?
                 try


Update: Product Sync constant property name update.

--- lib/product-import.coffee
+++ lib/product-import.coffee
@@ -11,7 +11,7 @@

   constructor: (@logger, options = {}) ->
     @sync = new ProductSync
-    if options.blackList and ProductSync.actions
+    if options.blackList and ProductSync.actionGroups
       @sync.config @_configureSync(options.blackList)
     @client = new SphereClient options.clientConfig
     @_configErrorHandling(options)
@@ -21,14 +21,14 @@

   _configureSync: (blackList) =>
     @_validateSyncConfig(blackList)
-    debug "Product sync config validated"
-    _.difference(ProductSync.actions, blackList)
+    @logger.info "Product sync config validated"
+    _.difference(ProductSync.actionGroups, blackList)
       .map (type) -> {type: type, group: 'white'}
       .concat(blackList.map (type) -> {type: type, group: 'black'})

   _validateSyncConfig: (blackList) ->
     for actionGroup in blackList
-      if not _.contains(ProductSync.actions, actionGroup)
+      if not _.contains(ProductSync.actionGroups, actionGroup)
         throw ("invalid product sync action group: #{actionGroup}")

   _configErrorHandling: (options) =>


Adding createIndex and dropIndex.

Adding createIndex and dropIndex.

--- direct.coffee
+++ direct.coffee
@@ -80,6 +80,18 @@
     collection = @_getCollection()
     blocking(collection, collection.findAndModify)(selector, sort, document, options)

+  createIndex: (fieldOrSpec, options) =>
+    options = {} unless options
+    options.w ?= 1
+    collection = @_getCollection()
+    blocking(collection, collection.createIndex)(fieldOrSpec, options)
+
+  dropIndex: (indexName, options) =>
+    options = {} unless options
+    options.w ?= 1
+    collection = @_getCollection()
+    blocking(collection, collection.dropIndex)(indexName, options)
+
   @_getConnection: (databaseUrl) ->
     if databaseUrl?
       if not connections[databaseUrl]


Fix overwriting bug

Fix overwriting bug

--- components/Log.coffee
+++ components/Log.coffee
@@ -54,9 +54,9 @@
     @outPorts =
       out: new noflo.Port

-    @inPorts.options.on "data", (options) =>
-      if _.isObject options
-        for own key, value of options
+    @inPorts.options.on "data", (otps) =>
+      if _.isObject opts
+        for own key, value of opts
           options[key] = value

     @inPorts.in.on "connect", =>
@@ -66,7 +66,7 @@

     @inPorts.in.on "begingroup", (group) =>
       here = @locate()
-      here[group] = []
+      here[group] ?= []
       @groups.push group
       @outPorts.out.beginGroup group if @outPorts.out.isAttached()


preparing log line for join-part

preparing log line for join-part

--- scripts/eslogger_watcher.coffee
+++ scripts/eslogger_watcher.coffee
@@ -52,7 +52,13 @@
       eslogger.logMessageES log, res.message.room, res

     robot.enter (res) ->
-      console.log res
+      msg = res.envelope.message
+      line = "#{msg.user.name} left #{msg.room} (#{msg.text})"
+      console.log line
+      console.log msg.user

     robot.leave (res) ->
-      console.log res
+      msg = res.envelope.message
+      line = "#{msg.user.name} joined #{msg.room}"
+      console.log line
+      console.log msg.user


Add 'default' tasks

Add 'default' tasks

--- build/Gruntfile.coffee
+++ build/Gruntfile.coffee
@@ -399,3 +399,11 @@
     ciTasks.push('publish-nylas-build')

   grunt.registerTask('ci', ciTasks)
+
+  defaultTasks = ['download-electron', 'build', 'set-version', 'generate-asar']
+  # We don't run `install` on linux because you need to run `sudo`.
+  # See docs/build-instructions/linux.md
+  # `sudo script/grunt install`
+  defaultTasks.push 'mkdmg' if process.platform is 'darwin'
+  defaultTasks.push 'install' unless process.platform is 'linux'
+  grunt.registerTask('default', defaultTasks)


:lipstick:

:lipstick:

--- lib/tabs-to-spaces.coffee
+++ lib/tabs-to-spaces.coffee
@@ -5,8 +5,6 @@
 # Public: Handles the interface between Atom and the Tabs to Spaces package.
 module.exports =
 class TabsToSpaces
-  spaces = null
-
   # Public: Converts all leading spaces to tabs in the current buffer.
   tabify: (@editor=atom.workspace.getActiveEditor()) ->
     return unless @editor?


Fix +/- font size on mac

Fix +/- font size on mac

--- lib/views/terminal.coffee
+++ lib/views/terminal.coffee
@@ -30,6 +30,8 @@
           text = Clipboard.readText().replace(/\n/g, "\r")
           @term.emit 'data', text
         else if (e.which == 187 || e.which == 189) && e.metaKey
+          e.preventDefault()
+          e.stopPropagation()
           @adjustTermFontSize(e.which)

     @applyEditorStyling()


Fix browser.last_request/last_response failing on second request/response pair

--- lib/zombie/browser.coffee
+++ lib/zombie/browser.coffee
@@ -346,16 +346,16 @@
     #
     # Returns the last request sent by this browser. The object will have the
     # properties url, method, headers, and if applicable, body.
-    @__defineGetter__ "last_request", -> trail[trail.length -1]?.request
+    @__defineGetter__ "last_request", -> trail[trail.length - 1]?.request
     # ### browser.last_response => Object
     #
     # Returns the last response received by this browser. The object will have the
     # properties status, headers and body. Long bodies may be truncated.
-    @__defineGetter__ "last_response", -> trail[trail.length -1]?.response
+    @__defineGetter__ "last_response", -> trail[trail.length - 1]?.response
     # ### browser.last_error => Object
     #
     # Returns the last error received by this browser in lieu of response.
-    @__defineGetter__ "last_error", -> trail[trail.length -1]?.error
+    @__defineGetter__ "last_error", -> trail[trail.length - 1]?.error

 exports.Browser = Browser


show form every day

show form every day

--- html-app/app/scripts/controllers/topics/query.coffee
+++ html-app/app/scripts/controllers/topics/query.coffee
@@ -19,9 +19,9 @@

   setLoggedInStuff = ->
     if $scope.currentSession.loggedIn()
-      yesterday = moment().subtract("days", 1)
+      morning = moment().hour(6)
       $scope.currentSession.hasPostedToday = !!_.find($scope.topics, (topic)->
-        topic.author.id == $scope.currentSession.id && yesterday.isBefore(topic['first-post']['created-at'])
+        topic.author.id == $scope.currentSession.id && morning.isBefore(topic['first-post']['created-at'])
       )
       console.log $scope.currentSession.hasPostedToday
       if !$scope.currentSession.hasPostedToday || $scope.currentSession.new


Correct check for global `exports` for commonJS

(Also for browserify)

Using `typeof exports is not 'undefined'` in coffee script translates to
`(typeof exports === !'undefined')` which is obviously not what we want.
Instead we can use the expression `exports?` [1] which will properly
translate into `(typeof exports !== 'undefined' && exports !== null)`.

[1] http://stackoverflow.com/a/10238211/790169

--- odometer.coffee
+++ odometer.coffee
@@ -551,7 +551,7 @@
   # AMD. Register as an anonymous module.
   define ['jquery'], ->
     Odometer
-else if typeof exports is not 'undefined'
+else if exports?
   # CommonJS
   module.exports = Odometer
 else


cleanup a todo flag

cleanup a todo flag

--- scripts/pagerv2_commands.coffee
+++ scripts/pagerv2_commands.coffee
@@ -116,7 +116,6 @@
         res.send e
       res.finish()

-  # TODO
   #   hubot pd me <duration>     - creates an override for <duration> minutes
     robot.respond /pd (?:([^ ]+) )?(?:for )?(\d+)(?: min(?:utes)?)?\s*$/, (res) ->
       [ _, who, duration ] = res.match


Don't append to the replacement text to preserve the cursor position

--- src/trix/models/document.coffee
+++ src/trix/models/document.coffee
@@ -24,10 +24,10 @@
           when endLocation.block
             currentText.removeTextAtRange([0, endLocation.position])
             endText = currentText
+          when startLocation.block
+            currentText.replaceTextAtRange(text, [startLocation.position, currentText.getLength()])
+            currentText.appendText(endText)
             textsToRemove.push(endText)
-          when startLocation.block
-            text.appendText(endText)
-            currentText.replaceTextAtRange(text, [startLocation.position, currentText.getLength()])
           else
             textsToRemove.push(currentText)


added name to sv

added name to sv

--- src/ubret/subject_viewer.coffee
+++ src/ubret/subject_viewer.coffee
@@ -1,7 +1,8 @@
 BaseTool = window.Ubret.BaseTool or require('./base_tool')

 class SubjectViewer extends BaseTool
-
+  name: 'Subject Viewer'
+
   constructor: (opts) ->
     super
     @count = 0


When doing a POST in the UI, don't show an error. People used to see a flash of red on logout

--- js/inner.coffee
+++ js/inner.coffee
@@ -900,6 +900,10 @@

     @get('(.*)', (cx) -> VM.unsupportedRoute(cx))

+    # dont show an error when posting
+    @post '/logout', -> true
+    @post '/admin/switch-user', -> true
+
     # Google analytics
     @bind 'event-context-after', ->
       if window._gaq? # we dont use ga in test mode


Enable popovers on pricing page

Enable popovers on pricing page

--- js/outer.coffee
+++ js/outer.coffee
@@ -162,6 +162,14 @@
     placeholder()
     follow()

+  pricing.lib = =>
+    $('html').popover
+      html: true
+      placement: "top"
+      trigger: "hover"
+      selector: ".more-info"
+
+
   # Twitter Follow

   # Google analytics


Refresh effect for app tiles

Refresh effect for app tiles

--- app/assets/javascripts/ajax.js.coffee
+++ app/assets/javascripts/ajax.js.coffee
@@ -112,6 +112,8 @@
       $("#project-page-#{p_id} abbr.timeago").timeago();
       add_click_to_test_buttons()
       add_tooltips()
+      glow_effect(".app-tile")
+      set_icon(p_id, false)
       )


Los mapas también funcionan en la página de ayuda del editor.

--- app/assets/javascripts/maps.js.coffee
+++ app/assets/javascripts/maps.js.coffee
@@ -14,4 +14,4 @@

       map.setCenter(lonlat, 15)

-$(document).ready -> $('article.pagina').worldMaps()
+$(document).ready -> $('article.pagina, body.static #main').worldMaps()


:lipstick:

:lipstick:

--- spec/package-generator-spec.coffee
+++ spec/package-generator-spec.coffee
@@ -54,7 +54,7 @@
       expect(apmExecute.mostRecentCall.args[0]).toBe 'apm'
       expect(apmExecute.mostRecentCall.args[1]).toEqual ['init', '--package', "#{path.join(path.dirname(packagePath), "camel-case-is-for-the-birds")}"]

-    describe 'which is regular package theme', ->
+    describe 'when creating a package', ->
       beforeEach -> rootView.trigger("package-generator:generate-package")

       it "calls `apm init`", ->
@@ -68,7 +68,7 @@
         expect(apmExecute.mostRecentCall.args[0]).toBe 'apm'
         expect(apmExecute.mostRecentCall.args[1]).toEqual ['init', '--package', "#{packagePath}"]

-    describe 'which is a theme', ->
+    describe 'when creating a theme', ->
       beforeEach -> rootView.trigger("package-generator:generate-theme")

       it "calls `apm init`", ->


Increase clarity of `waitsFor` block

Increase clarity of `waitsFor` block

--- spec/tree-view-package-spec.coffee
+++ spec/tree-view-package-spec.coffee
@@ -1813,7 +1813,7 @@
                 dirView.entries.querySelectorAll(".file").length > 1

               waitsFor "tree view selection to be updated", ->
-                treeView.element.querySelector('.file.selected')
+                treeView.element.querySelector('.file.selected') isnt null

               runs ->
                 expect(treeView.element.querySelector('.selected').textContent).toBe path.basename(newPath)


fixed some js oddities with .on('click'...)

--- app/assets/javascripts/pins.js.coffee
+++ app/assets/javascripts/pins.js.coffee
@@ -33,7 +33,7 @@
 	)

-	$('.pin-link').click(() ->
+	$('body').on('click', '.pin-link', () ->
 		title = "Pin " + $(this).data('pin')
 		url = "/" + History.getState().cleanUrl.split("/")[3] + '/' + $(this).data('stream') + '/pins/' + $(this).data('pin')
 		History.pushState({ stream: $(this).data('stream'), pin: $(this).data('pin') }, title,  url)


do not evaluate unless current editor is supercollider

--- lib/controller.coffee
+++ lib/controller.coffee
@@ -53,12 +53,17 @@
       if fn
         promise.done(fn)

+  editorIsSC: ->
+    editor = atom.workspace.getActiveEditor()
+    editor and editor.getGrammar().scopeName is 'source.supercollider'
+
   currentExpression: ->
     editor = atom.workspace.getActiveEditor()
     return unless editor?
     editor.getSelectedText() or editor.getText()

   eval: ->
+    return unless @editorIsSC()
     expression = @currentExpression()

     doEval = =>


Aligned datepicker configs

Aligned datepicker configs

--- app/assets/javascripts/reports.coffee
+++ app/assets/javascripts/reports.coffee
@@ -4,4 +4,6 @@
     language: 'sv'
     autoclose: true
     todayHighlight: true
-    endDate: 'today'
+    todayBtn: true
+    orientation: 'left bottom'
+    keyboardNavigation: false


Small translation bug on issues list

Small translation bug on issues list

--- app/coffee/modules/issues/list.coffee
+++ app/coffee/modules/issues/list.coffee
@@ -70,7 +70,7 @@
                   @navUrls, @events, @analytics, @translate, @errorHandlingService, @storage, @filterRemoteStorageService, @projectService) ->
         bindMethods(@)

-        @scope.sectionName = "Issues"
+        @scope.sectionName = @translate.instant("PROJECT.SECTION.ISSUES")
         @.voting = false

         return if @.applyStoredFilters(@params.pslug, @.filtersHashSuffix)


Fancier syntax for db_index options

Fancier syntax for db_index options

--- lib/dispatcher.coffee
+++ lib/dispatcher.coffee
@@ -20,9 +20,9 @@
     @_idle_timeout = options.idle_timeout ? (if @_test_mode then 500 else 10000)
     @_audit_log = new AuditLog stream: options.audit
     {db_index} = options
-    @_control_channel = new ControlChannel db_index: db_index
-    @_requests_channel = new RequestChannel db_index: db_index
-    @_responses_channel = new ResponseChannel db_index: db_index
+    @_control_channel = new ControlChannel {db_index}
+    @_requests_channel = new RequestChannel {db_index}
+    @_responses_channel = new ResponseChannel {db_index}
     @_dependency_count = {}
     @_state = {}
     @_cycles = {}


Updated gruntfile

Updated gruntfile

--- Gruntfile.coffee
+++ Gruntfile.coffee
@@ -54,6 +54,9 @@
       haml:
         files: 'src/haml/**/*.haml'
         tasks: ['haml']
+      images:
+        files: 'src/images/**'
+        tasks: ['copy']

   grunt.loadNpmTasks('grunt-contrib-sass')
   grunt.loadNpmTasks('grunt-contrib-coffee')


Grunt: Fix options passed to microflo-emscripten

--- Gruntfile.coffee
+++ Gruntfile.coffee
@@ -7,7 +7,8 @@
         "MICROFLO=./node_modules/.bin/microflo"
         "GRAPH=graph.fbp"
         "MICROFLO_SOURCE_DIR=`pwd`/node_modules/microflo/microflo"
-        "LIBRARY=`pwd`/components/arduino-standard.json"
+        "PROJECT_DIR=`pwd`/node_modules/microflo-emscripten"
+        "LIBRARYOPTION='--library `pwd`/components/arduino-standard.json'"
     ]
     return build.join ' '


Rename grunt sub task to be consistent with other projects.

--- Gruntfile.coffee
+++ Gruntfile.coffee
@@ -5,7 +5,7 @@

     # Generate library from Peg grammar
     peg:
-      preparser:
+      parser:
         src: 'src/grammar.peg'
         dest: 'lib/parser.js'


Create aws_config.json if there is not one.

--- Gruntfile.coffee
+++ Gruntfile.coffee
@@ -16,6 +16,11 @@
 assetPaths = assetPaths.map (assetPath) -> assetPath.split('/').join(path.sep)

 module.exports = (grunt) ->
+  awsConfigPath = 'aws_config.json'
+  if !grunt.file.exists(awsConfigPath)
+    grunt.file.copy("#{awsConfigPath}.example", awsConfigPath)
+  awsJSON = grunt.file.readJSON(awsConfigPath)
+
   grunt.initConfig
     pkg: grunt.file.readJSON('package.json')
     concurrent:
@@ -112,7 +117,7 @@
             'Gemfile.lock'
             'dump.rdb'
           ]
-    aws: grunt.file.readJSON("aws_config.json")
+    aws: awsJSON
     s3:
       options:
         accessKeyId: "<%= aws.accessKeyId %>"


More consistent task name.

More consistent task name.

--- Gruntfile.coffee
+++ Gruntfile.coffee
@@ -33,7 +33,7 @@

       coffee:
         files: ["./app/scripts/**/*.coffee"]
-        tasks: ["coffee:dist", "browserify2:compile"]
+        tasks: ["coffee:dist", "browserify2:dist"]

       coffeeTest:
         files: ["test/**/*.coffee"]
@@ -73,7 +73,7 @@
         ]

     browserify2:
-      compile:
+      dist:
         entry: "./dist/scripts/my_app.js"
         compile: "./dist/scripts/application.js"

@@ -111,7 +111,7 @@
     "clean:dist"
     "copy:dist"
     "coffee:dist"
-    "browserify2:compile"
+    "browserify2:dist"
   ]

   grunt.registerTask "server", [


Correction chemin image dans gruntfile

Correction chemin image dans gruntfile

--- Gruntfile.coffee
+++ Gruntfile.coffee
@@ -134,7 +134,7 @@
         flatten: true
       icons:
         expand: true
-        src: 'bower_components/material-design-icons/*/production/*_24px.svg'
+        src: 'bower_components/material-design-icons/*/svg/production/*_24px.svg'
         dest: 'build/css/icons/'
         flatten: true


fix #88, we can now run `grunt run` in Mac

--- Gruntfile.coffee
+++ Gruntfile.coffee
@@ -36,7 +36,7 @@
             runnw:
                 options:
                     stdout: true
-                command: [ '/build/cache/mac/0.9.2/node-webkit.app/Contents/MacOS/node-webkit --debug' , '\\build\\cache\\win\\0\.9\.2\\nw.exe --debug' ].join('&')
+                command: [ './build/cache/mac/0.9.2/node-webkit.app/Contents/MacOS/node-webkit . --debug' , '\\build\\cache\\win\\0\.9\.2\\nw.exe --debug' ].join('&')

         'regex-replace':
             windows_installer:


Make sure the cache is cleared.

Make sure the cache is cleared.

Actually we should run this in our vm, but I don't like that, therefore
I just remove the folders, so the cache is regenerated on reload.

--- Gruntfile.coffee
+++ Gruntfile.coffee
@@ -83,6 +83,9 @@
       beforeGenerateIconFonts: [
         '<%= assetsPath %>/sass/_icons.scss'
         '<%= assetsPath %>/sass/_icon-*.scss'
+      ]
+      removeSymfonyCache: [
+        'app/cache/*'
       ]

     # Imagemin configuration
@@ -289,9 +292,12 @@

   # Do Assetic stuff
   grunt.registerTask 'generateAsseticAssets', [
+    'clean:removeSymfonyCache'
     'shell:clearCache'
     'shell:asseticDump'
     'shell:assetsInstall'
+    'shell:clearCache'
+    'clean:removeSymfonyCache'
   ]

   # Default task


更新Gruntfile

更新Gruntfile

--- Gruntfile.coffee
+++ Gruntfile.coffee
@@ -5,10 +5,10 @@
 	grunt.initConfig
 		pkg: pkg
 		clean:
-			build: ["dest/work", "dist"]
-			workTemp: ["dest/work/cola"]
-			dev: ["dest/dev"]
-			"core-widget": ["dist/cola-widget.js"]
+			build: [ "dest/work", "dist" ]
+			workTemp: [ "dest/work/cola" ]
+			dev: [ "dest/dev" ]
+			"core-widget": [ "dist/cola-widget.js" ]
 		coffee:
 			dev:
 				options:
@@ -64,19 +64,19 @@
 			libs:
 				expand: true
 				cwd: "src"
-				src: ["lib/**"]
+				src: [ "lib/**" ]
 				dest: "dest/dev"

 			semantic:
 				expand: true
 				cwd: "src/lib/semantic-ui"
-				src: ["themes/**", "semantic.css", "semantic.js"]
+				src: [ "themes/**", "semantic.css", "semantic.js" ]
 				dest: "dist"

 			apiResources:
 				expand: true
 				cwd: "node_modules/grunt-cola-ui-build"
-				src: ["resources/**"]
+				src: [ "resources/**" ]
 				dest: "api"

 		uglify:
@@ -98,18 +98,18 @@
 				files: [
 					expand: true
 					cwd: "src"
-					src: ["**/*.yaml"]
+					src: [ "**/*.yaml" ]
 					dest: "api"
 				]
 		watch:
 			coffee:
-				files: ["src/**/*.coffee"]
+				files: [ "src/**/*.coffee" ]
 				tasks: "coffee:dev"
 			less:
-				files: ["src/**/*.less"]
+				files: [ "src/**/*.less" ]
 				tasks: "less:dev"
 			libs:
-				files: ["src/lib/**"]
+				files: [ "src/lib/**" ]
 				tasks: "copy:libs"
 		yamlToDoc:
 			api:
@@ -120,7 +120,7 @@
 					{
 						expand: true
 						cwd: "src"
-						src: ["**/*.yaml"]
+						src: [ "**/*.yaml" ]
 						dest: "api"
 					}
 				]
@@ -135,7 +135,7 @@
 		"cola-ui-license":
 			options:
 				license: """
-/*! Colla - #{pkg.version}
+/*! Cola - #{pkg.version}
  * Copyright (C) 2015-2017 Benny Bao & Alex Tong.
  * Licensed under the MIT license */

@@ -154,18 +154,18 @@
 					"dist/3rd.js": sources.lib.js
 			cola:
 				files:
-					"dist/cola.js": ["dist/cola-core.js", "dist/cola-widget.js"]
+					"dist/cola.js": [ "dist/cola-core.js", "dist/cola-widget.js" ]
 			all:
 				files:
-					"dist/all/javascript.js": ["dist/3rd.js", "dist/semantic.js", "dist/cola.js"]
-					"dist/all/css.js": ["dist/semantic.css", "dist/cola.css"]
+					"dist/all/javascript.js": [ "dist/3rd.js", "dist/semantic.js", "dist/cola.js" ]
+					"dist/all/css.js": [ "dist/semantic.css", "dist/cola.css" ]
 		cssmin:
 			target:
 				files: [
 					{
 						expand: true
 						cwd: "dist"
-						src: ["cola.css", "semantic.css"]
+						src: [ "cola.css", "semantic.css" ]
 						dest: "dist"
 						ext: ".min.css"
 					}
@@ -219,16 +219,16 @@
 	grunt.loadNpmTasks "grunt-contrib-cssmin"
 	grunt.loadNpmTasks "grunt-contrib-compress"

-	grunt.registerTask "compile", ["clean:dev", "coffee:dev", "less:dev", "copy:libs"]
-	grunt.registerTask "api", ["yamlToDoc", "copy:apiResources"]
-	grunt.registerTask "all", ["clean", "coffee", "less", "uglify", "copy"]
-	grunt.registerTask "w", ["watch"]
-	grunt.registerTask "build", ["clean:build", "cola-ui-clean", "coffee:cola-core", "coffee:cola-widget",
+	grunt.registerTask "compile", [ "clean:dev", "coffee:dev", "less:dev", "copy:libs" ]
+	grunt.registerTask "api", [ "yamlToDoc", "copy:apiResources" ]
+	grunt.registerTask "all", [ "clean", "coffee", "less", "uglify", "copy" ]
+	grunt.registerTask "w", [ "watch" ]
+	grunt.registerTask "build", [ "clean:build", "cola-ui-clean", "coffee:cola-core", "coffee:cola-widget",
 		"coffee:i18n",
 		"less:build", "cola-ui-license", "concat:3rd-core", "concat:3rd", "concat:cola",
 		"clean:core-widget", "copy:semantic",
 		"uglify:build",
 		"cssmin",
-#								 "compress",
-		"clean:workTemp"]
-	grunt.registerTask "concat-all", ["build", "concat:all"]+		#								 "compress",
+		"clean:workTemp" ]
+	grunt.registerTask "concat-all", [ "build", "concat:all" ]


Dynamic repo name detection for commit status

--- Gruntfile.coffee
+++ Gruntfile.coffee
@@ -25,9 +25,11 @@
     type: 'oauth'
     token: process.env.GITHUB_TOKEN

+  repo = (process.env.TRAVIS_REPO_SLUG || 'baconjs/bacon.js').split('/', 2)
+
   q =
-    user: 'baconjs',
-    repo: 'bacon.js',
+    user: repo[0],
+    repo: repo[1],
     sha: sha,
     state: state
     context: 'continous-integration/browserstack'


wspace

wspace

--- Gruntfile.coffee
+++ Gruntfile.coffee
@@ -225,6 +225,7 @@

   # Grunt contribution tasks.
   grunt.loadNpmTasks('grunt-contrib-clean')
+
   grunt.loadNpmTasks('grunt-contrib-handlebars')
   grunt.loadNpmTasks('grunt-contrib-stylus')
   grunt.loadNpmTasks('grunt-contrib-coffee')


Copy .htaccess file to dist folder

Copy .htaccess file to dist folder

--- Gruntfile.coffee
+++ Gruntfile.coffee
@@ -140,6 +140,9 @@
 					cwd: '.'
 					src: config.image_files
 					dest: '<%= config.dist %>'
+				,
+					src: '.htaccess',
+					dest: '<%= config.dist %>/.htaccess'
 				]

 		ngtemplates:
@@ -157,6 +160,7 @@
 					expand: yes
 					cwd: '<%= config.dist %>'
 					src: ['**']
+					dot: yes
 					dest: 'v<%= bower.version %>'
 				]


* grunt test use dot report

* grunt test use dot report

--- Gruntfile.coffee
+++ Gruntfile.coffee
@@ -35,7 +35,7 @@
           ui: 'bdd'
           quiet: false
           require: 'coffee-script/register'
-          #reporter: 'dot'
+          reporter: 'dot'
           check: ['src/**/*.coffee', 'test/**/*.js', 'test/**/*.coffee']
         src: ['test/**/*.coffee']

@@ -65,7 +65,7 @@
   grunt.loadNpmTasks('grunt-contrib-clean')
   grunt.loadNpmTasks('grunt-newer')

-  grunt.registerTask('build', ['newer:coffee', 'copy'])
+  grunt.registerTask('build', ['newer:coffee', 'newer:copy'])
   grunt.registerTask('rebuild', ['clean', 'build'])
   grunt.registerTask('test', ['build', 'mochaTest'])
   grunt.registerTask('watch', ['watch'])


boilerplated

boilerplated

--- Gruntfile.coffee
+++ Gruntfile.coffee
@@ -5,7 +5,6 @@
     pkg: grunt.file.readJSON('package.json')

-    # Wipe out previous builds and test reporting.
     clean:
       dev:
         src: 'tmp/'
@@ -51,20 +50,26 @@
           'dist/index.html': ['index.html']

-    # This task uses James Burke's excellent r.js AMD builder to take all
-    # modules and concatenate them into a single file.
+    # Inspirational reading: https://github.com/jrburke/r.js/blob/master/build/example.build.js
     requirejs:
       compile:
         options:
           baseUrl: 'tmp/app'
           mainConfigFile: 'tmp/app/config.js'
-          moduleDirs: ["tmp/app"]
+
+          include: ["main"]
+          insertRequire: ["main"]
+          findNestedDependencies: true
+          name: "almond"
+
+          wrap: true

           out: 'tmp/application.js'
-          optimize: ''
+          optimize: 'none'

           generateSourceMaps: false
           preserveLicenseComments: true
+          waitSeconds: 7

     copy:
@@ -167,11 +172,13 @@
     #   }
     # },

+
     concurrent:
       pipe:
         tasks: ['server', 'watch']
         options:
             logConcurrentOutput: true
+

     server:
       options:
@@ -217,7 +224,8 @@
   grunt.loadNpmTasks('grunt-contrib-coffee')

   grunt.loadNpmTasks('grunt-processhtml')
-  grunt.loadNpmTasks('grunt-bbb-requirejs')
+  # grunt.loadNpmTasks("grunt-bbb-requirejs")
+  grunt.loadNpmTasks('grunt-contrib-requirejs')

   grunt.loadNpmTasks('grunt-contrib-copy')
   grunt.loadNpmTasks('grunt-contrib-uglify')
@@ -225,11 +233,12 @@

   grunt.loadNpmTasks('grunt-contrib-compress')

+
   # Third-party tasks.
   # grunt.loadNpmTasks('grunt-karma')
   # grunt.loadNpmTasks('grunt-karma-coveralls')

-  # Grunt BBB tasks.
+
   grunt.loadNpmTasks('grunt-concurrent')
   grunt.loadNpmTasks('grunt-bbb-server')
   grunt.loadNpmTasks('grunt-contrib-watch')
@@ -237,6 +246,7 @@
   # Create an aliased test task.
   # grunt.registerTask('test', ['karma:run'])

+
   grunt.registerTask('dev', [
     'clean'

@@ -263,4 +273,3 @@

     'compress'
   ])
-


Make editable code buildable

Make editable code buildable

--- Gruntfile.coffee
+++ Gruntfile.coffee
@@ -141,6 +141,11 @@
               'cs!pages/contents/contents'
               'cs!pages/search/search'
               'cs!pages/me/me'
+
+              # FIX: edit modules should be loaded in separate modules
+              'select2'
+              'cs!modules/media/editbar/editbar'
+              'cs!helpers/backbone/views/editable'
             ]
             exclude: ['coffee-script', 'less/normalize']
             excludeShallow: ['settings']


Mount#unmount should remove "update" event listener from component


The bolus arrival index is on the scan, not the session.

--- app/javascripts/intensityChart.coffee
+++ app/javascripts/intensityChart.coffee
@@ -96,7 +96,7 @@
       data = [scanDataSeries].concat(regDataSeries)

       # Add the bolus arrival bar.
-      bolusArvNdx = scan.session.bolusArrivalIndex
+      bolusArvNdx = scan.bolusArrivalIndex
       if bolusArvNdx?
         # Extend the bar from the axis to the top.
         dsIntensities = (_.map(dataSeries.values, 'y') for dataSeries in data)


Change to use jQuery's function for checking if a single element is visible.

To achieve the same comprehensive check of visibility as the original
$el.is(":visible") code, we use jQuery's function for checking if a
single element is visible.  Which is a different method to
$el.is(":visible") which looks for $el in the array of elements that
match :visible from the entire DOM

--- src/view.coffee
+++ src/view.coffee
@@ -44,7 +44,7 @@
   #
   # @return [Boolean]
   visible: ->
-    @$el[0].style.display == "block"
+    $.expr.filters.visible(@$el[0])

   highlighted: ->
     @$el.find(".cur").length > 0


Don't need to use pane.

Don't need to use pane.

--- lib/highlighted-area-view.coffee
+++ lib/highlighted-area-view.coffee
@@ -43,12 +43,11 @@
     range =  [[0, 0], editor.getEofBufferPosition()]

     @ranges = []
-    @paneItem = atom.workspaceView.getActivePaneItem()
     editor.scanInBufferRange new RegExp(result[0], 'g'), range,
       (result) =>
         if prefix = result.match[1]
           result.range = result.range.translate([0, prefix.length], [0, 0])
-        @ranges.push @paneItem.markBufferRange(result.range).getScreenRange()
+        @ranges.push editor.markBufferRange(result.range).getScreenRange()

     for range in @ranges
       view = new MarkerView(range, this, @getEditorView())


if AuthenticateUser()'s fetchMyMemberships promise is rejected, clear out cookie before redirecting to login

--- app/services/authenticate-user.coffee
+++ app/services/authenticate-user.coffee
@@ -26,6 +26,9 @@
           deferred.resolve(CurrentUser())
         .catch (data) ->
           Toast.show('Please log in to continue')
+          ipCookie.remove('currentUserId')
+          ipCookie.remove('currentGroupId')
+          ipCookie.remove('initialRequestPath')
           $location.path('/')
           deferred.reject()
     else


Add a test for when apikey does not belong to owner of box

--- test/ssh_keys.coffee
+++ test/ssh_keys.coffee
@@ -113,6 +113,27 @@
           (_.isEqual (JSON.parse resp.body), {"error":"Unauthorised"}).should.be.true
           done()

+    describe 'when the apikey does not belong to the box creator', ->
+      before ->
+        apikey2 = 'otheruserapikey'
+        new User({apikey: apikey2}).save()
+
+        froth = nock('https://scraperwiki.com')
+        .get("/froth/check_key/otheruserapikey")
+        .reply 200, "200", { 'content-type': 'text/plain' }
+
+      it 'returns an error', (done) ->
+        options =
+          uri: URL
+          form:
+            apikey: 'otheruserapikey'
+            sshkey: 'blah'
+
+        request.post options, (err, resp, body) ->
+          resp.statusCode.should.equal 403
+          (_.isEqual (JSON.parse resp.body), {"error":"Unauthorised"}).should.be.true
+          done()
+
     describe "when the box doesn't exist", ->
       response = null
       before (done) ->


Draft implementation of the monitor

Draft implementation of the monitor

--- library/visualize/monitor.coffee
+++ library/visualize/monitor.coffee
@@ -61,6 +61,28 @@
         throw new Error noTagging unless _.isSring tag
         throw new Error noKernel unless isKernel

+    # Attach one of the ends of the monitor to the previously bound
+    # transport instance. This method will attach the specific event
+    # handlers for all of the reference events, which will transfer
+    # the event into the corresponding event on the bound element.
+    attachToTransport: -> for descriptor in @constructor.REFERENCE
+        @transport.on descriptor.event, (event, origin, context) ->
+            resolved = @element.resolve origin
+            missing = "Cannot resolve element #{origin}"
+            throw new Error missing unless resolved?
+            @element.emit event, resolved, context
+
+    # Attach one of the ends of the monitor to the previously bound
+    # element instance. This method will attach the specific event
+    # handlers for all of the reference events, which will transfer
+    # the event into the corresponding event on the bound transport.
+    attachToTransport: -> for descriptor in @constructor.REFERENCE
+        @element.on descriptor.event, (event, origin, context) ->
+            tagging = @element.tag or undefined
+            missing = "The element has not tag attached"
+            throw new Error missing unless tagging?
+            @transport.emit event, tagging, context
+
     # Set the transport channel of this session. If the transport is
     # not supplied, the method will return the transport instead of
     # setting one. The transport will be tested to ensure that it is


Added onBlur Abstract method to BaseView

--- Framework/Views/BaseView.coffee
+++ Framework/Views/BaseView.coffee
@@ -20,6 +20,7 @@
     @window = Ti.UI.createWindow(@settings)
     @window.addEventListener('focus', @focus)
     @window.addEventListener('close', @onClose)
+    @window.addEventListener('blur', @onBlur)

     @content = Ti.UI.createView({
       height: Ti.UI.FILL
@@ -105,6 +106,8 @@
     @onClose()

   onClose: ->
+
+  onBlur: ->

   add: (control) ->
     @content.add control