Correctly fire change events with hasMany collections.

--- app/assets/javascripts/slickbone.js.coffee
+++ app/assets/javascripts/slickbone.js.coffee
@@ -27,7 +27,6 @@
     # Listen for the event, change the Collection's comparator appropriately and re-sort.
     # The grid will pick up the changes because we raise a `reset` event after sort().
     @grid.onSort.subscribe (event, args) =>
-      console.log 'args', arguments...
       sortType = args.sortCol.sortType || 'string'
       @comparator = @comparatorDefinitions[sortType](@, args.sortCol.field, args.sortAsc)
       @sort()
@@ -131,11 +130,8 @@

   _createEmptyCollections: ->
     return if @_emptyCollectionsCreated
-    for name, definition of @associations
-      if definition.associationType == 'hasMany'
-        newCollection = new definition.model()
-        newCollection.bind 'all', @handleAssociatedCollectionEvent
-        @attributes[name] = new definition.model()
+    for name, definition of @associations when definition.associationType == 'hasMany'
+      @attributes[name] = (new definition.model).bind('all', @handleAssociatedCollectionEvent)
     @_emptyCollectionsCreated = true

   # Add a derived field to the end of the derivation chain.
@@ -159,32 +155,33 @@
   #   the options hash passed in.
   # * If an attribute being set is subject to conversion, execute the type conversion.
   set: (attrs, options) ->
-    @_createEmptyCollections() unless @_emptyCollectionsCreated #
+    @_createEmptyCollections() unless @_emptyCollectionsCreated
     for attribute, value of attrs
       if association = @associations[attribute]
         currentValue = @attributes[attribute]
+
         attrs[attribute] = switch association.associationType
           when 'hasOne'
             if currentValue
               currentValue.set(value, silent: true)
             else
-              newModel = new association.model(value)
-              newModel.bind 'all', @handleAssociatedModelEvent
-              newModel
+              (new association.model(value)).bind 'all', @handleAssociatedModelEvent
           when 'hasMany'
             @attributes[attribute].reset(value, silent: true)
       if converter = @converters[attribute]
         if _.isFunction(converter)
-          attrs[attribute] = converter(value)#
+          attrs[attribute] = converter(value)
         else
           throw "The conversion function for #{attribute} is invalid; it must be a function."
     super

   handleAssociatedModelEvent: =>
-    Compass.debug('associated model event. context:', @, 'args:', arguments)
+    alert('models')

-  handleAssociatedCollectionEvent: =>
-    Compass.debug('associated collection event. context:', @, 'args:', arguments)
+  handleAssociatedCollectionEvent: (event, changedItem, options) =>
+    switch event
+      when 'change', 'add', 'remove', 'reset'
+        @change(options)

   # Override the default Backbone.js `toJSON` method to handle associations.
   toJSON: ->


Removed silent flags from the hasOne and hasMany relationships

--- app/assets/javascripts/slickbone.js.coffee
+++ app/assets/javascripts/slickbone.js.coffee
@@ -32,7 +32,7 @@
       @sort()

     # Tell the grid when a model is added to SlickBone.Collection.
-    @bind 'add', (model)  =>
+    @bind 'add', (model)  =>
       @grid.updateRowCount()
       @grid.invalidateRow(@length - 1)
       @grid.render()
@@ -43,7 +43,7 @@
       @grid.render()

     # Tell the grid that a model has been removed from a SlickBone.Collection.
-    @bind 'remove', (model) =>
+    @bind 'remove', (model) =>
       @grid.updateRowCount()
       @grid.render()

@@ -56,7 +56,7 @@
     @grid.invalidate()

   # Return the JSON associated with a particular index in the collection.
-  getItem: (index) ->
+  getItem: (index) ->
     model = @at(index)
     if model?
       attrs = model.toJSON()
@@ -66,7 +66,7 @@
   # You can modify this hash to define different comparator types.
   comparatorDefinitions:
     number: (collection, field, sortAsc) ->
-      (model) ->
+      (model) ->
         val = Number(model.get(field))
         if sortAsc then val else -val
     string: (collection, field, sortAsc) ->
@@ -112,17 +112,17 @@

   # indicates that a given attribute is actually a Collection. Adds the correct settings to
   # the association hash.
-  hasMany:   (name, collection) ->
+  hasMany:   (name, collection) ->
     @associations[name] = { model: collection, associationType: 'hasMany' }

   # indicates that a given attribute is actually a Model. Adds the correct settings to
   # the association hash.
-  hasOne:    (name, model)      ->
+  hasOne:    (name, model)      ->
     @associations[name] = { model: model, associationType: 'hasOne' }

   # Actually calculate and set the derived fields in the prescribed order as
   # specified by the derivation chain.
-  _executeDerivations: ->
+  _executeDerivations: ->
     for derivation in @derivations
       result = {}
       result[derivation.field] = derivation.func(@)
@@ -162,13 +162,13 @@
         currentValue = @attributes[attribute]

         attrs[attribute] = switch association.associationType
-          when 'hasOne'
-            if currentValue
-              currentValue.set(value, silent: true)
-            else
+          when 'hasOne'
+            if currentValue
+              currentValue.set(value)
+            else
               (new association.model(value)).bind 'all', @handleAssociatedModelEvent
           when 'hasMany'
-            @attributes[attribute].reset(value, silent: true)
+            @attributes[attribute].reset(value)
       if converter = @converters[attribute]
         if _.isFunction(converter)
           attrs[attribute] = converter(value)


Fix undefined method error

Fix undefined method error

--- app/assets/javascripts/swimlanes.js.coffee
+++ app/assets/javascripts/swimlanes.js.coffee
@@ -35,8 +35,12 @@

   update_story_counter: ->
       counter = @_el.find('.swimlane-header .info')
-      stories = @_el.find('.story').size()
-      counter.text("#{stories} issue#{'s' if stories > 1}")
+      total = @_el.find('.story').size()
+
+      if total == 1
+        counter.text("#{total} issue")
+      else
+        counter.text("#{total} issues")

   # Private methods
   _set_attr_readers: (type) ->


test(clean-rb-client): fix it by making sure app config is set

--- test/tests/clean/clean-rb-client-spec.coffee
+++ test/tests/clean/clean-rb-client-spec.coffee
@@ -7,26 +7,31 @@
 fs           = Promise.promisifyAll require 'fs'
 config       = require "#{process.cwd()}/temp/config.json"
 tests        = require("#{config.paths.abs.test.helpers}/tests") config
-appConfig    = tests.get.app.config()
-rbDirName    = appConfig.rb.prefix.distDir
 rbClientPath = config.paths.abs.test.app.dist.client.build
+rbDirName    = config.pkgs.rb.name

 # tests
 # =====
 describe task, ->
-	if appConfig.exclude.default.client.files
-		msg  = "should delete client dist #{rbDirName} dir "
-		msg += "if build option exclude.default.client.files is true"
-		it msg, async (done) ->
-			try stats = await fs.statAsync rbClientPath
-			result = stats?.isDirectory()
-			expect(result).not.toBeDefined()
-			done()
-	else
-		msg  = "should not delete client dist #{rbDirName} dir "
-		msg += "if build option exclude.default.client.files is false"
-		it msg, async (done) ->
-			try stats = await fs.statAsync rbClientPath
-			result = stats?.isDirectory()
-			expect(result).toBeDefined()
-			done()+	appConfig = undefined
+
+	beforeAll ->
+		appConfig = tests.get.app.config()
+
+	msg1  = "should delete client dist #{rbDirName} dir "
+	msg1 += "if build option exclude.default.client.files is true"
+	it msg1, async (done) ->
+		return done() unless appConfig.exclude.default.client.files
+		try stats = await fs.statAsync rbClientPath
+		result = stats?.isDirectory()
+		expect(result).not.toBeDefined()
+		done()
+
+	msg2  = "should not delete client dist #{rbDirName} dir "
+	msg2 += "if build option exclude.default.client.files is false"
+	it msg2, async (done) ->
+		return done() if appConfig.exclude.default.client.files
+		try stats = await fs.statAsync rbClientPath
+		result = stats?.isDirectory()
+		expect(result).toBeDefined()
+		done()


discussions: fix commenting on topics containing videos

fixes CNVS-7974

test plan:
  * create a discussion topic containing this HTML:

<object width="480" height="385" data="http://www.youtube.com/v/y8mzDvpKzfY?fs=1&hl=en_US" type="application/x-shockwave-flash"></object>

  * view the topic
  * verify that the video is displayed
  * verify that you can add a comment at the root level on the topic

Change-Id: I05b20f4635ca999044fe90c9334de2bde402be9c
Reviewed-on: https://gerrit.instructure.com/36221
Tested-by: Jenkins <d95b56ce41a2e1ac4cecdd398defd7414407cc08@instructure.com>
Reviewed-by: Drew Bowman <43bd25f9469d5056946537962fe98ec04e66c401@instructure.com>
QA-Review: Trevor deHaan <85df72112e8a9484fec7b3db2e31789c2c2d4e07@instructure.com>
Product-Review: Braden Anderson <5d57265d16cfe2e0f2e6eb7f13e876bb378ef0f1@instructure.com>

--- app/coffeescripts/discussions/Reply.coffee
+++ app/coffeescripts/discussions/Reply.coffee
@@ -22,7 +22,7 @@
       @discussionEntry = @el.closest '.discussion_entry'
       # required for non-threaded reply area at bottom of an entry block
       @discussionEntry = @el.closest '.entry' if @discussionEntry.length == 0
-      @form = @discussionEntry.find('form:first').submit preventDefault @submit
+      @form = @discussionEntry.find('form.discussion-reply-form:first').submit preventDefault @submit
       @textArea = @getEditingElement()
       @form.find('.cancel_button').click @hide
       @form.on 'click', '.toggle-wrapper a', (e) =>


placeholder

placeholder

--- lib/ui.coffee
+++ lib/ui.coffee
@@ -69,6 +69,7 @@
   protected: false
   excludedFiles: null
   queryForSelectFiles: null
+  delayedRefreshTimeout: null

   onDidMoveToPrompt: (fn) -> @emitter.on('did-move-to-prompt', fn)
   emitDidMoveToPrompt: -> @emitter.emit('did-move-to-prompt')


ApplicationTabHandleHolder: Make sure there is handle (since its optional this check is necessary)

--- client/Main/CommonViews/applicationview/applicationtabhandleholder.coffee
+++ client/Main/CommonViews/applicationview/applicationtabhandleholder.coffee
@@ -15,6 +15,8 @@
     @addPlusHandle()  if @getOptions().addPlusHandle

   addPlusHandle: ->
+    @plusHandle?.destroy()
+
     @addSubView @plusHandle = new KDCustomHTMLView
       cssClass : "kdtabhandle visible-tab-handle plus"
       partial  : ""


landing/payment: setup inputs correctly with v3

Signed-off-by: Umut Sirin <4055abbc0e40a1254e715b952ccd414607e0b365@gmail.com>

--- client/landing/site.landing/coffee/team/forms/stripepaymenttabform.coffee
+++ client/landing/site.landing/coffee/team/forms/stripepaymenttabform.coffee
@@ -86,8 +86,39 @@

     super

-    Payment.formatCardNumber @number.getElement()
-    Payment.formatCardCVC @cvc.getElement()
+    utils.loadStripe().then (client) =>
+
+      @stripeClient = client
+
+      style =
+        base:
+          fontSize: '18px'
+          fontFamily: "'Proxima Nova','proxima-nova',Helvetica,Arial"
+          color: '#4a4a4a'
+          '::placeholder':
+            color: '#ccc'
+            fontWeight: 300
+
+      elements = client.elements()
+      @cardNumber = elements.create('cardNumber', { style, classes: base: 'kdinput text' })
+      cardExpiry = elements.create('cardExpiry', { style, classes: base: 'kdinput text' })
+      cardCvc = elements.create('cardCvc', { placeholder: '•••', style, classes: base: 'kdinput text' })
+
+      @cardNumber.on 'ready', => @emit 'ready'
+
+      @number.mountTo @cardNumber
+      @cvc.mountTo cardCvc
+      @expiration.mountTo cardExpiry
+
+      [@cardNumber, cardExpiry, cardCvc].forEach (element) =>
+        element.on 'change', =>
+          @forEachInputView (input) -> input.resetDecoration()
+
+
+  focusFirstElement: ->
+    @ready => @cardNumber.focus()
+
+
   submit: (event) ->
     kd.utils.stopDOMEvent event


rtmp: Fix crashing as to finished live stream

Fix a bug where the server crashes when RTMP client tries to resume a
finished live stream.

--- rtmp.coffee
+++ rtmp.coffee
@@ -1825,7 +1825,7 @@

     @lastSentTimestamp = null

-    if @stream.type is avstreams.STREAM_TYPE_RECORDED
+    if @stream?.type is avstreams.STREAM_TYPE_RECORDED
       clearQueuedRTMPMessages @stream
       _isPlaying = @isPlaying
       @isPlaying = false
@@ -2030,7 +2030,7 @@
     if doPause # playing -> pause
       @isPlaying = false
       @isWaitingForKeyFrame = false
-      if @stream.type is avstreams.STREAM_TYPE_RECORDED
+      if @stream?.type is avstreams.STREAM_TYPE_RECORDED
         @stream.pause?()
         logger.info "[rtmp:client=#{@clientid}] stream #{@stream.id} paused at #{msec / 1000} sec (client player time)"

@@ -2068,7 +2068,7 @@
       else # live stream
         callback null
     else # pausing -> resume
-      if @stream.type is avstreams.STREAM_TYPE_RECORDED
+      if @stream?.type is avstreams.STREAM_TYPE_RECORDED
         clearQueuedRTMPMessages @stream
         # RTMP 1.0 spec says that the server only sends messages with timestamps
         # greater than the specified msec, but it appears that Flash Player expects
@@ -2256,7 +2256,7 @@

       else # live
         @startPlaying()
-        @respondPlay requestCommand, callback, @stream.id
+        @respondPlay requestCommand, callback, @stream?.id

   closeStream: (callback) ->
     @isPlaying = false


act cache wip

act cache wip

--- core/KDScrollView.coffee
+++ core/KDScrollView.coffee
@@ -29,9 +29,7 @@
     thisEvent = thisEvent ? superResponse #only return superResponse if local handle didn't happen
     willPropagateToDOM = thisEvent

-  hasScrollBars:()->
-    log @getScrollHeight() > @getHeight()
-    @getScrollHeight() > @getHeight()
+  hasScrollBars:()-> @getScrollHeight() > @getHeight()

   getScrollHeight:()-> @$()[0].scrollHeight
   getScrollWidth:()->  @$()[0].scrollWidth


Remove console.log from server/server

Remove console.log from server/server

--- admin/static/coffee/servers/server.coffee
+++ admin/static/coffee/servers/server.coffee
@@ -51,7 +51,6 @@
                 id: r.row 'uuid'

             @timer = driver.run query, 5000, (error, result) =>
-                console.log JSON.stringify(result, null, 2)
                 # We should call render only once to avoid blowing all the sub views
                 if @loading is true
                     @loading = false


CLEANUP

CLEANUP

--- source/Art/Engine/Core/Drawing/ElementDrawMixin.coffee
+++ source/Art/Engine/Core/Drawing/ElementDrawMixin.coffee
@@ -91,7 +91,7 @@
             drawSteps = compactFlatten drawSteps
             needsNormalizing = false
             for step in drawSteps
-              {fill, outline, radius, color, colors, padding, shadow, to, from} = step
+              {fill, outline, radius, color, colors, padding, to, from} = step
               if (radius ? fill ? outline ? color ? colors ? padding ? to ? from ? looksLikeColor step)?
                 needsNormalizing = true
                 break


#137 small refactorings

#137 small refactorings

--- app/assets/javascripts/oxalis/model.coffee
+++ app/assets/javascripts/oxalis/model.coffee
@@ -53,7 +53,6 @@
             @user = new User(user)
             @scaleInfo = new ScaleInfo(dataSet.scale)

-            # TODO: Define color bit depth
             supportedDataLayers = [{name: "color", allowManipulation : true},
                                     {name: "volume", allowManipulation : false},
                                     {name: "segmentation", allowManipulation : false}]
@@ -94,7 +93,7 @@
               "positionChanged" : (position) =>
                 @flycam3d.setPositionSilent(position)

-            isSkeletonTracing = tracing.content.settings.allowedModes.indexOf("volume") == -1
+            isSkeletonTracing = "volume" not in tracing.content.settings.allowedModes
             if isSkeletonTracing
               @cellTracing = new CellTracing(tracing, @scaleInfo, @flycam, @flycam3d, @user)
             else


VT#renderer -> VT#view

VT#renderer -> VT#view

--- app/assets/javascripts/player/vt.js.coffee
+++ app/assets/javascripts/player/vt.js.coffee
@@ -1,6 +1,6 @@
 class AsciiIo.VT

-  constructor: (@cols, @lines, @renderer) ->
+  constructor: (@cols, @lines, @view) ->
     @data = ''
     @resetTerminal()
     @render()
@@ -309,7 +309,7 @@
     @buffer.setBrush AsciiIo.Brush.create(props)

   bell: ->
-    @renderer.visualBell()
+    @view.visualBell()
     # @trigger('bell')

   compilePatterns: ->
@@ -334,10 +334,15 @@

     @render()

+    if @data.length > 500
+      head = @data.slice(0, 100)
+      hex = ("0x#{c.charCodeAt(0).toString(16)}" for c in head)
+      console.log "failed matching: '" + Utf8.decode(head) + "' (" + hex.join() + ")" # [pos: " + (@dataIndex - count) + "]"
+
     @data.length is 0

   render: ->
-    @renderer.render(@buffer.changes(), @buffer.cursorX, @buffer.cursorY)
+    @view.render(@buffer.changes(), @buffer.cursorX, @buffer.cursorY)
     @buffer.clearChanges()

   # ==== Screen buffer operations
@@ -368,10 +373,10 @@
   # ------ Cursor control

   showCursor: ->
-    @renderer.showCursor true
+    @view.showCursor true

   hideCursor: ->
-    @renderer.showCursor false
+    @view.showCursor false

   # ----- Scroll control


will add reserved text for students

will add reserved text for students

fixes CNVS-33318

Test Plan:
As a student, reserve an appointment.
Close out of the appointment process.
Hover over your reserved appointment.
Note that the hover state says "Reserved"

Change-Id: I94f48f500d388e7de0eff347c8df786ddde8da2d
Reviewed-on: https://gerrit.instructure.com/95427
Reviewed-by: Felix Milea-Ciobanu <9384aa226ac9d3237ed0bc52e18ffcb251ee0bf7@instructure.com>
Tested-by: Jenkins
QA-Review: David Tan <6283e310a2278fc51bdc4fb5974f70dd9c3366b9@instructure.com>
Product-Review: Chris Ward <341ae4b10181e9ae5056162440771572020800f2@instructure.com>

--- app/coffeescripts/calendar/Calendar.coffee
+++ app/coffeescripts/calendar/Calendar.coffee
@@ -253,7 +253,9 @@

       reservedText = ""
       if event.isAppointmentGroupEvent()
-        if event.reservedUsers == ""
+        if event.appointmentGroupEventStatus == "Reserved"
+          reservedText = "\n\n#{I18n.t('Reserved By You')}"
+        else if event.reservedUsers == ""
             reservedText = "\n\n#{I18n.t('Unreserved')}"
         else
           reservedText = "\n\n#{I18n.t('Reserved By: ')} #{event.reservedUsers}"


Modified in browser at pixie.strd6.com

Modified in browser at pixie.strd6.com

--- src/controllable.coffee
+++ src/controllable.coffee
@@ -11,7 +11,7 @@
     x: 15
     y: 30

-  # hold one of the movement keys
+  # hold one of the movement keys, t

   player.update()


user: online status needs defaults

user: online status needs defaults

+ user preference enum disabled for now

--- workers/social/lib/social/models/user.coffee
+++ workers/social/lib/social/models/user.coffee
@@ -108,9 +108,10 @@
         actual      :
           type      : String
           enum      : ['invalid status',['online','offline']]
+          default   : 'online'
         userPreference:
           type      : String
-          enum      : ['invalid status',['online','offline','away','busy']]
+          # enum      : ['invalid status',['online','offline','away','busy']]

     relationships       :
       ownAccount        :


<use /> now works immediate

<use /> now works immediate

--- src/document/use.coffee
+++ src/document/use.coffee
@@ -26,7 +26,7 @@

     visibilityChangeListener = ->
         if @file.isRendered and not @isRendered
-            @render()
+            @renderImmediate()

     propsChangeListener = (name) ->
         if name is 'component'
@@ -34,7 +34,7 @@

             if @isRendered
                 @revert()
-                signal.setImmediate @render
+                @renderImmediate()
         return

     queue = []
@@ -61,7 +61,8 @@
         @refName = @node.props.ref
         @usedComponent = null
         @isRendered = false
-        @render = utils.bindFunctionContext @render, @
+        @isRenderPending = false
+        @_renderImmediateCallback = utils.bindFunctionContext @_renderImmediateCallback, @

         @node.onVisibleChange visibilityChangeListener, @
         @node.onPropsChange propsChangeListener, @
@@ -70,6 +71,18 @@
         if @constructor is Use
             Object.preventExtensions @
         `//</development>`
+
+    renderImmediate: ->
+        unless @isRenderPending
+            @isRenderPending = true
+            signal.setImmediate @_renderImmediateCallback
+        return
+
+    _renderImmediateCallback: ->
+        @isRenderPending = false
+        unless @isRendered
+            @render()
+        return

     render: (file) ->
         assert.instanceOf file, File if file?


Update auth.coffee, warning not warn

Update auth.coffee, warning not warn

--- src/scripts/auth.coffee
+++ src/scripts/auth.coffee
@@ -31,7 +31,7 @@
 module.exports = (robot) ->

   unless process.env.HUBOT_AUTH_ADMIN?
-    robot.logger.warn 'The HUBOT_AUTH_ADMIN environment variable not set'
+    robot.logger.warning 'The HUBOT_AUTH_ADMIN environment variable not set'

   admins = (process.env.HUBOT_AUTH_ADMIN or []).split ','


fixing manual flying issues to impossible locations

--- src/scripts/game.coffee
+++ src/scripts/game.coffee
@@ -1,6 +1,6 @@
 require './message_bus'
 _       = require 'lodash'
-{ Alert, Plane, Airport, Loyalty, Player} = require '../data'
+{ Alert, Plane, Airport, Loyalty, Player, Route } = require '../data'

 instance = null

@@ -32,7 +32,9 @@
   scheduleFlight: (startAirportCode, endAirportCode) ->
     # @todo only send our own planes
     plane = _.first (Plane.at startAirportCode)
-    plane.location = "#{startAirportCode}->#{endAirportCode}"
+    routeKey = "#{startAirportCode}->#{endAirportCode}"
+    return unless Route.find(key: routeKey)
+    plane.location = routeKey
     MessageBus.publish 'dataChange'

   landPlane: (plane) ->


Basic template generation functionality is working

--- src/scripts/yara.coffee
+++ src/scripts/yara.coffee
@@ -5,7 +5,7 @@
 #   None
 #
 # Configuration:
-#   None
+#   None…
 #
 # Commands:
 #   hubot yara - Generates default rule template
@@ -16,6 +16,37 @@

 module.exports = (robot) ->
   robot.respond /yara/i, (msg) ->
+    # Default Values
+    yara_rule_name = "rule_name"
+    yara_rule_category = "category"
+    yara_meta_author = "Hubot"
+    yara_meta_date = "2013-01-01"
+    yara_meta_description = "Default Rule Template"
+    yara_strings_list = ['foo', 'bar', 'baz']
+
     # If there's strings generate rule with strings

-    # If there aren't then just generate a template
+    # Generate Strings Section
+    # yara_conditions = 0
+    # yara_strings_parsed = ""
+    #
+    # for yara_string in yara_strings_list
+    #   yara_strings_parsed += "    string#{yara_conditions} '#{yara_string}'\n"
+    #   yara_conditions++
+
+    new_rule = """
+    rule #{yara_rule_name} : #{yara_rule_category}
+    {
+      meta:
+        author = '#{yara_meta_author}'
+        date = '#{yara_meta_date}'
+        description = '#{yara_meta_description}'
+      strings:
+        $string0 = "foo"
+        $string1 = "bar"
+        $string2 = "baz" wide
+    condition:
+        3 of them
+    }
+    """
+    msg.send new_rule


Improve spec description

Improve spec description

--- spec/app/text-mate-grammar-spec.coffee
+++ spec/app/text-mate-grammar-spec.coffee
@@ -76,11 +76,14 @@
         expect(token[1].value).toBe " "
         expect(token[2].value).toBe "Quicksort"

-    describe "something", ->
-      fit "works", ->
+    describe "when the line matches a rule with nested capture groups and lookahead capture groups beyond the scope of the overall match", ->
+      fit "creates distinct tokens for nested captures and does not return tokens beyond the scope of the overall capture", ->
         {tokens} = grammar.getLineTokens("  destroy: ->")
+
+        for token in tokens
+          console.log token.value, token.scopes.join(' ')
+
         expect(tokens.length).toBe 5
-

    describe "when the line matches a begin/end pattern that contains sub-patterns", ->
      it "returns tokens within the begin/end scope based on the sub-patterns", ->


ListView

ListView

- After succesful row move, don't install click handler.

--- src/elements/ListView/tools/ListViewRowMoveTool.coffee
+++ src/elements/ListView/tools/ListViewRowMoveTool.coffee
@@ -63,6 +63,9 @@

 		source_node = @lV.getListViewRow(@info.cell.row_i)
 		target_node = @lV.getListViewRow(@target.row_i)
+
+		globalDrag.noClickKill = true
+
 		if source_node.moveRow
 			source_node.moveRow(@lV, target_node, @target.after)
 		else


Fix for workaround for users type parsing

--- src/hubot/talker.coffee
+++ src/hubot/talker.coffee
@@ -72,10 +72,10 @@
     @socket.addListener 'data', (data) ->
       console.log data

-      if data.indexOf('{"type":"users"') == 0
+      if data.indexOf('"type":"users"') > 0
+        message = {"type": "none"}
+      else
         message = JSON.parse(data)
-      else
-        message = {"type": "none"}

       if message.type == "connected"
         console.log "Succesfully connected, listing users:"


fix add dataset

fix add dataset

--- app/assets/javascripts/admin/admin.coffee
+++ app/assets/javascripts/admin/admin.coffee
@@ -1,7 +1,7 @@
 DatasetListView             = require("../dashboard/views/dataset/dataset_list_view")
 PaginationView              = require("./views/pagination_view")
 DatasetCollection           = require("./models/dataset/dataset_collection")
-DatasetUploadView           = require("./views/dataset/dataset_upload_view")
+DatasetAddView              = require("./views/dataset/dataset_add_view")
 UserListView                = require("./views/user/user_list_view")
 UserCollection              = require("./models/user/user_collection")
 TeamListView                = require("./views/team/team_list_view")
@@ -37,5 +37,5 @@
   StatisticView
   WorkloadListView
   WorkloadCollection
-  DatasetUploadView
+  DatasetAddView
 }


remove useless return

remove useless return

--- app/assets/javascripts/archives.js.coffee
+++ app/assets/javascripts/archives.js.coffee
@@ -2,5 +2,4 @@
   setTimeout ( ->
     $.get "archives/#{id}", (data) ->
       $("#button-#{id}").html(data)
-      return
   ), 5000


24h format resolves #30

24h format resolves #30

--- app/assets/javascripts/bookings.js.coffee
+++ app/assets/javascripts/bookings.js.coffee
@@ -23,6 +23,7 @@
 		defaultView: 'agendaWeek'
 		firstDay: 1
 		scrollTime: '10:00:00'
+		axisFormat: 'HH:mm'

 setFormValues = (activeRadio) ->
 	fest = $(activeRadio).data 'fest'


call on page load

call on page load

--- app/assets/javascripts/projects.js.coffee
+++ app/assets/javascripts/projects.js.coffee
@@ -27,7 +27,8 @@
 $(document).foundation('reveal', {animation_speed: 100})

 $ ->
-  $('span[class$=-repo]').parent().mouseover ->
-    $(this).width($(this).find('span').width() + 20) if $(this).find('span').width() > 200
-  $('span[class$=-repo]').parent().mouseout ->
-    $(this).css('width', '') if $(this).width() > 220+  $(document).on 'ready page:load', ->
+    $('span[class$=-repo]').parent().mouseover ->
+      $(this).width($(this).find('span').width() + 20) if $(this).find('span').width() > 200
+    $('span[class$=-repo]').parent().mouseout ->
+      $(this).css('width', '') if $(this).width() > 220


don't save during warning

don't save during warning

--- src/app/bucket-list/bucket-list.coffee
+++ src/app/bucket-list/bucket-list.coffee
@@ -13,6 +13,10 @@
         $scope.status = $scope.round.getStatus()

     $scope.saveContribution = (contribution) ->
+      # if we're gonna have a bad time
+      if $scope.status == 'warning'
+        # gtfo
+        return
       contribution.save(ContributionService).then ->
         $scope.loadContributorDetails()


enhance: display all versions for no preference

--- app/components/project-preferences.coffee
+++ app/components/project-preferences.coffee
@@ -29,7 +29,7 @@
           else if currentDevice is ENUMS.DEVICE_TYPE.TABLET_REQUIRED
             that.set "availableDevices", versions.devices.filterBy("platform", 0).filterBy("is_tablet",true)
           else
-            that.set "availableDevices", versions.devices.filterBy("platform", 0).filterBy("is_tablet",true)
+            that.set "availableDevices", versions.devices.filterBy("platform", 0)
         else if platform is ENUMS.PLATFORM.IOS
           versions = that.set "versions", data
           if currentDevice is ENUMS.DEVICE_TYPE.PHONE_REQUIRED
@@ -37,7 +37,7 @@
           else if currentDevice is ENUMS.DEVICE_TYPE.TABLET_REQUIRED
             that.set "availableDevices", versions.devices.filterBy("platform", 1).filterBy("is_tablet",true)
           else
-            that.set "availableDevices", versions.devices.filterBy("platform", 1).filterBy("is_tablet",true)
+            that.set "availableDevices", versions.devices.filterBy("platform", 1)
         else
           versions = that.set "versions", data
           if currentDevice is ENUMS.DEVICE_TYPE.PHONE_REQUIRED
@@ -45,7 +45,7 @@
           else if currentDevice is ENUMS.DEVICE_TYPE.TABLET_REQUIRED
             that.set "availableDevices", versions.devices.filterBy("platform", 1).filterBy("is_tablet",true)
           else
-            that.set "availableDevices", versions.devices.filterBy("platform", 1).filterBy("is_tablet",true)
+            that.set "availableDevices", versions.devices.filterBy("platform", 1)
       .catch (error) ->
         that.get("notify").error "failed"
         if Ember.isEmpty error?.errors


:art: Make editor-linter::_lock better looking

--- lib/editor-linter.coffee
+++ lib/editor-linter.coffee
@@ -64,8 +64,10 @@
   # This method sets or gets the lock status of given type
   _lock: (wasTriggeredOnChange, value) ->
     key = wasTriggeredOnChange ? 'inProgressFly' : 'inProgress'
-    return @[key] if typeof value is 'undefined'
-    @[key] = value
+    if typeof value is 'undefined'
+      @[key]
+    else
+      @[key] = value

   # Checks the responses for any kind-of errors
   @validateResults: (results) ->


Add option to disable reload notification

--- lib/flex-tool-bar.coffee
+++ lib/flex-tool-bar.coffee
@@ -20,9 +20,15 @@
     reloadToolBarWhenEditConfigFile:
       type: 'boolean'
       default: true
+    reloadToolBarNotification:
+      type: 'boolean'
+      default: true
     useBrowserPlusWhenItIsActive:
       type: 'boolean'
       default: false
+
+  reloadToolBarNotification: ->
+    atom.config.get 'flex-tool-bar.reloadToolBarNotification'

   activate: ->
     require('atom-package-deps').install('flex-tool-bar')
@@ -124,7 +130,7 @@
     if atom.config.get('flex-tool-bar.reloadToolBarWhenEditConfigFile')
       watcher = chokidar.watch @configFilePath
         .on 'change', =>
-          @reloadToolbar(true)
+          @reloadToolbar(@reloadToolBarNotification())
       @watcherList.push watcher

   registerProjectWatch: ->
@@ -132,7 +138,7 @@
       @watchList.push @projectToolbarConfigPath
       watcher = chokidar.watch @projectToolbarConfigPath
         .on 'change', (event, filename) =>
-          @reloadToolbar(true)
+          @reloadToolbar(@reloadToolBarNotification())
       @watcherList.push watcher

   switchProject: ->


fix csv generation to ignore object functions

--- app/controllers/interactive/graphs.coffee
+++ app/controllers/interactive/graphs.coffee
@@ -172,10 +172,11 @@
   createCSVHeader: (datum, prefix='') =>
     header = new String
     for key, value of datum
-      if typeof(value) is 'object'
-        header = header + @createCSVHeader value, "#{key}_"
-      else
-        header = header + "," + prefix + key
+      unless typeof(value) is 'function'
+        if typeof(value) is 'object'
+          header = header + @createCSVHeader value, "#{key}_"
+        else
+          header = header + "," + prefix + key
     return header

   createCSVBody: (data) =>
@@ -186,10 +187,11 @@
   createCSVLine: (datum) =>
     line = new String
     for key, value of datum
-      if typeof(value) is 'object'
-        line = line + @createCSVLine value
-      else
-        line = line + "," + value
+      unless typeof(value) is 'function'
+        if typeof(value) is 'object'
+          line = line + @createCSVLine value
+        else
+          line = line + "," + value
     return line

   # Helper functions


unobserving configuration on destroy

unobserving configuration on destroy

--- lib/linter-jshint.coffee
+++ lib/linter-jshint.coffee
@@ -26,4 +26,7 @@
     atom.config.observe 'linter-jshint.jshintExecutablePath', =>
       @executablePath = atom.config.get 'linter-jshint.jshintExecutablePath'

+  destroy: ->
+    atom.config.unobserve 'linter-jshint.jshintExecutablePath'
+
 module.exports = LinterJshint


KDModalView: standalone @ changed to this

--- src/components/modals/modalview.coffee
+++ src/components/modals/modalview.coffee
@@ -210,7 +210,7 @@
       uber()

     @overlay?.destroy()
-    @emit 'KDModalViewDestroyed', @
+    @emit 'KDModalViewDestroyed', this

   ### STACK HELPERS ###


Remove .bin from DownloadDataset.  Turns out it was unnecessary after all.

--- src/ext/components/frame-output.coffee
+++ src/ext/components/frame-output.coffee
@@ -50,7 +50,7 @@
     _.insertAndExecuteCell 'cs', "predict frame: #{stringify _frame.frame_id.name}"

   download = ->
-    window.open "/3/DownloadDataset.bin?frame_id=#{encodeURIComponent _frame.frame_id.name}", '_blank'
+    window.open "/3/DownloadDataset?frame_id=#{encodeURIComponent _frame.frame_id.name}", '_blank'

   exportFrame = ->
     _.insertAndExecuteCell 'cs', "exportFrame #{stringify _frame.frame_id.name}"


Display trees vs deviance in model outputs for DL, GBM, DRF.

--- src/ext/components/model-output.coffee
+++ src/ext/components/model-output.coffee
@@ -344,7 +344,7 @@

       if table = _.inspect 'output - Scoring History', _model
         if table.schema['validation_MSE']
-          renderPlot 'Scoring History', no, _.plot (g) ->
+          renderPlot 'Scoring History - MSE', no, _.plot (g) ->
             g(
               g.path(
                 g.position 'epochs', 'training_MSE'
@@ -365,7 +365,7 @@
               g.from table
             )
         else
-          renderPlot 'Scoring History', no, _.plot (g) ->
+          renderPlot 'Scoring History - MSE', no, _.plot (g) ->
             g(
               g.path(
                 g.position 'epochs', 'training_MSE'
@@ -377,6 +377,42 @@
               )
               g.from table
             )
+
+        if table.schema['training_deviance']
+          if table.schema['validation_deviance']
+            renderPlot 'Scoring History - Deviance', no, _.plot (g) ->
+              g(
+                g.path(
+                  g.position 'number_of_trees', 'training_deviance'
+                  g.strokeColor g.value '#1f77b4'
+                )
+                g.path(
+                  g.position 'number_of_trees', 'validation_deviance'
+                  g.strokeColor g.value '#ff7f0e'
+                )
+                g.point(
+                  g.position 'number_of_trees', 'training_deviance'
+                  g.strokeColor g.value '#1f77b4'
+                )
+                g.point(
+                  g.position 'number_of_trees', 'validation_deviance'
+                  g.strokeColor g.value '#ff7f0e'
+                )
+                g.from table
+              )
+          else
+            renderPlot 'Scoring History - Deviance', no, _.plot (g) ->
+              g(
+                g.path(
+                  g.position 'number_of_trees', 'training_deviance'
+                  g.strokeColor g.value '#1f77b4'
+                )
+                g.point(
+                  g.position 'number_of_trees', 'training_deviance'
+                  g.strokeColor g.value '#1f77b4'
+                )
+                g.from table
+              )

       if output = _model.output
         if output.model_category is 'Multinomial'
@@ -390,7 +426,7 @@
     when 'gbm', 'drf'
       if table = _.inspect 'output - Scoring History', _model
         if table.schema['validation_MSE']
-          renderPlot 'Scoring History', no, _.plot (g) ->
+          renderPlot 'Scoring History - MSE', no, _.plot (g) ->
             g(
               g.path(
                 g.position 'number_of_trees', 'training_MSE'
@@ -411,7 +447,7 @@
               g.from table
             )
         else
-          renderPlot 'Scoring History', no, _.plot (g) ->
+          renderPlot 'Scoring History - MSE', no, _.plot (g) ->
             g(
               g.path(
                 g.position 'number_of_trees', 'training_MSE'
@@ -423,6 +459,42 @@
               )
               g.from table
             )
+
+        if table.schema['training_deviance']
+          if table.schema['validation_deviance']
+            renderPlot 'Scoring History - MSE', no, _.plot (g) ->
+              g(
+                g.path(
+                  g.position 'number_of_trees', 'training_deviance'
+                  g.strokeColor g.value '#1f77b4'
+                )
+                g.path(
+                  g.position 'number_of_trees', 'validation_deviance'
+                  g.strokeColor g.value '#ff7f0e'
+                )
+                g.point(
+                  g.position 'number_of_trees', 'training_deviance'
+                  g.strokeColor g.value '#1f77b4'
+                )
+                g.point(
+                  g.position 'number_of_trees', 'validation_deviance'
+                  g.strokeColor g.value '#ff7f0e'
+                )
+                g.from table
+              )
+          else
+            renderPlot 'Scoring History - MSE', no, _.plot (g) ->
+              g(
+                g.path(
+                  g.position 'number_of_trees', 'training_deviance'
+                  g.strokeColor g.value '#1f77b4'
+                )
+                g.point(
+                  g.position 'number_of_trees', 'training_deviance'
+                  g.strokeColor g.value '#1f77b4'
+                )
+                g.from table
+              )

       if table = _.inspect 'output - training_metrics - Metrics for Thresholds', _model
         plotter = _.plot (g) ->


PUBDEV-2118: Add plotting of Gains/Lift tables to Flow.

--- src/ext/components/model-output.coffee
+++ src/ext/components/model-output.coffee
@@ -572,6 +572,46 @@
           if confusionMatrix = output.cross_validation_metrics?.cm?.table
             renderMultinomialConfusionMatrix 'Cross Validation Metrics - Confusion Matrix', confusionMatrix

+  if table = _.inspect 'output - training_metrics - Gains/Lift Table', _model
+    renderPlot 'Training Metrics - Gains/Lift Table', no, _.plot (g) ->
+      g(
+        g.path(
+          g.position 'cumulative_data_fraction', 'cumulative_lift'
+          g.strokeColor g.value 'green'
+        )
+        g.path(
+          g.position 'cumulative_data_fraction', 'cumulative_capture_rate'
+          g.strokeColor g.value 'black'
+        )
+        g.from table
+      )
+  if table = _.inspect 'output - validation_metrics - Gains/Lift Table', _model
+    renderPlot 'Validation Metrics - Gains/Lift Table', no, _.plot (g) ->
+      g(
+        g.path(
+          g.position 'cumulative_data_fraction', 'cumulative_lift'
+          g.strokeColor g.value 'green'
+        )
+        g.path(
+          g.position 'cumulative_data_fraction', 'cumulative_capture_rate'
+          g.strokeColor g.value 'black'
+        )
+        g.from table
+      )
+  if table = _.inspect 'output - cross_validation_metrics - Gains/Lift Table', _model
+    renderPlot 'Cross Validation Metrics - Gains/Lift Table', no, _.plot (g) ->
+      g(
+        g.path(
+          g.position 'cumulative_data_fraction', 'cumulative_lift'
+          g.strokeColor g.value 'green'
+        )
+        g.path(
+          g.position 'cumulative_data_fraction', 'cumulative_capture_rate'
+          g.strokeColor g.value 'black'
+        )
+        g.from table
+      )
+
   for tableName in _.ls _model when tableName isnt 'parameters'

     # Skip CM tables for multinomial models


Fix automatic application of country coupons (#6048)

* Fix automatic application of coupons

* Document brazil edge case

--- app/views/core/SubscribeModal.coco.coffee
+++ app/views/core/SubscribeModal.coco.coffee
@@ -40,6 +40,14 @@
     else
       @products = new Products()
       data = {}
+
+      # Attempt to get the coupon associated with the user's country.
+      # If coupon doesn't exist nothing is returned.
+      @couponID ?= me?.get('country')
+      if @couponID is 'brazil'
+        # Edge case due to misconfigured brazil coupon in stripe that is immutable
+        @couponID = 'brazil-annual'
+
       if @couponID
         data.coupon = @couponID
       @supermodel.trackRequest @products.fetch {data}


May have fixed BufferedProcess related Slime integration error

--- lib/swank-starter.coffee
+++ lib/swank-starter.coffee
@@ -15,7 +15,13 @@
       return false
     command = @lisp
     args = ['--load', @swank_script]
-    @process = new BufferedProcess command:command, args:args, stdout:@stdout_callback, exit:@exit_callback
+    @process = new BufferedProcess({
+      command: command,
+      args: args,
+      stdout: @stdout_callback,
+      stderr: @stderr_callback,
+      exit: @exit_callback
+    })
     console.log "Started a swank server"
     return true

@@ -35,6 +41,9 @@
   stdout_callback: (output) ->
     #console.log output

+  stderr_callback: (output) ->
+    #console.log output
+
   exit_callback: (code) ->
     console.log "Lisp process exited: #{code}"


sync user custom styles

sync user custom styles

--- lib/sync-settings.coffee
+++ lib/sync-settings.coffee
@@ -30,6 +30,8 @@
         content: JSON.stringify(@getPackages(), null, '\t')
       "keymap.cson":
         content: @fileContent atom.keymap.getUserKeymapPath()
+      "styles.less":
+        content: @fileContent atom.themes.getUserStylesheetPath()

     @createClient().gists.edit
       id: atom.config.get 'sync-settings.gistId'
@@ -64,6 +66,9 @@
       console.debug "keymap.cson = ", res.files['keymap.cson']?.content
       fs.writeFileSync(atom.keymap.getUserKeymapPath(), res.files['keymap.cson'].content) if keymap

+      styles = res.files['styles.less']?.content
+      console.debug "styles.less = ", res.files['styles.less']?.content
+      fs.writeFileSync(atom.themes.getUserStylesheetPath(), res.files['styles.less'].content) if styles

   createClient: ->
     token = atom.config.get 'sync-settings.personalAccessToken'


minimum value for global bar

minimum value for global bar

--- lib/util/progress.coffee
+++ lib/util/progress.coffee
@@ -58,7 +58,6 @@
   consumeStatusBar: (bar) ->
     @statusBar = bar

-
   create: (p = {progress: 0}) ->
     @activate()
     p.emitter = new Emitter
@@ -108,7 +107,7 @@
   onDidUpdateProgress: (f) -> @emitter.on 'did-update-progress', f

   # UI elements:
-  progressView: (p) ->
+  progressView: (p, {min} = {}) ->
     span = document.createElement 'span'
     prog = document.createElement 'progress'
     prog.classList.add 'ink'
@@ -116,7 +115,7 @@
     span.appendChild prog

     updateView = (prg) =>
-      if prg.progress?
+      if prg.progress? and not (min? and prg.progress < min)
         prog.setAttribute 'value', prg.progress
       else
         prog.removeAttribute 'value'
@@ -196,12 +195,10 @@
     @onDidUpdateStack =>
       span.removeChild span.firstChild
       # find the first determinate progress bar
-      global = @stack.find (p) => p.progress?
       # if there is none, use the first one in the stack
-      global = @stack[0] unless global?
-      # display an empty progress bar if the stack is empty
-      global = @create() unless global?
-      span.appendChild @progressView global
-      global.emitter.emit 'did-update-progress'
+      if (global = (@stack.find (p) => p.progress?) ? @stack[0])?
+        span.appendChild @progressView global, min: 0.01
+      else
+        span.appendChild @progressView @create()

     span


drawDotsOptionOnSeries

drawDotsOptionOnSeries

--- lib/utils/options.coffee
+++ lib/utils/options.coffee
@@ -50,6 +50,7 @@
           if s.type is 'column'
             delete s.thickness
             delete s.lineMode
+            delete s.drawDots
           else if not /^\d+px$/.test(s.thickness)
             s.thickness = '1px'


Simplification

Simplification

--- sync.coffee
+++ sync.coffee
@@ -1,7 +1,6 @@
 util = require 'util'
 _ = require 'underscore'
 Backbone = require 'backbone'
-inflection = require 'inflection'

 AjaxCursor = require './lib/ajax_cursor'
 Schema = require 'backbone-orm/lib/schema'


reset button working

reset button working

--- platform/src/app.coffee
+++ platform/src/app.coffee
@@ -128,25 +128,33 @@
     currentFrame = 0
     currentModel = currentModel.atVersion(0)

+    # TODO: move these handlers to MVC events
+    $("#timeSlider").slider "option",
+      value: 0
+      max: 0
+
     automaticallyUpdatingModel = true
     editors.modelEditor.setValue(JSON.stringify(currentModel.data, null, MODEL_FORMATTING_INDENTATION))
     # The new contect will be selected by default
     editors.modelEditor.selection.clearSelection()
     automaticallyUpdatingModel = false

+    # Execute again
+    executeCode()
+
   $("#timeSlider").on "slide", ->
     currentFrame = $(this).slider("value")
-    modelAtCurrentFrame = currentModel.atVersion(currentFrame)
-
+
+    # If done immediately, will block slider movement, so we postpone it
     GE.doLater ->
       automaticallyUpdatingModel = true
-      editors.modelEditor.setValue(JSON.stringify(modelAtCurrentFrame.data, null, MODEL_FORMATTING_INDENTATION))
+      editors.modelEditor.setValue(JSON.stringify(currentModel.atVersion(currentFrame).data, null, MODEL_FORMATTING_INDENTATION))
       # The new contect will be selected by default
       editors.modelEditor.selection.clearSelection()
       automaticallyUpdatingModel = false

       # Execute again
-      executeCode(modelAtCurrentFrame)
+      executeCode()

 setupEditor = (id) ->
   editor = ace.edit(id)
@@ -203,11 +211,12 @@
     showMessage(MessageType.Info, "Game updated")
     callback(null)

-# Runs the currently loaded code with the provided model (by default is the current model)
+# Runs the currently loaded code on the current frame
 # Returns a new model
-executeCode = (model = currentModel) ->
-  [result, patches] = GE.runStep(model, currentLoadedAssets, currentActions, currentLayout)
-  return model.applyPatches(patches)
+executeCode = ->
+  modelAtFrame = currentModel.atVersion(currentFrame)
+  [result, patches] = GE.runStep(modelAtFrame, currentLoadedAssets, currentActions, currentLayout)
+  return modelAtFrame.applyPatches(patches)

 notifyCodeChange = ->
   if automaticallyUpdatingModel then return false


Cleanup from the system tracked properties refactoring.

--- app/lib/world/world.coffee
+++ app/lib/world/world.coffee
@@ -349,7 +349,6 @@
     [w.totalFrames, w.maxTotalFrames, w.frameRate, w.dt, w.scriptNotes, w.victory] = [o.totalFrames, o.maxTotalFrames, o.frameRate, o.dt, o.scriptNotes ? [], o.victory]
     w[prop] = val for prop, val of o.trackedProperties

-    [w.showCoordinates, w.showGrid, w.showPaths, w.indieSprites] = [o.showCoordinates, o.showGrid, o.showPaths, o.indieSprites]
     perf.t1 = now()
     w.thangs = (Thang.deserialize(thang, w, classMap) for thang in o.thangs)
     w.setThang thang for thang in w.thangs


sending all events to particles

sending all events to particles

--- src/timed_events.coffee
+++ src/timed_events.coffee
@@ -30,5 +30,5 @@
   @param {Function} fn Code to execute after n frames has passed
   ###
   every: (n, fn) ->
-
+    for event
       fn()


handle private messages on irc

handle private messages on irc

--- src/scripts/hubot-simple-logger.coffee
+++ src/scripts/hubot-simple-logger.coffee
@@ -148,7 +148,9 @@
         reply: robot.Response.prototype.reply

     robot.Response.prototype.send = (strings...) ->
-        log_response @message.room, strings...
+
+        if not @message.room == null
+            log_response @message.room, strings...
         response_orig.send.call @,strings...

     robot.Response.prototype.reply = (strings...) ->


keep the query string on rewrite of url

keep the query string on rewrite of url

--- src/scripts/modules/media/media.coffee
+++ src/scripts/modules/media/media.coffee
@@ -73,9 +73,10 @@
       components = linksHelper.getCurrentPathComponents()
       components.version = "@#{components.version}" if components.version
       title = linksHelper.cleanUrl(@model.get('title'))
+      qs = components.rawquery

       if title isnt components.title
-        router.navigate("contents/#{components.uuid}#{components.version}/#{title}", {replace: true})
+        router.navigate("contents/#{components.uuid}#{components.version}/#{title}#{qs}", {replace: true})

     trackAnalytics: () ->
       # Track loading using the media's own analytics ID, if specified


keep the twitter image square                     [finishes #16138693]

--- public/javascripts/people.coffee
+++ public/javascripts/people.coffee
@@ -28,7 +28,7 @@
       $form.find('.bio textarea').text (i, t) -> t or data.description

       unless $form.find('.image_url input').val()
-        image_url = data.profile_image_url.replace '_normal.', '.'
+        image_url = data.profile_image_url.replace '_normal.', '_bigger.'
         $form.find('.image_url')
           .find('img.avatar').attr('src', image_url).end()
           .find('input').val image_url


Explicitly test that weather cancel stops upkeep

--- test/battle_spec.coffee
+++ test/battle_spec.coffee
@@ -1,6 +1,7 @@
 {Battle, BattleController, Pokemon, Weather} = require('../').server
 {Factory} = require('./factory')
 should = require 'should'
+require './helpers'

 describe 'Battle', ->
   beforeEach ->
@@ -138,3 +139,11 @@

       @battle.delay(@p1, @battle.getMove('Tackle').priority)
       queue[1].pokemon.should.eql @p1
+
+  describe "#weatherUpkeep", ->
+    it "does not damage Pokemon if a weather-cancel ability is on the field", ->
+      @battle.setWeather(Weather.HAIL)
+      @sandbox.stub(@battle, 'hasWeatherCancelAbilityOnField', -> true)
+      @battle.endTurn()
+      @p1.currentHP.should.not.be.lessThan @p1.stat('hp')
+      @p2.currentHP.should.not.be.lessThan @p2.stat('hp')


fixed syntax errors from when Taeyoung was added

--- maps/contributors.coffee
+++ maps/contributors.coffee
@@ -288,8 +288,6 @@
   }
   ,
   {
-  ,
-  {
     name: 'Benedict Singleton'
     location: 'London'
     links: ['[benedictsingleton.com](http://www.benedictsingleton.com/)', '[@benedict](https://twitter.com/benedict)', '[are.na/benedict-singleton](https://www.are.na/benedict-singleton--2)']
@@ -339,15 +337,16 @@
     azone_funds: []
   }
   ,
-    {
-      name: 'Dan Taeyoung'
-      location: 'London'
-      links: ['[dantaeyoung.com](http://dantaeyoung.com/)', '[@dantaeyoung](https://twitter.com/dantaeyoung)']
-      bio: 'Dan Taeyoung operates at the intersection of architecture, technology, community, and believes that radical architecture is achieved through applied anthropology, activist real estate, and critical engineering. He is a Co-founder of Prime Produce, an intentional guild for social good in New York City, and Adjunct Assistant Professor at Columbia University’s Graduate School of Architecture, Planning and Preservation, where he teaches on representational strategies and experimental design tools.'
-      azone_username: ''
-      azone_reviews: []
-      azone_funds: []
-    }
+  {
+    name: 'Dan Taeyoung'
+    location: 'New York'
+    links: ['[dantaeyoung.com](http://dantaeyoung.com/)', '[@dantaeyoung](https://twitter.com/dantaeyoung)']
+    bio: 'Dan Taeyoung operates at the intersection of architecture, technology, community, and believes that radical architecture is achieved through applied anthropology, activist real estate, and critical engineering. He is a Co-founder of Prime Produce, an intentional guild for social good in New York City, and Adjunct Assistant Professor at Columbia University’s Graduate School of Architecture, Planning and Preservation, where he teaches on representational strategies and experimental design tools.'
+    azone_username: ''
+    azone_reviews: []
+    azone_funds: []
+  }
+  ,
   {
     name: 'Ben Vickers'
     location: 'Nomadic'


Delete SampleCodeSpec.coffee

Delete SampleCodeSpec.coffee

--- test/unit/sample/SampleCodeSpec.coffee
+++ test/unit/sample/SampleCodeSpec.coffee
@@ -1,13 +0,0 @@
-describe "SampleCode", ->
-
-  beforeEach ()->
-    injector().inject (@SampleCode)=>
-
-  afterEach ()->
-
-  it "should exist", ->
-    expect(@SampleCode).to.exist
-
-  it 'should return a valid text', ->
-    subject = new @SampleCode()
-    expect(subject.test()).to.equal("The test worked")


Replace some test setup with subject/given helpers

--- test/units/processing/core.spec.coffee
+++ test/units/processing/core.spec.coffee
@@ -19,32 +19,34 @@
         expect(-> core.readFiles()).toThrow()

     describe 'when called with paths that exists', ->
-      beforeEach ->
-        @readFiles = core.readFiles [
+      given 'expectedResult', ->
+        {}.tap (o) ->
+          coffeePath = fixture 'processing/file.coffee'
+          jsPath = fixture 'processing/file.js'
+          o[coffeePath] = "# this is file.coffee\n"
+          o[jsPath] = "// this is file.js\n"
+
+      subject 'promise', ->
+        core.readFiles [
           fixture 'processing/file.coffee'
           fixture 'processing/file.js'
         ]
-        @expectedResult = {}
-        coffeePath = fixture 'processing/file.coffee'
-        jsPath = fixture 'processing/file.js'
-        @expectedResult[coffeePath] = "# this is file.coffee\n"
-        @expectedResult[jsPath] = "// this is file.js\n"

       it 'should return a promise', ->
-        expect(@readFiles).toBePromise()
+        expect(@promise).toBePromise()

-      promise(-> @readFiles)
+      promise()
       .should.beFulfilled()
       .should.returns 'a hash with the paths content', -> @expectedResult

     describe 'when called with paths that does not exists', ->
-      beforeEach ->
-        @readFiles = core.readFiles [
+      subject 'promise', ->
+        core.readFiles [
           fixture 'processing/foo.coffee'
           fixture 'processing/bar.js'
         ]

-      promise(-> @readFiles).should.beRejected()
+      promise().should.beRejected()

   describe 'writeFiles', ->
     it 'should exists', ->
@@ -57,18 +59,19 @@
         expect(-> core.writeFiles null).toThrow()

     describe 'when called with a files buffer', ->
-      beforeEach ->
-        @files = {}
-        @files[tmp 'processing/foo.coffee'] = 'foo.coffee'
-        @files[tmp 'processing/foo.js'] = 'foo.js'
-        @writeFiles = core.writeFiles @files
+      given 'files', ->
+        {}.tap (o) ->
+          o[tmp 'processing/foo.coffee'] = 'foo.coffee'
+          o[tmp 'processing/foo.js'] = 'foo.js'
+
+      subject 'promise', -> core.writeFiles @files

       afterEach -> clearTmp 'processing'

       it 'should return a promise', ->
-        expect(@writeFiles).toBePromise()
+        expect(@promise).toBePromise()

-      promise(-> @writeFiles)
+      promise()
       .should.beFulfilled()
       .should 'have written the files on the file system', ->
         expect(tmp 'processing/foo.coffee').toContain('foo.coffee')


Modified in browser at pixie.strd6.com

Modified in browser at pixie.strd6.com

--- test/game_object.coffee
+++ test/game_object.coffee
@@ -47,9 +47,7 @@

   o.create()

-  GameObject
-    create: 'ok(true, "created event is fired on create")'
-  .create()
+  o.create()

 test "[event] update", 1, ->
   gameObject = GameObject()


Test: Add missing test for 510 evs

Test: Add missing test for 510 evs

--- test/server_spec.coffee
+++ test/server_spec.coffee
@@ -598,6 +598,11 @@
     it "returns non-empty if a pokemon has an ev above 255", ->
       server = new BattleServer()
       pokemon = Factory("Magikarp", evs: { hp: 256 })
+      server.validateTeam([ pokemon ]).should.not.be.empty
+
+    it "returns non-empty if a pokemon has an ev total above 510", ->
+      server = new BattleServer()
+      pokemon = Factory("Magikarp", evs: { hp: 255, defense: 255, speed: 255 })
       server.validateTeam([ pokemon ]).should.not.be.empty

     it "returns non-empty if a pokemon has bogus evs", ->


Don't send empty durations

Don't send empty durations

--- SingularityUI/app/models/Request.coffee
+++ SingularityUI/app/models/Request.coffee
@@ -58,14 +58,17 @@
             type: 'POST'

     pause: (killTasks, duration) =>
+        data =
+            user:      app.getUsername()
+            killTasks: killTasks
+        duration = @_parseDuration(duration)
+        if duration
+            data[durationMillis] = duration
         $.ajax
             url:         "#{ @url() }/pause"
             type:        'POST'
             contentType: 'application/json'
-            data:         JSON.stringify
-                user:      app.getUsername()
-                killTasks: killTasks
-                durationMillis: @_parseDuration(duration)
+            data: JSON.stringify data

     run: (confirmedOrPromptData) ->
         options =
@@ -83,13 +86,16 @@
         $.ajax options

     scale: (confirmedOrPromptData) =>
+        data =
+            instances: confirmedOrPromptData.instances
+        duration = @_parseDuration(confirmedOrPromptData.duration)
+        if duration
+            data[durationMillis] = duration
         $.ajax
           url: "#{ @url() }/scale?user=#{ app.getUsername() }"
           type: "PUT"
           contentType: 'application/json'
-          data: JSON.stringify
-              instances: confirmedOrPromptData.instances
-              durationMillis: @_parseDuration(confirmedOrPromptData.duration)
+          data: JSON.stringify data

     makeScalePermanent: (callback) =>
         $.ajax(
@@ -110,13 +116,16 @@
         ).then callback

     bounce: (incremental, duration) =>
+        data =
+            incremental: incremental
+        duration = @_parseDuration(duration)
+        if duration
+            data[durationMillis] = duration
         $.ajax
             type: "POST"
             url:  "#{ @url() }/bounce?user=#{ app.getUsername() }"
             contentType: 'application/json'
-            data: JSON.stringify
-              durationMillis: @_parseDuration(duration)
-              incremental: incremental
+            data: JSON.stringify data

     exitCooldown: =>
         $.ajax


check for no data in beforeClose

check for no data in beforeClose

because we added the beforeClose method, we need to test if the data is
empty there since it’s called after the callback

--- SingularityUI/app/models/Request.coffee
+++ SingularityUI/app/models/Request.coffee
@@ -130,6 +130,8 @@
             ]

             beforeClose: =>
+                return if @data is false
+
                 fileName = @data.filename.trim()

                 if fileName.length is 0 and @data.autoTail is 'on'
@@ -149,7 +151,6 @@
                 $('#autoTail').prop 'checked', (localStorage.getItem('taskRunAutoTail') is 'on')

             callback: (data) =>
-                return if data is false
                 @data = data

     promptRemove: (callback) =>


Delete Enumeration.coffee

Delete Enumeration.coffee

--- Enumeration.coffee
+++ Enumeration.coffee
@@ -1,35 +0,0 @@
-#Registered enums
-enumNames=[]
-class Enumeration
-  #Static function that creates an enum object value. Uniqueness guarantied by object reference.
-  #This objects's unique own field is the Enumeration name. It's read only.
-  #string value shall be uppercase
-  @value:(value,enumName="Enumeration")->
-    prototype= id: -> @[enumName]
-    properties={}
-    properties[enumName]=
-      value:value
-      enumerable:true
-    Object.create prototype, properties
-
-  constructor:(enumName,enumValues) ->
-    #Check for uniqueness
-    if enumName in enumNames then throw "#{enumName} already exists!"
-    else enumNames.push enumName
-    #Lambda to write enum values
-    writeProperty = (property,key) => @[key or property]=Enumeration.value(property,enumName)
-    if enumValues instanceof Array then writeProperty val for val in enumValues
-    else writeProperty val,key for key,val of enumValues
-    #Define non-enumerable property
-    Object.defineProperty @, 'concise', {
-      #Returns a concise string representing the enumeration
-      value:-> "#{enumName}:[#{" "+val+" " for val in enumValues}]"
-    }
-    Object.defineProperty @, 'from', {
-      #Returns the enum instance that matches value
-      value: (lookupVal) -> (@[key] for key,val of enumValues when val is lookupVal)[0]
-    }
-    #Guaranties properties to be 'final', non writable
-    Object.freeze(this)
-
-#If you want to export the class, you'll need window.Enumeration=Enumeration or global.Enumeration=Enumeration


Fix error in testing.

Fix error in testing.

--- test.coffee
+++ test.coffee
@@ -1,3 +1,3 @@
-core = require('./core')
+core = require('./nointro')
 fs = require('fs')
 should = require('should')


Fixup 9e3ec14, explicit returns in extensions.

--- tests/js/core.mixin.coffee
+++ tests/js/core.mixin.coffee
@@ -31,6 +31,7 @@
       @dependencies =
         valueA: 'foo'
         valueB: 'bar'
+      return

   QUnit.test '.createMixin', (assert) ->
     result = hlf.createMixin @mixins, @mixinName, @mixin
@@ -89,6 +90,7 @@
         attr: (name) -> "some-ns-#{name}"
         $el: $ '<div>'
       hlf.applyMixin @instance, [], 'data'
+      return

   QUnit.test '#data', (assert) ->
     @instance.$el.data 'some-ns-some-attr', 'some-value'
@@ -104,5 +106,6 @@
     for own key, value of pairs
       assert.strictEqual @instance.$el.data("some-ns-#{key}"), value,
         'It namespaces keys and sets values in pairs object via $.fn.data.'
+    return

   yes


+comments and formatting tweaks

+comments and formatting tweaks

--- plugin/browserify.coffee
+++ plugin/browserify.coffee
@@ -17,7 +17,7 @@
 path = Plugin.path

 # extend standard compiler class to make implementation easier.
-# it will make us process the *.browserify.js files, and, provide them
+# it will make us process the *.browserify.js files, and, provide the
 # *.browserify.options.json files as InputPath instances to get the content.
 # and it does the caching :)
 class BrowserifyPlugin extends MultiFileCachingCompiler
@@ -27,8 +27,10 @@
       compilerName: 'CosmosBrowserify'
       defaultCacheSize: 1024*1024*10 # TODO: what size??

+
   # this is how it knows which files we want to process, and which are referenced
   isRoot: (file) -> file.getExtension() is 'browserify.js'
+

   getCacheKey: (file) ->
     return [
@@ -38,8 +40,10 @@
       # TODO: modified time of npm-shrinkwrap.json file OR hash of contents
     ]

+
   compileResultSize: (compileResult) ->
     compileResult.source.length + compileResult.sourceMap.length
+

   addCompileResult: (file, compileResult) ->
     file.addJavaScript
@@ -48,15 +52,21 @@
       data: compileResult.source,
       sourceMap: compileResult.sourceMap

+
   getOptionInfo: (file, files) ->
+
     # generate path to options file from `file`, then get options InputFile
     packageName = file.getPackageName()
+
     # app file has no package, it's null, so, use empty string
     packageName ?= ''
+
     # replace 'js' with 'options.json'
     tail = file.getPathInPackage()[...-2] + 'options.json'
+
     # combine to form the weird path to the options file
     optionFileKey = "{#{packageName}}/#{tail}"
+
     # use it to get the InputFile representing the options file
     optionInputFile = files.get optionFileKey

@@ -66,10 +76,12 @@
       ref: if optionInputFile? then [optionFileKey] else []
       package: file.getFileOptions()

+
   #  1. returns '' for an app file, unless altPackageName exists
   #  2. returns 'packages/packageFolderName' for package files
-  #  3. when altPackageName exists and it's an app file, it becomes the packageFolderName
+  #  3. when altPackageName exists and it's an app file, it's used as the packageFolderName
   getRoot: (altPackageName) ->
+
     root = @getPackageName()
     if root?
       index = root.indexOf(':') + 1
@@ -81,6 +93,7 @@

     return root

+
   compileOneFile: (file, files) ->
     # bind a helper function to the file
     file.getRoot = @getRoot.bind file
@@ -114,7 +127,9 @@

     return

+
   applyTransforms: (browserify, browserifyOptions) ->
+
     # extract envify tranform's options so it isn't used in loop
     envifyOptions = browserifyOptions.transforms.envify
     delete browserifyOptions.transforms.envify
@@ -123,12 +138,14 @@
     for own transformName, transformOptions of browserifyOptions.transforms
       browserify.transform transformName, transformOptions

-    # run the envify transform
+    # run the envify transform now (so it's last)
     browserify.transform envify envifyOptions

     return

+
   getBundle: (browserify, file) ->
+
     # have browserify process the file and include all required modules.
     # we receive a readable stream as the result
     bundle = browserify.bundle()
@@ -136,32 +153,46 @@
     # set the readable stream's encoding so we read strings from it
     bundle.setEncoding('utf8')

-    # extract the source map content from the generated file to give to Meteor
-    # explicitly by piping bundle thru `exorcist`
+    # # extract the source map content from the generated file to give to Meteor
+    # # explicitly by piping bundle thru `exorcist`
+    # get path to file in OS style, resolve against CWD with app/package root, and file path
     mapFilePath = Plugin.convertToOSPath path.resolve file.getRoot(), file.getPathInPackage() + '.map'
+
+    # pipe thru exorcist transform with display path as the 'source map url'
     exorcisedBundle = bundle.pipe exorcist mapFilePath, file.getDisplayPath()
+
+    # store reference to original bundle to access it elsewhere
     exorcisedBundle.originalBundle = bundle
+
+    # store path to map file so we can delete it later
     exorcisedBundle.mapFilePath = mapFilePath

     return exorcisedBundle

+
   getCompileResult: (bundle) ->
+
     result = source: @getString bundle

     # read the generated source map from the file
     sourceMap = fs.readFileSync bundle.mapFilePath, encoding:'utf8'
+
     # delete source map file
     fs.unlinkSync bundle.mapFilePath
+
     # add source map to result
     result.sourceMap = sourceMap

     return result

+
   getBasedir: (file) ->
-    # get root folder for file, use npm-container when an app file.
+
+    # get app/package root folder for file, use npm-container when an app file.
     folderPath = file.getRoot('npm-container')
-    # convert to a path on the system, resolve it against CWD, use real folder name
+    # convert to OS style, resolve it against CWD, use real folder name
     Plugin.convertToOSPath path.resolve folderPath, '.npm/package'
+

   getBrowserifyOptions: (file, option) ->

@@ -197,7 +228,9 @@

     return userOptions

+
   getDebug: ->
+
     debug = true

     # check args used
@@ -209,13 +242,14 @@

     return debug

+
   getReadable: (file) ->

     # Browserify accepts a Readable stream as input, so, we'll use a PassThrough
     # stream to hold the Buffer
     readable = new stream.PassThrough()

-    # Meteor's CompileStep provides the file as a Buffer from step.read()
+    # Meteor's InputFile provides content as a Buffer or String
     # add the buffer into the stream and end the stream with one call to end()
     readable.end file.getContentsAsBuffer()


handler: group usage tests

handler: group usage tests

--- test/api/handler.coffee
+++ test/api/handler.coffee
@@ -4,19 +4,21 @@

 describe 'api handler', ->

-  it 'is an option', (next) ->
-    history = []
-    mecano
-    .call
-      handler: ->
-        history.push 'a'
-    .call
-      handler: (_, callback) ->
-        history.push 'b'
-        callback()
-    .call ->
-      history.should.eql ['a', 'b']
-    .then next
+  describe 'usage', ->
+
+    it 'is an option', (next) ->
+      history = []
+      mecano
+      .call
+        handler: ->
+          history.push 'a'
+      .call
+        handler: (_, callback) ->
+          history.push 'b'
+          callback()
+      .call ->
+        history.should.eql ['a', 'b']
+      .then next

   describe 'error', ->


Psssh tests

Psssh tests

--- test/config.test.coffee
+++ test/config.test.coffee
@@ -75,10 +75,10 @@
       .to.throw /HUBOT_MARKOV_STORAGE must be one of/

     it 'falls back to the default on a missing key', ->
-      expect(config({}).storageKind).to.equal('redis')
+      expect(config({}).storageKind).to.equal('memory')

     it 'falls back to the default on an empty key', ->
-      expect(config({HUBOT_MARKOV_STORAGE: ''}).storageKind).to.equal('redis')
+      expect(config({HUBOT_MARKOV_STORAGE: ''}).storageKind).to.equal('memory')

   describe 'string settings', ->
     it 'passes the setting through as-is', ->


Modified in browser at pixie.strd6.com

Modified in browser at pixie.strd6.com

--- test/flickerable.coffee
+++ test/flickerable.coffee
@@ -25,8 +25,8 @@
     alpha: 0.2

   5.times (n) ->
+    player.update()

-     p

   player.update()
   equals player.I.alpha, 0.2


adding elapsedTime

adding elapsedTime

--- test/game_object.coffee
+++ test/game_object.coffee
@@ -38,7 +38,8 @@

   gameObject.update()

-test "elapsedTime"
+test "elapsedTime", ->
+

 test "[event] destroy", 2, ->
   GameObject


remove trailing space

remove trailing space

--- test/testOptions.coffee
+++ test/testOptions.coffee
@@ -36,7 +36,7 @@
         done()

   it "should be able to override cookies option", (done) ->
-    options =
+    options =
       jar: false

     client = request.createClient(options)


Make run_mycha helper asynchronous

Make run_mycha helper asynchronous

--- test/test_helper.coffee
+++ test/test_helper.coffee
@@ -27,24 +27,24 @@
 # Runs the Mycha command-line tool
 # with tests in the given directory and
 # with the given arguments.
-global.run_mycha = ({ test_dir, args }) ->
+global.run_mycha = ({ test_dir, args, done }) ->
   cwd = path.join process.cwd(), 'test_data', test_dir
-  mycha_path = path.resolve __dirname, '../bin/mycha'
-  child.spawn mycha_path, args, cwd: cwd
+  mycha_path = path.resolve process.cwd(), 'bin/mycha'
+  mycha_process = child.spawn mycha_path, args, cwd: cwd
+  mycha_process.on 'close', done
+

 # Verifies that the tests in the given test directory pass.
 global.verify_success = (test_dir, done) ->
-  mycha_process = run_mycha test_dir: test_dir, args: ['run']
-  mycha_process.on 'close', (exit_code) =>
+  run_mycha test_dir: test_dir, args: ['run'], done: (exit_code) ->
     expect(exit_code).to.equal 0
     done()

 # Verifies that the tests in the given test directory fail.
 global.verify_failure = (test_dir, done) ->
-  mycha_process = run_mycha test_dir: test_dir, args: ['run']
-  mycha_process.on 'close', (exit_code) =>
+  run_mycha test_dir: test_dir, args: ['run'], done: (exit_code) ->
     expect(exit_code).to.equal 1
     done()


debug line

debug line

--- public/fav-client.coffee
+++ public/fav-client.coffee
@@ -19,8 +19,8 @@

 twapi = (url, callback) ->
   # for debug
-  # console.log JSON.parse localStorage[url] if localStorage[url]
-  # return callback JSON.parse localStorage[url] if localStorage[url]
+  console.log JSON.parse localStorage[url] if localStorage[url]
+  return callback JSON.parse localStorage[url] if localStorage[url]

   $.getJSON url, (json) ->
     console.log json


fix rewriter to never accept powers outside of allowed diapason

--- vondyck_rewriter.coffee
+++ vondyck_rewriter.coffee
@@ -214,7 +214,9 @@
         @block =>
             @line("//Non-trivial rewrites, when new element is #{newElement}")
             nodeConstructor=@_nodeClass(newElement)
-            @line("chain = new #{nodeConstructor}(power, chain);")
+            o = @_nodeOrder newElement
+            mo = @_lowestPower newElement
+            @line("chain = new #{nodeConstructor}((((power - #{mo})%#{o}+#{o})%#{o}+#{mo}), chain);")
             @generateRewriteBySuffixTree(newElement, @suffixTree, 'chain')

     generateRewriteBySuffixTree: ( newElement, suffixTree, chain)->
@@ -296,9 +298,9 @@

     for [suffix, rewrite] in ruleset.items()
         gSuffix = groupPowersVd(suffix)
-        gSuffix.reverse()
+        #gSuffix.reverse()
         gRewrite = groupPowersVd(rewrite)
-        gRewrite.reverse()
+        #gRewrite.reverse()
         if ignorePowers
             if gSuffix.length is 1 and gRewrite.length is 1 and gSuffix[0][0] is gRewrite[0][0]
                 continue
@@ -332,7 +334,9 @@
   g = new CodeGenerator(s)
   g.debug=false

-  appendRewriteOnce = eval g.generateAppendRewriteOnce()
+  rewriterCode = g.generateAppendRewriteOnce()
+  console.log rewriterCode
+  appendRewriteOnce = eval rewriterCode
   throw new Error("Rewriter failed to compile") unless appendRewriteOnce?

   appendRewrite = repeatRewrite appendRewriteOnce


Increase progress event timeout to prevent test failures

--- tests/write.spec.coffee
+++ tests/write.spec.coffee
@@ -74,7 +74,7 @@
 					progressSpy = m.sinon.spy()
 					emitter.on('progress', progressSpy)

-					# A tiny timeout is needed for the
+					# A timeout is needed for the
 					# progress event to be emitted.
 					setTimeout ->
 						m.chai.expect(progressSpy).to.have.been.called
@@ -90,7 +90,7 @@
 							transferred: Number
 						m.chai.expect(state.length).to.equal(26)
 						done()
-					, 1
+					, 500

 			describe 'given a stream with a length property', ->

@@ -109,4 +109,4 @@
 						state = progressSpy.firstCall.args[0]
 						m.chai.expect(state.length).to.equal(26)
 						done()
-					, 1
+					, 500


update chart label positions

update chart label positions

--- app/assets/javascripts/app/chart.coffee
+++ app/assets/javascripts/app/chart.coffee
@@ -109,7 +109,7 @@

             for segment, i in segments
               $label = $($(id).find('.highcharts-xaxis-labels span')[i])
-              $label.css('left', segment.position - (segment.width / 2) - ($label.width() / 2))
+              $label.css('left', segment.position - (segment.width / 2) - ($label.width() / 2) - 1)

       credits:
         enabled: false


Removed unused JS file

Removed unused JS file

--- app/assets/javascripts/errors.js.coffee
+++ app/assets/javascripts/errors.js.coffee
@@ -1,3 +0,0 @@
-# Place all the behaviors and hooks related to the matching controller here.
-# All this logic will automatically be available in application.js.
-# You can use CoffeeScript in this file: http://coffeescript.org/


Remove unsupported items from toolbar

Remove unsupported items from toolbar

--- app/assets/javascripts/papers.js.coffee
+++ app/assets/javascripts/papers.js.coffee
@@ -6,6 +6,15 @@
         removePlugins: 'floatingspace,resize'
         sharedSpaces:
           top: 'ckeditor-toolbar'
+        toolbarGroups: [
+          { name: 'styles' }
+          { name: 'basicstyles', groups: [ 'basicstyles', 'cleanup' ] }
+          { name: 'clipboard',   groups: [ 'clipboard', 'undo' ] }
+          { name: 'editing',     groups: [ 'find', 'selection', 'spellchecker' ] }
+          { name: 'paragraph',   groups: [ 'list', 'indent', 'blocks', 'align', 'bidi' ] }
+          { name: 'links' }
+          { name: 'tools' }
+        ]

   $('#save_button').on 'click', (e) ->
     e.preventDefault()


Prevent method calls on undefined

Prevent method calls on undefined

--- app/assets/javascripts/papers.js.coffee
+++ app/assets/javascripts/papers.js.coffee
@@ -7,9 +7,8 @@
       li.html $('#author-template').html()
       li.appendTo $('ul.authors')
     @fixArticleControls()
-    unless window.jasmine?
-      @instantiateEditables()
-      @togglePlaceholders()
+    @instantiateEditables()
+    @togglePlaceholders()

   authors: ->
     authorsArray = []
@@ -64,27 +63,27 @@

     if $('#abstract_editable').text().trim() == ''
       abstract_placeholder_text = "
#{$('#abstract_editable').attr('placeholder')}
"
-      CKEDITOR.instances.abstract_editable.setData abstract_placeholder_text
+      CKEDITOR.instances.abstract_editable?.setData abstract_placeholder_text

-      CKEDITOR.instances.abstract_editable.on 'focus', ->
-        if $.trim(CKEDITOR.instances.abstract_editable.getData()) == abstract_placeholder_text
-          CKEDITOR.instances.abstract_editable.setData ''
+      CKEDITOR.instances.abstract_editable?.on 'focus', ->
+        if $.trim(CKEDITOR.instances.abstract_editable?.getData()) == abstract_placeholder_text
+          CKEDITOR.instances.abstract_editable?.setData ''

-      CKEDITOR.instances.abstract_editable.on 'blur', ->
-        if $.trim(CKEDITOR.instances.abstract_editable.getData()) == ''
-          CKEDITOR.instances.abstract_editable.setData abstract_placeholder_text
+      CKEDITOR.instances.abstract_editable?.on 'blur', ->
+        if $.trim(CKEDITOR.instances.abstract_editable?.getData()) == ''
+          CKEDITOR.instances.abstract_editable?.setData abstract_placeholder_text

     if $('#body_editable').text().trim() == ''
       body_placeholder_text = "
#{$('#body_editable').attr('placeholder')}
"
-      CKEDITOR.instances.body_editable.setData body_placeholder_text
+      CKEDITOR.instances.body_editable?.setData body_placeholder_text

-      CKEDITOR.instances.body_editable.on 'focus', ->
-        if $.trim(CKEDITOR.instances.body_editable.getData()) == body_placeholder_text
-          CKEDITOR.instances.body_editable.setData ''
+      CKEDITOR.instances.body_editable?.on 'focus', ->
+        if $.trim(CKEDITOR.instances.body_editable?.getData()) == body_placeholder_text
+          CKEDITOR.instances.body_editable?.setData ''

-      CKEDITOR.instances.body_editable.on 'blur', ->
-        if $.trim(CKEDITOR.instances.body_editable.getData()) == ''
-          CKEDITOR.instances.body_editable.setData body_placeholder_text
+      CKEDITOR.instances.body_editable?.on 'blur', ->
+        if $.trim(CKEDITOR.instances.body_editable?.getData()) == ''
+          CKEDITOR.instances.body_editable?.setData body_placeholder_text

 $(document).ready ->


Update DataTables `aoColumnDefs` class names.

They were not updated to match the new class name conventions, so the
mark and recall columns were ending up searchable.

--- app/assets/javascripts/rounds.js.coffee
+++ app/assets/javascripts/rounds.js.coffee
@@ -4,7 +4,7 @@
     bInfo: false
     sDom: 't'
     aoColumnDefs: [
-      aTargets: ['recalled_header', 'adjudicator_header']
+      aTargets: ['recalled_col', 'adjudicator_col']
       bSearchable: false
     ]


Add ctrl-f,b bindings for expanding/collapsing dir

Make emacs bindings consistent with rest of app

--- keymaps/tree-view.cson
+++ keymaps/tree-view.cson
@@ -24,9 +24,11 @@
   'right': 'tree-view:expand-directory'
   'ctrl-]': 'tree-view:expand-directory'
   'l': 'tree-view:expand-directory'
+  'ctrl-f': 'tree-view:expand-directory'
   'left': 'tree-view:collapse-directory'
   'ctrl-[': 'tree-view:collapse-directory'
   'h': 'tree-view:collapse-directory'
+  'ctrl-b': 'tree-view:collapse-directory'
   'enter': 'tree-view:open-selected-entry'
   'ctrl-C': 'tree-view:copy-full-path'
   'm': 'tree-view:move'


Wrap long lines in /i18n views

Wrap long lines in /i18n views

--- app/views/i18n/I18NEditModelView.coffee
+++ app/views/i18n/I18NEditModelView.coffee
@@ -92,6 +92,7 @@
       session.setMode 'ace/mode/markdown'
       session.setNewLineMode = 'unix'
       session.setUseSoftTabs true
+      session.setUseWrapMode true
       editor.setOptions({ maxLines: Infinity })

   onEditorChange: (event, editor) =>


make sure to fetch counts

make sure to fetch counts

--- apps/fair/components/browse/view.coffee
+++ apps/fair/components/browse/view.coffee
@@ -16,6 +16,7 @@
       countsUrl: "#{ARTSY_URL}/api/v1/search/filtered/fair/#{@fair.get 'id'}/suggest"
       urlRoot: "#{@profile.id}/browse"
     @artworkParams = @filterArtworksView.params
+    @counts = @filterArtworksView.counts
     @boothsView = new BoothsView
       el: $ '.fair-page-content'
       fair: @fair
@@ -24,6 +25,7 @@
     @boothParams = @boothsView.params
     @boothParams.on 'change', @boothsSection
     @artworkParams.on 'change', @artworksSection
+    @counts.fetch()
     @highlightHome()

   boothsSection: =>


refactor, :lipstick:

refactor, :lipstick:

--- lib/atom-ternjs.coffee
+++ lib/atom-ternjs.coffee
@@ -12,6 +12,7 @@
   client: null
   documentationView: null
   currentProviderIdx: 0
+  activeTextEditor: null

   # autocomplete
   autocompletePlus = null
@@ -59,17 +60,16 @@
     @client.update(editor.getURI(), editor.getText())

   findDefinition: ->
-    editor = atom.workspace.getActiveTextEditor()
-    cursor = editor.getLastCursor()
+    cursor = @activeTextEditor.getLastCursor()
     position = cursor.getBufferPosition()
-    @client.definition(editor.getURI(),
+    @client.definition(@activeTextEditor.getURI(),
       line: position.row
       ch: position.column
-    editor.getText()).then (data) =>
+    @activeTextEditor.getText()).then (data) =>
       if data?.start
         # check if definition is in current active TextEditor
-        if atom.workspace.getActiveTextEditor().getPath().indexOf(data.file) > -1
-          buffer = editor.getBuffer()
+        if @activeTextEditor.getPath().indexOf(data.file) > -1
+          buffer = @activeTextEditor.getBuffer()
           cursor.setBufferPosition(buffer.positionForCharacterIndex(data.start))
           return
         # else open the file and set cursor position to definition
@@ -83,35 +83,30 @@

   registerEvents: ->
     @disposables.push atom.workspace.onDidOpen (e) =>
-      return unless e.item
-      return unless !e.item.mini
-      return unless e.item.getGrammar?
-      return unless e.item.getGrammar().name in @grammars
+      return unless e.item and @isValidEditor(e.item)
       @startServer()
     @disposables.push atom.workspace.onDidChangeActivePaneItem =>
       @setCurrentProvider()

-  isGrammarInGrammars: (editor) ->
-    grammar = editor.getGrammar().name
-    if grammar in @grammars
-      return true
-    else
-      return false
+  isValidEditor: (editor) ->
+    return false if editor.mini
+    return false if !editor.getGrammar
+    return false if editor.getGrammar().name not in @grammars
+    return true

   setCurrentProvider: ->
-    editor = atom.workspace.getActiveTextEditor()
-    return unless editor
+    @activeTextEditor = atom.workspace.getActiveTextEditor()
+    return unless @activeTextEditor
     for provider, idx in @providers
       provider.isActive = false
-      if provider.editor.id is editor.id
+      if provider.editor.id is @activeTextEditor.id
         @currentProviderIdx = idx
         provider.isActive = true
         break

   registerEditors: ->
     @editorSubscription = atom.workspace.observeTextEditors (editor) =>
-      return unless !editor.mini
-      return unless editor.getGrammar().name in @grammars
+      return unless @isValidEditor(editor)
       @registerEditor(editor)
       @setCurrentProvider()

@@ -132,8 +127,7 @@
     @disposables = []

   startServer: ->
-    return unless !@server?.process
-    return unless atom.project.getDirectories()[0]
+    return unless !@server?.process and atom.project.getDirectories()[0]
     @server = new TernServer()
     @server.start (port) =>
       if !@client
@@ -145,7 +139,7 @@

   registerCommands: ->
     atom.commands.add 'atom-text-editor', 'tern:definition': (event) =>
-        @findDefinition(atom.workspace.getActiveTextEditor())
+        @findDefinition()
     atom.commands.add 'atom-text-editor', 'tern:startCompletion': (event) =>
       @providers[@currentProviderIdx].callPreBuildSuggestions(true)
     atom.commands.add 'atom-text-editor', 'tern:stop': (event) =>


Suppress other language constructs being auto indented inside JSX templates.

--- lib/auto-indent.coffee
+++ lib/auto-indent.coffee
@@ -48,6 +48,8 @@
     @multipleCursorTrigger = 1
     @disposables = new CompositeDisposable()
     @eslintIndentOptions = @getIndentOptions()
+    @templateDepth = 0 # track depth of any embedded back-tick templates
+

     @disposables.add atom.commands.add 'atom-text-editor',
       'language-babel:auto-indent-jsx-on': (event) =>
@@ -165,6 +167,7 @@
     indent =  0
     isFirstTagOfBlock = true
     @JSXREGEXP.lastIndex = 0
+    @templateDepth = 0

     for row in [range.start.row..range.end.row]
       isFirstTokenOfLine = true
@@ -408,6 +411,7 @@
           # Javascript brace Start { or switch brace start { or paren ( or back-tick `start
           when BRACE_OPEN, SWITCH_BRACE_OPEN, PAREN_OPEN, TEMPLATE_START
             tokenOnThisLine = true
+            if token is TEMPLATE_START then @templateDepth++
             if isFirstTokenOfLine
               stackOfTokensStillOpen.push parentTokenIdx = stackOfTokensStillOpen.pop()
               if isFirstTagOfBlock and
@@ -477,6 +481,8 @@
               if parentTokenIdx >=0 then tokenStack[parentTokenIdx].termsThisTagIdx = idxOfToken
               idxOfToken++

+            if token is TEMPLATE_END then @templateDepth--
+
           # case, default statement of switch
           when SWITCH_CASE, SWITCH_DEFAULT
             tokenOnThisLine = true
@@ -553,10 +559,8 @@
         @indentRow({row: row, blockIndent: tokenStack[token.parentTokenIdx].firstCharIndentation, jsxIndent: 1, allowAdditionalIndents: true })
       when SWITCH_CASE, SWITCH_DEFAULT
         @indentRow({row: row, blockIndent: token.firstCharIndentation, jsxIndent: 1 })
-      when TEMPLATE_START
+      when TEMPLATE_START, TEMPLATE_END
         return; # don't touch templates
-      when TEMPLATE_END
-        @indentRow({row: row, blockIndent: token.firstCharIndentation, jsxIndent: 1 })

   # get the token at the given match position or return truthy false
   getToken: (bufferRow, match) ->
@@ -774,6 +778,7 @@
   # option contains row to indent and allowAdditionalIndents flag
   indentRow: (options) ->
     { row, allowAdditionalIndents, blockIndent, jsxIndent, jsxIndentProps } = options
+    if @templateDepth > 0 then return false # don't indent inside a template
     # calc overall indent
     if jsxIndent
       if @eslintIndentOptions.jsxIndent[0]


'Updating for version 0.12.6rc1'

'Updating for version 0.12.6rc1'

--- bokehjs/src/coffee/version.coffee
+++ bokehjs/src/coffee/version.coffee
@@ -1 +1 @@
-export version = '0.12.6dev7'
+export version = '0.12.6rc1'


'Updating for version 0.12.6dev3'

'Updating for version 0.12.6dev3'

--- bokehjs/src/coffee/version.coffee
+++ bokehjs/src/coffee/version.coffee
@@ -1 +1 @@
-export version = '0.12.6dev2'
+export version = '0.12.6dev3'


removed unnecessary return statements

removed unnecessary return statements

--- lib/script-view.coffee
+++ lib/script-view.coffee
@@ -198,9 +198,9 @@

   getCwd: ->
     if @options.cmd_cwd is null || @options.cmd_cwd == ''
-      return atom.project.getPath()
+      atom.project.getPath()
     else
-      return @options.cmd_cwd
+      @options.cmd_cwd

   stop: ->


Remove done TODO

Remove done TODO

--- lib/token/token.coffee
+++ lib/token/token.coffee
@@ -1,4 +1,3 @@
-# TODO: Persist token in a secure manner
 data = require('../data/data')

 TOKEN_KEY = 'token'


This isn't needed with gesposito's PR adding same line in bin/gatsby-serve

(which is where babel should be required as it's the entry point).

--- lib/utils/serve.coffee
+++ lib/utils/serve.coffee
@@ -1,5 +1,4 @@
 require('node-cjsx').transform()
-require("babel/register")
 Hapi = require 'hapi'
 Boom = require 'boom'
 React = require 'react'


Add tests for new client API functions

Add tests for new client API functions

--- tests/experiment_client_tests.coffee
+++ tests/experiment_client_tests.coffee
@@ -34,6 +34,10 @@
       workerId = Meteor.users.findOne(userId).workerId
       return Assignments.findOne({workerId, status: "assigned"})

+    setAssignmentPayment: (amount) ->
+      TurkServer.Assignment.currentAssignment().setPayment(amount);
+      return
+
     setAssignmentInstanceData: (arr) ->
       selector =
         workerId: Meteor.user().workerId
@@ -41,6 +45,10 @@

       unless Assignments.update(selector, $set: {instances: arr}) > 0
         throw new Meteor.Error(400, "Could not find assignment to update")
+      return
+
+    endAssignmentInstance: (returnToLobby) ->
+      TurkServer.Instance.currentInstance().teardown(returnToLobby)
       return

 if Meteor.isClient
@@ -94,6 +102,13 @@
       treatment = TurkServer.treatment()
       return true if treatment.treatments.length
     ), verify, fail, 2000
+
+  Tinytest.addAsync "experiment - client - current payment variable", (test, next) ->
+    amount = 0.42
+
+    Meteor.call "setAssignmentPayment", amount, (err, res) ->
+      test.equal TurkServer.currentPayment(), amount
+      next()

   Tinytest.addAsync "experiment - client - assignment metadata and local time vars", (test, next) ->
     asstData = null
@@ -180,6 +195,21 @@

       next()

+  Tinytest.addAsync "experiment - client - instance ended state", (test, next) ->
+    # In experiment. not ended
+    test.isTrue TurkServer.inExperiment()
+    test.isFalse TurkServer.instanceEnded()
+
+    Meteor.call "endAssignmentInstance", false, (err, res) ->
+      test.isTrue TurkServer.inExperiment()
+      test.isTrue TurkServer.instanceEnded()
+
+      next()
+
+  ###
+    Next test edits instance fields, so client APIs may break state
+  ###
+
   Tinytest.addAsync "experiment - client - selects correct instance of multiple", (test, next) ->
     fields = [
       {


add a subsription to the speakers so they can easily access their proposals at My Speaker Page


Add fuzzy_sort local function to StorageFreak


Draw visual indent marker by hand so it's more stylish.

--- app/views/play/level/tome/SpellView.coffee
+++ app/views/play/level/tome/SpellView.coffee
@@ -298,19 +298,26 @@
             level = Math.floor(xstart / 4)
             indent = startOfRow(row + 1)
             color = colors[level % colors.length]
+            bw = 3
+            to = markerLayer.$getTop(range.start.row, config)
             t = markerLayer.$getTop(range.start.row + 1, config)
             h = config.lineHeight * (range.end.row - range.start.row)
             l = markerLayer.$padding + xstart * config.characterWidth
             # w = (data.i - data.b) * config.characterWidth
             w = 4 * config.characterWidth
+            fw = config.characterWidth * ( @aceSession.getScreenLastRowColumn(range.start.row) - xstart )
+
+            html.push [
+              '

' ].join ''

             html.push [
               '

' ].join ''
-
-            markerLayer.drawTextMarker html, new Range(range.start.row,xstart, range.start.row, 1000), 'rob', config, "border: 3px solid rgba(#{color}, 0.4); position: absolute"

   fillACE: ->
     @ace.setValue @spell.source


Fix undefined deckHp

Fix undefined deckHp

--- views/battle-env.coffee
+++ views/battle-env.coffee
@@ -197,7 +197,7 @@
             enemy: body.api_enemy_info.api_deck_name
             dropShipId: if body.api_get_ship? then body.api_get_ship.api_ship_id else -1
             deckShipId: if combined then _decks[0].api_ship.concat(_decks[1].api_ship) else Object.clone _decks[deckId].api_ship
-            deckHp: if combined then _sortieHp.concat(_combinedHp)
+            deckHp: if combined then _sortieHp.concat(_combinedHp) else _sortieHp
             enemyShipId: Object.clone enemyShipId
             enemyFormation: enemyFormation
             enemyHp: Object.clone _enemyHp


iScrubber bug fix.

iScrubber bug fix.

--- client/js/jquery.iscrubber.coffee
+++ client/js/jquery.iscrubber.coffee
@@ -75,7 +75,7 @@
       switch activeDirection
         when DIRECTION.HORIZONTAL
           index = Math.ceil((e.pageX - $this.offset().left) / horizontalTrigger)
-        when activeDirection
+        when DIRECTION.VERTICAL
           index = Math.ceil((e.pageY - $this.offset().top) / verticalTrigger)

       index = Math.min(Math.max(index, 1), numberOfChildren)


use underscore for msg for signup

use underscore for msg for signup

--- client/views/signUp/signUp.coffee
+++ client/views/signUp/signUp.coffee
@@ -138,8 +138,8 @@
             return

           Session.set('entryError', undefined)
-          msg='Your account has been created. An activation email has been sent to your email address '+ email + '
 NOTE: if you do not see your activation email, look in your spam/junk mailbox.'
-
+          msg=_s.sprintf("Your account has been created. An activation email has been sent to your email address %s
 NOTE: if you do not see your activation email, look in your spam/junk mailbox. You can also try to resend activation email", email)
+
           if app && app.client
              app.client.alert(msg,'success')
           else


print dots

print dots

--- scripts/import_filesystem.coffee
+++ scripts/import_filesystem.coffee
@@ -34,7 +34,9 @@
   ]).spread (parent, files) ->
     Q.all(files.map((basename) ->
       fullPath = path.resolve root, directory, basename
-      sem.push -> getImageInfo(fullPath)
+      sem.push -> getImageInfo(fullPath).then (imageInfo) ->
+        process.stdout.write '.'
+        imageInfo
     )).then (imageInfos) ->
       albumPath = path.join(parent.path, slugify(title))


pass additional props onto error notification

--- coach/src/concept-coach/base.cjsx
+++ coach/src/concept-coach/base.cjsx
@@ -192,7 +192,7 @@
       loading: not (isLoggedIn or isLoaded)

     <div className='concept-coach openstax-wrapper'>
-      <ErrorNotification container={@} />
+      <ErrorNotification container={@} course={course} close={@props.close} />

       <SpyMode.Wrapper>
         <Navigation key='user-status' close={@props.close} course={course}/>


Express: Don't throw forked pages as an error...

--- server/express/lib/server.coffee
+++ server/express/lib/server.coffee
@@ -361,7 +361,7 @@
           console.log("Error: #{e}")
         )
         resp.on('end', ->
-          actionCB(JSON.parse(responsedata))
+          actionCB(null, JSON.parse(responsedata))
         )
       ).on('error', (e) ->
         console.log "Error: #{e}"


Safely clear out already saved picks

Safely clear out already saved picks

--- src/Lidsys/Application/Controller/assets/lidsys/football-models.js.coffee
+++ src/Lidsys/Application/Controller/assets/lidsys/football-models.js.coffee
@@ -229,7 +229,11 @@
         @$timeout.cancel(@queueTimeout) if @queueTimeout
         @queueTimeout = @$timeout(
             () =>
-                data = {fantasy_picks: @queuedPickChanges}
+                picksArray = for game_id, team_id of @queuedPickChanges
+                    game_id: game_id
+                    team_id: team_id
+                data = {fantasy_picks: {}}
+                this.preparePick(data, picksArray) while (picksArray.length > 0)
                 @$http.post("/api/v1.0/football/fantasy-picks/", data)
                     .success((response) =>
                         console.log(response)
@@ -238,6 +242,10 @@
             true
         )

+    preparePick: (data, picksArray) ->
+        pick = picksArray.pop()
+        data.fantasy_picks[pick.game_id] = pick.team_id
+


getting rid of useless stuff

getting rid of useless stuff

--- main/src/module.coffee
+++ main/src/module.coffee
@@ -16,7 +16,7 @@
     prettyHrtime process.hrtime start

   processInfos = ->
-    processInfosList = [
+    [
       pid         : process.pid,
       arch        : process.arch,
       platform    : process.platform,
@@ -25,10 +25,9 @@
       execPath    : process.execPath,
       execArgv    : process.execArgv
     ]
-    processInfosList

   osInfos = ->
-    osInfosList = [
+    [
       platform : os.platform(),
       arch     : os.arch(),
       release  : os.release(),
@@ -37,7 +36,6 @@
       totalmem : os.totalmem(),
       freemem  : os.freemem()
     ]
-    osInfosList

   globalStatus = (statuses) ->
     for status in statuses


Cleanup BoundedContext spec

Cleanup BoundedContext spec

--- spec/bounded_context_spec.coffee
+++ spec/bounded_context_spec.coffee
@@ -8,12 +8,9 @@

   class MongoDbEventStoreMock
       initialize: sinon.stub().yields null
-  class EventricComponent
-    initialize: sandbox.stub().yields false
-    registerClass: sandbox.stub()
-    registerServiceHandler: sandbox.stub()
   class CommandServiceMock
     commandAggregate: sandbox.stub()
+  class DomainEventServiceMock
   class AggregateRepositoryMock
     registerClass: sandbox.stub()

@@ -23,8 +20,8 @@
       warnOnUnregistered: false

     eventricMock = sandbox.stub()
-    eventricMock.returns EventricComponent
     eventricMock.withArgs('CommandService').returns CommandServiceMock
+    eventricMock.withArgs('DomainEventService').returns DomainEventServiceMock
     eventricMock.withArgs('AggregateRepository').returns AggregateRepositoryMock
     mockery.registerMock 'eventric', eventricMock
     mockery.registerMock 'eventric-store-mongodb', MongoDbEventStoreMock


Replace RootView.getActiveEditor() with getActiveView()

--- spec/bracket-matcher-spec.coffee
+++ spec/bracket-matcher-spec.coffee
@@ -8,7 +8,7 @@
     rootView.open('sample.js')
     window.loadPackage('bracket-matcher')
     rootView.attachToDom()
-    editor = rootView.getActiveEditor()
+    editor = rootView.getActiveView()
     editSession = editor.activeEditSession
     buffer = editSession.buffer


:lipstick: Minimap bookmark

:lipstick: Minimap bookmark


Use _state property instead of state

Use _state property instead of state

Avoid deprecation warnings in Ember v1.7.0

--- packages/emberella/lib/views/list_view.coffee
+++ packages/emberella/lib/views/list_view.coffee
@@ -756,7 +756,7 @@
   ###
   _recalculateWidth: ->
     return if get(@, 'isDestroyed') or get(@, 'isDestroying')
-    @set('_width', if @get('state') is 'inDOM' then +@$().width() else window.innerWidth)
+    @set('_width', if get(@, '_state') is 'inDOM' then +@$().width() else window.innerWidth)

   ###
     @private
@@ -768,7 +768,7 @@
   ###
   _recalculateHeight: ->
     return if get(@, 'isDestroyed') or get(@, 'isDestroying')
-    @set('_height', if @get('state') is 'inDOM' then +@$().height() else window.innerHeight)
+    @set('_height', if get(@, '_state') is 'inDOM' then +@$().height() else window.innerHeight)

   ###
     @private
@@ -779,7 +779,7 @@
   ###
   _contentDidChange: Ember.observer ->
     @_super()
-    @_rerenderList() if get(@, 'state') is 'inDOM'
+    @_rerenderList() if get(@, '_state') is 'inDOM'
   , 'content'

   ###


export createCredential function

export createCredential function

--- workers/social/testhelper/models/computeproviders/credentialhelper.coffee
+++ workers/social/testhelper/models/computeproviders/credentialhelper.coffee
@@ -53,6 +53,7 @@

 module.exports = {
+  createCredential
   generateMetaData
   withConvertedUserAndCredential
 }


Add the rest of pet items to utils

Add the rest of pet items to utils