Revert "do not use 'since' GET parameter"

This reverts commit 26f60fe9c5c6d9396269ec608d0b885cf59dd99c.

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/rremizov/github-notifier.git/'


IDEView: Added Split Vertically, Split Horizontally and Undo Split items to plus menu.

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/andrewjcasal/koding.git/'


:bug: Fix #24

:bug: Fix #24

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/jerone/flex-toolbar.git/'


minor cs style tweak for consistency

minor cs style tweak for consistency

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/crdx/crdx.org.git/'


Enable ads on HTTPS

Enable ads on HTTPS

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/lonelyplanet/rizzo.git/'


#162 copy pipeline class from branch 162

error: pathspec 'app/assets/javascripts/libs/pipeline.coffee' did not match any file(s) known to git

--- app/assets/javascripts/libs/pipeline.coffee
+++ app/assets/javascripts/libs/pipeline.coffee
@@ -0,0 +1,73 @@
+### define
+jquery : $
+underscore : _
+###
+
+
+class Pipeline
+
+  # Collects a list of asynchronous actions
+  # and executes them in order
+
+
+  constructor : (@options = {}) ->
+
+    @actions     = []
+    @deferred    = null
+    @retryCount  = 0
+
+    _.defaults @options,
+      maxRetry : 3
+
+
+  enqueueAction : ( action ) ->
+    # action : function that returns a
+    #          $.Deferred object
+
+    @actions.push( action )
+
+
+  enqueueActions : ( actionList ) ->
+
+    @actions = @actions.concat( actionList )
+
+
+  execute : ( firstArgument ) ->
+
+    unless @deferred?
+      @deferred = deferred = new $.Deferred()
+      @executeNext(firstArgument)
+
+    return deferred
+
+
+  executeNext : ( previousResponse ) ->
+
+    currentAction = @actions.shift()
+
+    if currentAction?
+
+      currentAction(previousResponse)
+        .done (response) =>
+
+          @retryCount = 0
+          @executeNext(response)
+
+        .fail (response) =>
+
+          @retryCount++
+
+          if @retryCount >= @options.maxRetry
+            deferred  = @deferred
+            @deferred = null
+            deferred.reject( response )
+
+          else
+            @actions.unshift( currentAction )
+            @executeNext()
+
+    else
+
+      deferred  = @deferred
+      @deferred = null
+      deferred.resolve( previousResponse )


fix(search-filter): use fa icons, ng-if instead of ng-show

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/keboola/kbc-ui-doctool-recipes.git/'


Search results model

Search results model

error: pathspec 'src/scripts/models/search-results.coffee' did not match any file(s) known to git

--- src/scripts/models/search-results.coffee
+++ src/scripts/models/search-results.coffee
@@ -0,0 +1,19 @@
+define (require) ->
+  Backbone = require('backbone')
+
+  SEARCH_URI = "#{location.protocol}//#{location.hostname}:6543/search"
+
+  return class SearchResults extends Backbone.Model
+    url: () -> "#{SEARCH_URI}#{@query}"
+
+    defaults:
+      query:
+        limits: []
+        sort: []
+      results:
+        items: []
+        total: 0
+
+    initialize: (options = {}) ->
+      @query = options.query or ''
+      @fetch()


originalSync did not return. It does now.

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/richterm/backbone-socket.io.git/'


Remove stray utils

Remove stray utils

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/VilkkuV/codecombat.git/'


added watch dir option

added watch dir option

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/genericdave/noprob.git/'


Update static/vendors/morrisjs/lib/morris.grid.coffee

Signed-off-by: Bernard Ojengwa <fccb4cc00c1ba7e51bf5c2b5f77130b9fe8d917e@gmail.com>

error: pathspec 'static/vendors/morrisjs/lib/morris.grid.coffee' did not match any file(s) known to git

--- static/vendors/morrisjs/lib/morris.grid.coffee
+++ static/vendors/morrisjs/lib/morris.grid.coffee
@@ -0,0 +1,499 @@
+class Morris.Grid extends Morris.EventEmitter
+  # A generic pair of axes for line/area/bar charts.
+  #
+  # Draws grid lines and axis labels.
+  #
+  constructor: (options) ->
+    # find the container to draw the graph in
+    if typeof options.element is 'string'
+      @el = $ document.getElementById(options.element)
+    else
+      @el = $ options.element
+    if not @el? or @el.length == 0
+      throw new Error("Graph container element not found")
+
+    if @el.css('position') == 'static'
+      @el.css('position', 'relative')
+
+    @options = $.extend {}, @gridDefaults, (@defaults || {}), options
+
+    # backwards compatibility for units -> postUnits
+    if typeof @options.units is 'string'
+      @options.postUnits = options.units
+
+    # the raphael drawing instance
+    @raphael = new Raphael(@el[0])
+
+    # some redraw stuff
+    @elementWidth = null
+    @elementHeight = null
+    @dirty = false
+
+    # range selection
+    @selectFrom = null
+
+    # more stuff
+    @init() if @init
+
+    # load data
+    @setData @options.data
+
+    # hover
+    @el.bind 'mousemove', (evt) =>
+      offset = @el.offset()
+      x = evt.pageX - offset.left
+      if @selectFrom
+        left = @data[@hitTest(Math.min(x, @selectFrom))]._x
+        right = @data[@hitTest(Math.max(x, @selectFrom))]._x
+        width = right - left
+        @selectionRect.attr({ x: left, width: width })
+      else
+        @fire 'hovermove', x, evt.pageY - offset.top
+
+    @el.bind 'mouseleave', (evt) =>
+      if @selectFrom
+        @selectionRect.hide()
+        @selectFrom = null
+      @fire 'hoverout'
+
+    @el.bind 'touchstart touchmove touchend', (evt) =>
+      touch = evt.originalEvent.touches[0] or evt.originalEvent.changedTouches[0]
+      offset = @el.offset()
+      @fire 'hovermove', touch.pageX - offset.left, touch.pageY - offset.top
+
+    @el.bind 'click', (evt) =>
+      offset = @el.offset()
+      @fire 'gridclick', evt.pageX - offset.left, evt.pageY - offset.top
+
+    if @options.rangeSelect
+      @selectionRect = @raphael.rect(0, 0, 0, @el.innerHeight())
+        .attr({ fill: @options.rangeSelectColor, stroke: false })
+        .toBack()
+        .hide()
+
+      @el.bind 'mousedown', (evt) =>
+        offset = @el.offset()
+        @startRange evt.pageX - offset.left
+
+      @el.bind 'mouseup', (evt) =>
+        offset = @el.offset()
+        @endRange evt.pageX - offset.left
+        @fire 'hovermove', evt.pageX - offset.left, evt.pageY - offset.top
+
+    if @options.resize
+      $(window).bind 'resize', (evt) =>
+        if @timeoutId?
+          window.clearTimeout @timeoutId
+        @timeoutId = window.setTimeout @resizeHandler, 100
+
+    # Disable tap highlight on iOS.
+    @el.css('-webkit-tap-highlight-color', 'rgba(0,0,0,0)')
+
+    @postInit() if @postInit
+
+  # Default options
+  #
+  gridDefaults:
+    dateFormat: null
+    axes: true
+    grid: true
+    gridLineColor: '#aaa'
+    gridStrokeWidth: 0.5
+    gridTextColor: '#888'
+    gridTextSize: 12
+    gridTextFamily: 'sans-serif'
+    gridTextWeight: 'normal'
+    hideHover: false
+    yLabelFormat: null
+    xLabelAngle: 0
+    numLines: 5
+    padding: 25
+    parseTime: true
+    postUnits: ''
+    preUnits: ''
+    ymax: 'auto'
+    ymin: 'auto 0'
+    goals: []
+    goalStrokeWidth: 1.0
+    goalLineColors: [
+      '#666633'
+      '#999966'
+      '#cc6666'
+      '#663333'
+    ]
+    events: []
+    eventStrokeWidth: 1.0
+    eventLineColors: [
+      '#005a04'
+      '#ccffbb'
+      '#3a5f0b'
+      '#005502'
+    ]
+    rangeSelect: null
+    rangeSelectColor: '#eef'
+    resize: false
+
+  # Update the data series and redraw the chart.
+  #
+  setData: (data, redraw = true) ->
+    @options.data = data
+
+    if !data? or data.length == 0
+      @data = []
+      @raphael.clear()
+      @hover.hide() if @hover?
+      return
+
+    ymax = if @cumulative then 0 else null
+    ymin = if @cumulative then 0 else null
+
+    if @options.goals.length > 0
+      minGoal = Math.min @options.goals...
+      maxGoal = Math.max @options.goals...
+      ymin = if ymin? then Math.min(ymin, minGoal) else minGoal
+      ymax = if ymax? then Math.max(ymax, maxGoal) else maxGoal
+
+    @data = for row, index in data
+      ret = {src: row}
+
+      ret.label = row[@options.xkey]
+      if @options.parseTime
+        ret.x = Morris.parseDate(ret.label)
+        if @options.dateFormat
+          ret.label = @options.dateFormat ret.x
+        else if typeof ret.label is 'number'
+          ret.label = new Date(ret.label).toString()
+      else
+        ret.x = index
+        if @options.xLabelFormat
+          ret.label = @options.xLabelFormat ret
+      total = 0
+      ret.y = for ykey, idx in @options.ykeys
+        yval = row[ykey]
+        yval = parseFloat(yval) if typeof yval is 'string'
+        yval = null if yval? and typeof yval isnt 'number'
+        if yval?
+          if @cumulative
+            total += yval
+          else
+            if ymax?
+              ymax = Math.max(yval, ymax)
+              ymin = Math.min(yval, ymin)
+            else
+              ymax = ymin = yval
+        if @cumulative and total?
+          ymax = Math.max(total, ymax)
+          ymin = Math.min(total, ymin)
+        yval
+      ret
+
+    if @options.parseTime
+      @data = @data.sort (a, b) -> (a.x > b.x) - (b.x > a.x)
+
+    # calculate horizontal range of the graph
+    @xmin = @data[0].x
+    @xmax = @data[@data.length - 1].x
+
+    @events = []
+    if @options.events.length > 0
+      if @options.parseTime
+        @events = (Morris.parseDate(e) for e in @options.events)
+      else
+        @events = @options.events
+      @xmax = Math.max(@xmax, Math.max(@events...))
+      @xmin = Math.min(@xmin, Math.min(@events...))
+
+    if @xmin is @xmax
+      @xmin -= 1
+      @xmax += 1
+
+    @ymin = @yboundary('min', ymin)
+    @ymax = @yboundary('max', ymax)
+
+    if @ymin is @ymax
+      @ymin -= 1 if ymin
+      @ymax += 1
+
+    if @options.axes in [true, 'both', 'y'] or @options.grid is true
+      if (@options.ymax == @gridDefaults.ymax and
+          @options.ymin == @gridDefaults.ymin)
+        # calculate 'magic' grid placement
+        @grid = @autoGridLines(@ymin, @ymax, @options.numLines)
+        @ymin = Math.min(@ymin, @grid[0])
+        @ymax = Math.max(@ymax, @grid[@grid.length - 1])
+      else
+        step = (@ymax - @ymin) / (@options.numLines - 1)
+        @grid = (y for y in [@ymin..@ymax] by step)
+
+    @dirty = true
+    @redraw() if redraw
+
+  yboundary: (boundaryType, currentValue) ->
+    boundaryOption = @options["y#{boundaryType}"]
+    if typeof boundaryOption is 'string'
+      if boundaryOption[0..3] is 'auto'
+        if boundaryOption.length > 5
+          suggestedValue = parseInt(boundaryOption[5..], 10)
+          return suggestedValue unless currentValue?
+          Math[boundaryType](currentValue, suggestedValue)
+        else
+          if currentValue? then currentValue else 0
+      else
+        parseInt(boundaryOption, 10)
+    else
+      boundaryOption
+
+  autoGridLines: (ymin, ymax, nlines) ->
+    span = ymax - ymin
+    ymag = Math.floor(Math.log(span) / Math.log(10))
+    unit = Math.pow(10, ymag)
+
+    # calculate initial grid min and max values
+    gmin = Math.floor(ymin / unit) * unit
+    gmax = Math.ceil(ymax / unit) * unit
+    step = (gmax - gmin) / (nlines - 1)
+    if unit == 1 and step > 1 and Math.ceil(step) != step
+      step = Math.ceil(step)
+      gmax = gmin + step * (nlines - 1)
+
+    # ensure zero is plotted where the range includes zero
+    if gmin < 0 and gmax > 0
+      gmin = Math.floor(ymin / step) * step
+      gmax = Math.ceil(ymax / step) * step
+
+    # special case for decimal numbers
+    if step < 1
+      smag = Math.floor(Math.log(step) / Math.log(10))
+      grid = for y in [gmin..gmax] by step
+        parseFloat(y.toFixed(1 - smag))
+    else
+      grid = (y for y in [gmin..gmax] by step)
+    grid
+
+  _calc: ->
+    w = @el.width()
+    h = @el.height()
+
+    if @elementWidth != w or @elementHeight != h or @dirty
+      @elementWidth = w
+      @elementHeight = h
+      @dirty = false
+      # recalculate grid dimensions
+      @left = @options.padding
+      @right = @elementWidth - @options.padding
+      @top = @options.padding
+      @bottom = @elementHeight - @options.padding
+      if @options.axes in [true, 'both', 'y']
+        yLabelWidths = for gridLine in @grid
+          @measureText(@yAxisFormat(gridLine)).width
+        @left += Math.max(yLabelWidths...)
+      if @options.axes in [true, 'both', 'x']
+        bottomOffsets = for i in [0...@data.length]
+          @measureText(@data[i].text, -@options.xLabelAngle).height
+        @bottom -= Math.max(bottomOffsets...)
+      @width = Math.max(1, @right - @left)
+      @height = Math.max(1, @bottom - @top)
+      @dx = @width / (@xmax - @xmin)
+      @dy = @height / (@ymax - @ymin)
+      @calc() if @calc
+
+  # Quick translation helpers
+  #
+  transY: (y) -> @bottom - (y - @ymin) * @dy
+  transX: (x) ->
+    if @data.length == 1
+      (@left + @right) / 2
+    else
+      @left + (x - @xmin) * @dx
+
+  # Draw it!
+  #
+  # If you need to re-size your charts, call this method after changing the
+  # size of the container element.
+  redraw: ->
+    @raphael.clear()
+    @_calc()
+    @drawGrid()
+    @drawGoals()
+    @drawEvents()
+    @draw() if @draw
+
+  # @private
+  #
+  measureText: (text, angle = 0) ->
+    tt = @raphael.text(100, 100, text)
+      .attr('font-size', @options.gridTextSize)
+      .attr('font-family', @options.gridTextFamily)
+      .attr('font-weight', @options.gridTextWeight)
+      .rotate(angle)
+    ret = tt.getBBox()
+    tt.remove()
+    ret
+
+  # @private
+  #
+  yAxisFormat: (label) -> @yLabelFormat(label)
+
+  # @private
+  #
+  yLabelFormat: (label) ->
+    if typeof @options.yLabelFormat is 'function'
+      @options.yLabelFormat(label)
+    else
+      "#{@options.preUnits}#{Morris.commas(label)}#{@options.postUnits}"
+
+  # draw y axis labels, horizontal lines
+  #
+  drawGrid: ->
+    return if @options.grid is false and @options.axes not in [true, 'both', 'y']
+    for lineY in @grid
+      y = @transY(lineY)
+      if @options.axes in [true, 'both', 'y']
+        @drawYAxisLabel(@left - @options.padding / 2, y, @yAxisFormat(lineY))
+      if @options.grid
+        @drawGridLine("M#{@left},#{y}H#{@left + @width}")
+
+  # draw goals horizontal lines
+  #
+  drawGoals: ->
+    for goal, i in @options.goals
+      color = @options.goalLineColors[i % @options.goalLineColors.length]
+      @drawGoal(goal, color)
+
+  # draw events vertical lines
+  drawEvents: ->
+    for event, i in @events
+      color = @options.eventLineColors[i % @options.eventLineColors.length]
+      @drawEvent(event, color)
+
+  drawGoal: (goal, color) ->
+    @raphael.path("M#{@left},#{@transY(goal)}H#{@right}")
+      .attr('stroke', color)
+      .attr('stroke-width', @options.goalStrokeWidth)
+
+  drawEvent: (event, color) ->
+    @raphael.path("M#{@transX(event)},#{@bottom}V#{@top}")
+      .attr('stroke', color)
+      .attr('stroke-width', @options.eventStrokeWidth)
+
+  drawYAxisLabel: (xPos, yPos, text) ->
+    @raphael.text(xPos, yPos, text)
+      .attr('font-size', @options.gridTextSize)
+      .attr('font-family', @options.gridTextFamily)
+      .attr('font-weight', @options.gridTextWeight)
+      .attr('fill', @options.gridTextColor)
+      .attr('text-anchor', 'end')
+
+  drawGridLine: (path) ->
+    @raphael.path(path)
+      .attr('stroke', @options.gridLineColor)
+      .attr('stroke-width', @options.gridStrokeWidth)
+
+  # Range selection
+  #
+  startRange: (x) ->
+    @hover.hide()
+    @selectFrom = x
+    @selectionRect.attr({ x: x, width: 0 }).show()
+
+  endRange: (x) ->
+    if @selectFrom
+      start = Math.min(@selectFrom, x)
+      end = Math.max(@selectFrom, x)
+      @options.rangeSelect.call @el,
+        start: @data[@hitTest(start)].x
+        end: @data[@hitTest(end)].x
+      @selectFrom = null
+
+  resizeHandler: =>
+    @timeoutId = null
+    @raphael.setSize @el.width(), @el.height()
+    @redraw()
+
+# Parse a date into a javascript timestamp
+#
+#
+Morris.parseDate = (date) ->
+  if typeof date is 'number'
+    return date
+  m = date.match /^(\d+) Q(\d)$/
+  n = date.match /^(\d+)-(\d+)$/
+  o = date.match /^(\d+)-(\d+)-(\d+)$/
+  p = date.match /^(\d+) W(\d+)$/
+  q = date.match /^(\d+)-(\d+)-(\d+)[ T](\d+):(\d+)(Z|([+-])(\d\d):?(\d\d))?$/
+  r = date.match /^(\d+)-(\d+)-(\d+)[ T](\d+):(\d+):(\d+(\.\d+)?)(Z|([+-])(\d\d):?(\d\d))?$/
+  if m
+    new Date(
+      parseInt(m[1], 10),
+      parseInt(m[2], 10) * 3 - 1,
+      1).getTime()
+  else if n
+    new Date(
+      parseInt(n[1], 10),
+      parseInt(n[2], 10) - 1,
+      1).getTime()
+  else if o
+    new Date(
+      parseInt(o[1], 10),
+      parseInt(o[2], 10) - 1,
+      parseInt(o[3], 10)).getTime()
+  else if p
+    # calculate number of weeks in year given
+    ret = new Date(parseInt(p[1], 10), 0, 1);
+    # first thursday in year (ISO 8601 standard)
+    if ret.getDay() isnt 4
+      ret.setMonth(0, 1 + ((4 - ret.getDay()) + 7) % 7);
+    # add weeks
+    ret.getTime() + parseInt(p[2], 10) * 604800000
+  else if q
+    if not q[6]
+      # no timezone info, use local
+      new Date(
+        parseInt(q[1], 10),
+        parseInt(q[2], 10) - 1,
+        parseInt(q[3], 10),
+        parseInt(q[4], 10),
+        parseInt(q[5], 10)).getTime()
+    else
+      # timezone info supplied, use UTC
+      offsetmins = 0
+      if q[6] != 'Z'
+        offsetmins = parseInt(q[8], 10) * 60 + parseInt(q[9], 10)
+        offsetmins = 0 - offsetmins if q[7] == '+'
+      Date.UTC(
+        parseInt(q[1], 10),
+        parseInt(q[2], 10) - 1,
+        parseInt(q[3], 10),
+        parseInt(q[4], 10),
+        parseInt(q[5], 10) + offsetmins)
+  else if r
+    secs = parseFloat(r[6])
+    isecs = Math.floor(secs)
+    msecs = Math.round((secs - isecs) * 1000)
+    if not r[8]
+      # no timezone info, use local
+      new Date(
+        parseInt(r[1], 10),
+        parseInt(r[2], 10) - 1,
+        parseInt(r[3], 10),
+        parseInt(r[4], 10),
+        parseInt(r[5], 10),
+        isecs,
+        msecs).getTime()
+    else
+      # timezone info supplied, use UTC
+      offsetmins = 0
+      if r[8] != 'Z'
+        offsetmins = parseInt(r[10], 10) * 60 + parseInt(r[11], 10)
+        offsetmins = 0 - offsetmins if r[9] == '+'
+      Date.UTC(
+        parseInt(r[1], 10),
+        parseInt(r[2], 10) - 1,
+        parseInt(r[3], 10),
+        parseInt(r[4], 10),
+        parseInt(r[5], 10) + offsetmins,
+        isecs,
+        msecs)
+  else
+    new Date(parseInt(date, 10), 0, 1).getTime()
+


user store

user store

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/rrecuero/coffee-react-webpack-hapi-template.git/'


add file account_controller

add file account_controller

error: pathspec 'app/controllers/account_controller.coffee' did not match any file(s) known to git

--- app/controllers/account_controller.coffee
+++ app/controllers/account_controller.coffee
@@ -0,0 +1,48 @@
+load 'application'
+
+git = require('git-rev')
+
+Client = require("request-json").JsonClient
+client = new Client("http://localhost:9102/")
+db = require('../../helpers/db_connect_helper').db_connect()
+crypto = require('../../lib/crypto.coffee')
+
+before 'lock request', ->
+    @lock = "#{params.id}"
+    app.locker.runIfUnlock @lock, =>
+        app.locker.addLock(@lock)
+        next()
+, only: ['update', 'upsert', 'delete', 'merge']
+
+after 'unlock request', ->
+    app.locker.removeLock @lock
+, only: ['update', 'upsert', 'delete', 'merge']
+
+###before 'get doc', ->
+    db.get params.id, (err, doc) =>
+        if err and err.error == "not_found"
+            app.locker.removeLock @lock
+            send 404
+        else if err
+            console.log "[Get doc] err: " + JSON.stringify err
+            app.locker.removeLock @lock
+            send 500
+        else if doc?
+            @doc = doc
+            next()
+        else
+            app.locker.removeLock @lock
+            send 404
+, only: ['find','update', 'delete', 'merge']###
+
+# POST /accounts/password/
+action 'initializeMasterKey', ->
+    delete body._attachments
+
+    # je vais chercher salt dans la base de donnée db.
+    # if salt exist -> on utilise l'existant
+    # sinon salt = crypto.randomBytes(32-body.userPwd.length)
+    # et enregister salt dans la BD
+
+    app.crypto.masterKey = app.crypto.genHashWithSalt(body.userPwd, salt)
+


Make history size configurable, and default to 1024, for reasons. Also, don't use maxDiskLength because it's not settable for readline-history

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/sharabash/hubot.git/'


Fix error response handler to look for nested status property

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/crdschurch/crds-angular-ajax-form.git/'


fixed an issue where VideoPopup popup windows would only work from the activity stream


add kites down disconnection reason

add kites down disconnection reason


IDE: removed unnecessary check

IDE: removed unnecessary check


IDE: chat pane to use common styles with privatemessage pane


test added but not done yet

test added but not done yet

error: pathspec 'tests/tests/options/option' did not match any file(s) known to git
error: pathspec 'label.coffee' did not match any file(s) known to git


cleanup - thanks!

cleanup - thanks!

--- apps/artist/client/follow_button.coffee
+++ apps/artist/client/follow_button.coffee
@@ -14,8 +14,8 @@
     return unless options.followArtistCollection
     { @followArtistCollection, @notes } = options

-    @analyticsUnfollowMessage = options.analyticsUnfollowMessage if options.analyticsUnfollowMessage
-    @analyticsFollowMessage = options.analyticsFollowMessage if options.analyticsFollowMessage
+    @analyticsUnfollowMessage ||= options.analyticsUnfollowMessage
+    @analyticsFollowMessage ||= options.analyticsFollowMessage

     @followArtistCollection.addRepoArtist @model.get('id')


If we are scaling up then check to see if we should use a larger image

--- apps/artwork/client/view-in-room.coffee
+++ apps/artwork/client/view-in-room.coffee
@@ -57,11 +57,14 @@
   transitionIn: ->
     @$el.attr 'data-state', 'in'
     @$img.css visibility: 'hidden'
-    @$artwork.addClass 'is-transition'
     @$artwork.
+      addClass('is-transition').
       css(@getRect(@$placeholder)).
       one($.support.transition.end, =>
         @$artwork.addClass('is-notransition')
+        if @artworkScalingFactor() > 1
+          @$artwork.attr 'src',
+            @artwork.defaultImage().imageUrlFor(@$artwork.width(), @$artwork.height())
       ).emulateTransitionEnd(750)

   transitionOut: ->


fixes

fixes

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/bubblegroup/bubblebot.git/'


autoupdate should not trigger on current tick either

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/AppGyver/supersonic.git/'


Don’t disable render backgrounding. Doesn’t seem to make a difference.

--- src/browser/atom-application.coffee
+++ src/browser/atom-application.coffee
@@ -158,7 +158,6 @@
   # Configures required javascript environment flags.
   setupJavaScriptArguments: ->
     app.commandLine.appendSwitch 'js-flags', '--harmony'
-    app.commandLine.appendSwitch 'disable-renderer-backgrounding'

   # Registers basic application commands, non-idempotent.
   handleEvents: ->


removed validation until further debugging can be done

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/NewSpring/norma-sass.git/'


Fix typo in cube logging setup

Fix typo in cube logging setup

--- src/streammachine/log_controller.coffee
+++ src/streammachine/log_controller.coffee
@@ -219,7 +219,7 @@
         #----------

         log: (level,msg,meta,cb) ->
-            @socket.send type:@options.minute_event, time:meta.time, data:meta if @socket
+            @socket.send type:@options.event, time:meta.time, data:meta if @socket

         #----------


Init w3c log file if it exists but has size of zero

--- src/streammachine/log_controller.coffee
+++ src/streammachine/log_controller.coffee
@@ -158,10 +158,14 @@
             @_opening = true

             initFile = true
-            if path.existsSync @options.filename
-                # existing file...  don't write headers, just open so we can
-                # start appending
-                initFile = false
+            if path.existsSync(@options.filename)
+                # file exists...  see if there's anything in it
+                stats = fs.statSync(@options.filename)
+
+                if stats.size > 0
+                    # existing file...  don't write headers, just open so we can
+                    # start appending
+                    initFile = false

             @file = fs.createWriteStream @options.filename


fix (graphql) Set headers with middleware instead of constructor argument.


bettered tab documentations

bettered tab documentations


Small style fixes

Small style fixes

--- src/nsqdconnection.coffee
+++ src/nsqdconnection.coffee
@@ -241,7 +241,7 @@
         switch data.toString()
           when 'OK'
             cb = @conn.messageCallbacks.shift()
-            cb null if cb?
+            cb? null
           when '_heartbeat_'
             @conn.write wire.nop()

@@ -252,7 +252,7 @@
       Enter: (err) ->
         # If there's a callback, pass it the error.
         cb = @conn.messageCallbacks.shift()
-        cb err if cb?
+        cb? err

         @conn.emit NSQDConnection.ERROR, err
         @goto 'CLOSED'
@@ -263,8 +263,9 @@
     CLOSED:
       Enter: ->
         # If there are callbacks, then let them error on the closed connection.
+        err = new Error 'nsqd connection closed'
         for cb in @conn.messageCallbacks
-          cb new Error 'nsqd connection closed.' if cb?
+          cb? err
         @conn.messageCallbacks = []

         @stop()


#28 Introduce ArbitraryPlaneMaterialFactory

error: pathspec 'app/assets/javascripts/oxalis/geometries/materials/arbitrary_plane_material_factory.coffee' did not match any file(s) known to git

--- app/assets/javascripts/oxalis/geometries/materials/arbitrary_plane_material_factory.coffee
+++ app/assets/javascripts/oxalis/geometries/materials/arbitrary_plane_material_factory.coffee
@@ -0,0 +1,37 @@
+### define
+three : THREE
+./abstract_plane_material_factory : AbstractPlaneMaterialFactory
+###
+
+class ArbitraryPlaneMaterialFactory extends AbstractPlaneMaterialFactory
+
+
+  createTextures : ->
+
+    @uniforms["color_texture"] = {
+      type : "t"
+      value : createDataTexture(@tWidth, 1)
+    }
+
+
+  getFragmentShader : ->
+
+    return """
+      uniform sampler2D color_texture;
+      uniform float brightness, contrast;
+      varying vec2 vUv;
+
+      void main()
+      {
+        float color_value  = 0.0;
+
+        /* Get grayscale value */
+        color_value = texture2D( color_texture, vUv).r;
+
+        /* Brightness / Contrast Transformation */
+        color_value = (color_value + brightness - 0.5) * contrast + 0.5;
+
+        /* Set frag color */
+        gl_FragColor = vec4(data_value, data_value, data_value, 1.0);
+      }
+    """


add tutorial-slides.coffee

add tutorial-slides.coffee

error: pathspec 'tutorial/tutorial-slides.coffee' did not match any file(s) known to git

--- tutorial/tutorial-slides.coffee
+++ tutorial/tutorial-slides.coffee
@@ -0,0 +1,29 @@
+translate = require "t7e"
+
+module?.exports = [
+  {
+    image: "./images/tutorial-kelp-1.jpg"
+    title: translate "tutorial.step1.header"
+    content: translate "tutorial.step1.content"
+  },
+  {
+    image: './gifs/kelp-tut.gif'
+    title: translate "tutorial.step2.header"
+    content: translate "tutorial.step2.content"
+  },
+  {
+    image: "./gifs/kelp-tut-delete.gif"
+    title: translate "tutorial.step3.header"
+    content: translate "tutorial.step3.content"
+  },
+  {
+    image: './images/clouds-1.jpg'
+    title: translate "tutorial.step4.header"
+    content: translate "tutorial.step4.content"
+  },
+  {
+    image: './images/tutorial-kelp.jpg'
+    title: translate "tutorial.step5.header"
+    content: translate "tutorial.step5.content"
+  }
+]


Added atom config

Added atom config

error: pathspec 'profile/atom/config.cson' did not match any file(s) known to git

--- profile/atom/config.cson
+++ profile/atom/config.cson
@@ -0,0 +1,14 @@
+"*":
+  core:
+    themes: [
+      "one-light-ui"
+      "one-light-syntax"
+    ]
+  editor:
+    fontSize: 10
+    preferredLineLength: 120
+    tabType: "soft"
+  "exception-reporting":
+    userId: "8a441668-36ba-6616-f082-fff121b8137a"
+  welcome:
+    showOnStartup: false


use forms in inplace-edit

use forms in inplace-edit

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/leonidas/qa-reports.git/'


God damnit, Slava, what the fuck?

God damnit, Slava, what the fuck?

--- scripts/ayp.coffee
+++ scripts/ayp.coffee
@@ -109,7 +109,7 @@
 module.exports = (robot) ->
   buffer = new PantsBuffer()

-  robot.adapter.on 'say', (target, target, str) ->
+  robot.adapter.on 'say', (target, str) ->
     console.log "WOULD ADD: #{target.user.name}: #{str}"

   # We listen to everything.


Add rtsp.coffee

Add rtsp.coffee

error: pathspec 'rtsp.coffee' did not match any file(s) known to git

--- rtsp.coffee
+++ rtsp.coffee
@@ -0,0 +1,60 @@
+# RTSP spec:
+#   RFC 2326  http://www.ietf.org/rfc/rfc2326.txt
+
+api =
+  INTERLEAVED_SIGN: 0x24  # '$' (dollar sign)
+  INTERLEAVED_HEADER_LEN: 4
+
+  # Creates an interleaved header and returns the buffer.
+  #
+  # opts:
+  #   channel: <number> channel identifier
+  #   payloadLength: <number> payload length
+  createInterleavedHeader: (opts) ->
+    if not opts?.channel?
+      throw new Error "createInterleavedHeader: channel is required"
+    if not opts?.payloadLength?
+      throw new Error "createInterleavedHeader: payloadLength is required"
+
+    return new Buffer [
+      api.INTERLEAVED_SIGN,
+      opts.channel,
+      opts.payloadLength >> 8, opts.payloadLength & 0xff,
+    ]
+
+  # Parses and returns an interleaved header.
+  #
+  # If the buffer doesn't have enough length for an interleaved header,
+  # returns null.
+  parseInterleavedHeader: (buf) ->
+    if buf.length < api.INTERLEAVED_HEADER_LEN
+      # not enough buffer
+      return null
+
+    if buf[0] isnt api.INTERLEAVED_SIGN
+      throw new Error "The buffer is not an interleaved data"
+
+    info = {}
+    info.channel = buf[1]
+    info.payloadLength = (buf[2] << 8) | buf[3]
+    info.totalLength = api.INTERLEAVED_HEADER_LEN + info.payloadLength
+    return info
+
+  # Parses and returns the information of complete interleaved data.
+  #
+  # If parsing failed or buf doesn't have enough length for
+  # the payload, returns null.
+  getInterleavedData: (buf) ->
+    info = api.parseInterleavedHeader buf
+    if not info?
+      return null
+
+    if buf.length < info.totalLength
+      # not enough buffer
+      return null
+
+    info.data = buf[api.INTERLEAVED_HEADER_LEN...info.totalLength]
+
+    return info
+
+module.exports = api


Add isEmpty() method to repository

Add isEmpty() method to repository

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/MicrosmartSA/ubiquity-ui.git/'


Added role.coffee - extension for querySelectorAll function

error: pathspec 'role.coffee' did not match any file(s) known to git

--- role.coffee
+++ role.coffee
@@ -0,0 +1,15 @@
+###
+  Role extension to querySelectorAll function.
+
+  Works only in modern browsers.
+  Perfectly in usage with Zepto.js or similar library
+
+  Version: 0.4.0
+  Copyright (c) 2011 Sasha Koss
+###
+
+for elm in [Document, Element]
+  do (elm) ->
+    nativeQuery = elm::querySelectorAll
+    elm::querySelectorAll = (selector) ->
+      nativeQuery.call( @, selector.replace(/@(\w+)/g, "[role~=\"$1\"]") )


Changing port to 8001

Changing port to 8001

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/bizMD/fidelius.git/'


[deploy: production]

[deploy: production]

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/domjtalbot/Portfolio.git/'


Framework built out for MyWot

Framework built out for MyWot

error: pathspec 'src/scripts/mywot.coffee' did not match any file(s) known to git

--- src/scripts/mywot.coffee
+++ src/scripts/mywot.coffee
@@ -0,0 +1,20 @@
+# Description:
+#   Get Website Reputation from MyWot (www.mywot.com)
+#
+# Dependencies:
+#   None
+#
+# Configuration:
+#   None
+#
+# Commands:
+#   hubot mywot <url> - Gets MyWot Report for URL
+#
+# Author:
+#   Scott J Roberts - @sroberts
+
+module.exports = (robot) ->
+  robot.respond /mywot/i, (msg) ->
+    # If there's strings generate rule with strings
+
+    # If there aren't then just generate a template


initial commit and queuer mocks

initial commit and queuer mocks

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/Bogdan-p/bookingbug-angular.git/'


Improve search query

Improve search query

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/douggr/atom-project-manager.git/'


Fallback to not using turbolinks on error.

When there is an error fetching the replacement document the code should
try an old fashioned "full request".  This allows the browser to do
the things that the browser knows how to do in this situation including
hits to the applicationCache and error messaging.

--- lib/assets/javascripts/turbolinks.js.coffee
+++ lib/assets/javascripts/turbolinks.js.coffee
@@ -17,9 +17,9 @@
 fetchReplacement = (url) ->
   triggerEvent 'page:fetch'

-  # Remove hash from url to ensure IE 10 compatibility
+  # Remove hash from url to ensure IE 10 compatibility
   safeUrl = removeHash url
-
+
   xhr = new XMLHttpRequest
   xhr.open 'GET', safeUrl, true
   xhr.setRequestHeader 'Accept', 'text/html, application/xhtml+xml, application/xml'
@@ -41,6 +41,10 @@

   xhr.onabort = -> console.log 'Aborted turbolink fetch!'

+  xhr.onerror = ->
+    console.log 'turbolink fetch Failed!'
+    document.location.href = url
+
   xhr.send()

 fetchHistory = (state) ->


Added a new overlay plugin to isolate the editable and save when pressing escape or clicking on the overly

error: pathspec 'plugins/overlay.coffee' did not match any file(s) known to git

--- plugins/overlay.coffee
+++ plugins/overlay.coffee
@@ -0,0 +1,163 @@
+#   Hallo - a rich text editing jQuery UI widget
+#   (c) 2011 Henri Bergius, IKS Consortium
+#   Hallo may be freely distributed under the MIT license
+#
+# ============================================================
+#
+#   Hallo overlay plugin
+#   (c) 2011 Liip AG, Switzerland
+#   This plugin may be freely distributed under the MIT license.
+#
+#   The overlay plugin adds an overlay around the editable element.
+#   It has no direct dependency with other plugins, but requires the
+#   "floating" hallo option to be false to look nice. Furthermore, the
+#   toolbar should have the same width as the editable element.
+#
+#   The options are documented in the code.
+#
+
+((jQuery) ->
+    jQuery.widget "IKS.hallooverlay",
+        options:
+            editable: null
+            toolbar: null
+            uuid: ""
+            opacity: 0.5
+            backgroundColor: '#000000'
+
+            # The pieces of the overlay are re-positioned when the editable is modified. This value defines
+            # the minimal interval between two repositioning to avoid performance issues
+            updateInterval: 100
+
+            # Adapt these values if you have rounded corners for the editable
+            offsetTop: 0
+            offsetLeft: 0
+            offsetRight: 0
+            offsetBottom: 0
+
+            # The overlay pieces around the editable element
+            pieces: {}
+
+        _create: ->
+            widget = this
+
+            if not @options.bound
+                @options.bound = true
+                widget.options.editable.element.bind "halloselected", (event, data) ->
+                    widget.options.currentEditable = jQuery(event.target)
+                    widget.showOverlay()
+
+                widget.options.editable.element.bind "hallomodified", (event, data) ->
+                    if widget.visible
+                        widget.updateOverlay()
+
+                # abort editing when pressing ESCAPE
+                widget.options.editable.element.keydown (event, data) ->
+                    if event.keyCode == 27
+                        widget.options.editable.restoreOriginalContent()
+                        widget.options.editable.element.blur()
+                        widget.hideOverlay()
+
+        _init: ->
+
+        showOverlay: ->
+            @options.visible = true
+            if @options.pieces.top
+                for key, piece of @options.pieces
+                    piece.show()
+                @updateOverlay()
+                return
+
+            @_createOverlay()
+
+        hideOverlay: ->
+            @options.visible = false
+            if @options.pieces.top
+                for key, piece of @options.pieces
+                    piece.hide()
+
+            @options.editable._deactivated {data: @options.editable}
+
+        updateOverlay: ->
+            # trying to avoid performance issue
+            now = new Date().getTime();
+            if @options.lastUpdate and now - @options.lastUpdate < @options.updateInterval
+                return
+
+            @options.lastUpdate = now
+            if @options.pieces.top
+                m = @_getMeasures();
+
+                @options.pieces.left.css
+                    height: m.editableHeight - @options.offsetTop - @options.offsetBottom
+
+                @options.pieces.right.css
+                    height: m.editableHeight - @options.offsetTop - @options.offsetBottom
+
+                @options.pieces.bottom.css
+                    top: m.editableTop + m.editableHeight - @options.offsetBottom
+                    height: m.documentHeight - m.editableTop + m.editableHeight + @options.offsetBottom
+
+        _createOverlay: () ->
+            m = @_getMeasures();
+
+            top = @_getBasicPiece()
+            top.css
+                top: 0
+                left: 0
+                width: '100%'
+                height: m.editableTop + @options.offsetTop
+            jQuery(document.body).append top
+            @options.pieces.top = top
+
+            left = @_getBasicPiece()
+            left.css
+                top: m.editableTop + @options.offsetTop
+                left: 0
+                width: m.editableLeft + @options.offsetLeft
+                height: m.editableHeight - @options.offsetTop - @options.offsetBottom
+            jQuery(document.body).append left
+            @options.pieces.left = left
+
+            right = @_getBasicPiece()
+            right.css
+                top: m.editableTop + @options.offsetTop
+                right: 0
+                width: m.windowWidth - (m.editableLeft + m.editableWidth) + @options.offsetRight
+                height: m.editableHeight - @options.offsetTop - @options.offsetBottom
+            jQuery(document.body).append right
+            @options.pieces.right = right
+
+            bottom = @_getBasicPiece()
+            bottom.css
+                top: m.editableTop + m.editableHeight - @options.offsetBottom
+                left: 0
+                width: '100%'
+                height: m.documentHeight - m.editableTop + m.editableHeight + @options.offsetBottom
+            jQuery(document.body).append bottom
+            @options.pieces.bottom = bottom
+
+            for key, piece of @options.pieces
+                piece.bind 'click', jQuery.proxy @hideOverlay, @
+
+        _getMeasures: ->
+            m =
+                editableHeight: @options.toolbar.outerHeight() + @options.currentEditable.outerHeight()
+                editableWidth: @options.currentEditable.outerWidth()
+                editableTop: parseInt @options.toolbar.css 'top'
+                editableLeft: parseInt @options.currentEditable.offset().left
+                windowWidth: jQuery(window).width()
+                documentHeight: jQuery(window.document).height()
+            m.editableRight = m.editableLeft + m.editableWidth
+            m.editableBottom = m.editableTop + m.editableHeight
+            return m
+
+        _getBasicPiece: ->
+            p = jQuery('<div>')
+            p.css
+                position: 'absolute'
+                backgroundColor: @options.backgroundColor
+                opacity: @.options.opacity
+
+
+)(jQuery)


getting ready to release RL stuff

getting ready to release RL stuff

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/Mikuia/Mikuia.git/'


Add coffee version of the shim.

Add coffee version of the shim.

error: pathspec 'examples/airbrake-shim.coffee' did not match any file(s) known to git

--- examples/airbrake-shim.coffee
+++ examples/airbrake-shim.coffee
@@ -0,0 +1,63 @@
+# Airbrake shim that stores exceptions until Airbrake notifier is loaded.
+window.Airbrake = []
+
+# Wraps passed function and returns new function that catches and
+# reports unhandled exceptions.
+Airbrake.wrap = (fn) ->
+  airbrakeWrapper = ->
+    try
+      return fn.apply(this, arguments)
+    catch exc
+      args = Array.prototype.slice.call(arguments)
+      Airbrake.push({error: exc, params: {arguments: args}})
+  if fn.guid
+    airbrakeWrapper.guid = fn.guid
+  return airbrakeWrapper
+
+# Reports unhandled exceptions.
+window.onerror = (message, file, line) ->
+  Airbrake.push({error: {message: message, fileName: file, lineNumber: line}})
+
+loadAirbrakeNotifier = ->
+  script = document.createElement('script')
+  sibling = document.getElementsByTagName('script')[0]
+  script.src = 'https://ssljscdn.airbrake.io/0.3.3/airbrake.min.js'
+  script.async = true
+  sibling.parentNode.insertBefore(script, sibling)
+
+# Asynchronously loads Airbrake notifier.
+if window.addEventListener
+  window.addEventListener('load', loadAirbrakeNotifier, false)
+else
+  window.attachEvent('onload', loadAirbrakeNotifier)
+
+# Reports exceptions thrown in jQuery event handlers.
+jqEventAdd = jQuery.event.add
+jQuery.event.add = (elem, types, handler, data, selector) ->
+  if handler.handler
+    if not handler.handler.guid
+      handler.handler.guid = jQuery.guid++
+    handler.handler = Airbrake.wrap(handler.handler)
+  else
+    if not handler.guid
+      handler.guid = jQuery.guid++
+    handler = Airbrake.wrap(handler)
+  return jqEventAdd(elem, types, handler, data, selector)
+
+# Reports exceptions thrown in jQuery callbacks.
+jqCallbacks = jQuery.Callbacks
+jQuery.Callbacks = (options) ->
+  cb = jqCallbacks(options)
+  cbAdd = cb.add
+  cb.add = ->
+    fns = arguments
+    jQuery.each fns, (i, fn) ->
+      if jQuery.isFunction(fn)
+        fns[i] = Airbrake.wrap(fn)
+    return cbAdd.apply(this, fns)
+  return cb
+
+# Reports exceptions thrown in jQuery ready callbacks.
+jqReady = jQuery.fn.ready
+jQuery.fn.ready = (fn) ->
+  return jqReady(Airbrake.wrap(fn))


error checking for chrome frame prompt

error checking for chrome frame prompt

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/leonidas/qa-dashboard.git/'


Add play_counts API input null check

Add play_counts API input null check

--- server/levels/level_handler.coffee
+++ server/levels/level_handler.coffee
@@ -319,6 +319,8 @@
     # This is hella slow (4s on my box), so relying on some dumb caching for it.
     # If we can't make this faster with indexing or something, we might want to maintain the counts another way.
     levelIDs = req.query.ids or req.body.ids
+    return @sendSuccess res, [] unless levelIDs?
+
     @playCountCache ?= {}
     @playCountCachedSince ?= new Date()
     if (new Date()) - @playCountCachedSince > 86400 * 1000  # Dumb cache expiration


clean phonebook search on new call

clean phonebook search on new call

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/VoiSmart/Rocket.Chat.git/'


add max_shown_results spec for prototype

error: pathspec 'spec/proto/max_shown_results.spec.coffee' did not match any file(s) known to git

--- spec/proto/max_shown_results.spec.coffee
+++ spec/proto/max_shown_results.spec.coffee
@@ -0,0 +1,68 @@
+describe 'search', ->
+  it 'should display only matching items when entering a search term', ->
+    tmpl = '''
+      <select data-placeholder="Choose a Country...">
+        <option value=""></option>
+        <option value="United States">United States</option>
+        <option value="United Kingdom">United Kingdom</option>
+        <option value="Afghanistan">Afghanistan</option>
+      </select>
+    '''
+    div = new Element('div')
+    document.body.insert(div)
+    div.update(tmpl)
+    select = div.down('select')
+    new Chosen(select)
+
+    container = div.down('.chosen-container')
+    simulant.fire(container, 'mousedown') # open the drop
+    # Expect all results to be shown
+    results = div.select('.active-result')
+    expect(results.length).toBe(3)
+
+    # Enter some text in the search field.
+    search_field = div.down('.chosen-search input')
+    search_field.value = 'Afgh'
+    simulant.fire(search_field, 'keyup')
+
+    # Expect to only have one result: 'Afghanistan'.
+    results = div.select('.active-result')
+    expect(results.length).toBe(1)
+    expect(results[0].innerText).toBe 'Afghanistan'
+
+  it 'should only show max_shown_results items in results', ->
+    tmpl = '''
+      <select data-placeholder="Choose a Country...">
+        <option value=""></option>
+        <option value="United States">United States</option>
+        <option value="United Kingdom">United Kingdom</option>
+        <option value="Afghanistan">Afghanistan</option>
+      </select>
+    '''
+    div = new Element('div')
+    document.body.insert(div)
+    div.update(tmpl)
+    select = div.down('select')
+    new Chosen(select, { max_shown_results: 1 })
+
+    container = div.down('.chosen-container')
+    simulant.fire(container, 'mousedown') # open the drop
+    results = div.select('.active-result')
+    expect(results.length).toBe(1)
+
+    # Enter some text in the search field.
+    search_field = div.down('.chosen-search input')
+    search_field.value = 'United'
+    simulant.fire(search_field, 'keyup')
+
+    # Showing only one result: the one that occurs first.
+    results = div.select('.active-result')
+    expect(results.length).toBe(1)
+    expect(results[0].innerText).toBe 'United States'
+
+    # Showing still only one result, but not the first one.
+    search_field.value = 'United Ki'
+    simulant.fire(search_field, 'keyup')
+    results = div.select('.active-result')
+    expect(results.length).toBe(1)
+    expect(results[0].innerText).toBe 'United Kingdom'


Better variable name

Better variable name

--- resources/assets/coffee/_classes/nav.coffee
+++ resources/assets/coffee/_classes/nav.coffee
@@ -27,11 +27,11 @@
     @switches = document.getElementsByClassName('js-nav-switch')

-  autoFocus: (event, target) =>
-    if event?
-      target = event.currentTarget
+  autoFocus: (e, popup) =>
+    if e?
+      popup = e.currentTarget

-    target.getElementsByClassName('js-nav-auto-focus')[0]?.focus?()
+    popup.getElementsByClassName('js-nav-auto-focus')[0]?.focus?()

   available: => @popup[0]?


fix(gdriveSpreadsheet): map scope dependency for minjs

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/keboola/kbc-ui-ex-gdrive.git/'


simplify the pane-axis-element-spec spec files

--- spec/pane-axis-element-spec.coffee
+++ spec/pane-axis-element-spec.coffee
@@ -1,58 +1,46 @@
 PaneAxisElement = require '../src/pane-axis-element'
+PaneAxis = require '../src/pane-axis.coffee'

-describe "PaneResizeHandleElement", ->
+fdescribe "PaneResizeHandleElement", ->
   describe "add and remove", ->
-    class TestItemElement extends HTMLElement
-      createdCallback: ->
-        @classList.add('test-root')
+    [paneAxisElement, paneAxis] = []

-    TestItemElement = document.registerElement 'atom-test-item-element', prototype: TestItemElement.prototype
+    beforeEach ->
+      paneAxisElement = document.createElement('atom-pane-axis')
+      paneAxis = new PaneAxis({})
+      paneAxisElement.initialize(paneAxis)
+      document.querySelector('#jasmine-content').appendChild(paneAxisElement)

-    [paneAxis, model, Model] = []
-    beforeEach ->
-      # This is a dummy item to prevent panes from being empty on deserialization
-      class Model
-        @newChild: -> document.createElement('atom-test-item-element')
-        add: (child, index) -> @addCallback({child, index})
-        remove: (child) -> @removeCallback {child}
-        replace: (index, oldChild, newChild) ->
-          @replaceCallback {index, oldChild, newChild}
-        onDidAddChild: (@addCallback) ->
-        onDidRemoveChild: (@removeCallback) ->
-        onDidReplaceChild: (@replaceCallback) ->
-        getOrientation: -> 'horizontal'
-        getChildren: -> []
+    it "inserts draggable resize elements between pane axis children", ->
+      expect(paneAxisElement).toBeTruthy()
+      modelChildren = (new PaneAxis({}) for i in [1..5])
+      paneAxis.addChild(modelChildren[0])
+      paneAxis.addChild(modelChildren[1])

-      paneAxis = document.createElement('atom-pane-axis')
-      model = new Model
-      paneAxis.initialize(model)
-      document.querySelector('#jasmine-content').appendChild(paneAxis)
+      expectPaneAxisElement = (index) ->
+        child = paneAxisElement.children[index]
+        expect(child.nodeName.toLowerCase()).toBe('atom-pane-axis')

-    it "should insert the correct postion in one pane axis", ->
-      expect(paneAxis).toBeTruthy()
-      modelChildren = (Model.newChild() for i in [1..5])
-      model.add(modelChildren[0])
-      model.add(modelChildren[1])
+      expectResizeElement = (index) ->
+        child = paneAxisElement.children[index]
+        expect(paneAxisElement.isPaneResizeHandleElement(child)).toBe(true)

-      expect(paneAxis.children[0]).toBe(modelChildren[0])
-      expect(paneAxis.children[2]).toBe(modelChildren[1])
-      expectTestItemElement = (index) ->
-        child = paneAxis.children[index]
-        expect(child.nodeName.toLowerCase()).toBe('atom-test-item-element')
-      expectResizeElement = (index) ->
-        expect(paneAxis.isPaneResizeHandleElement(paneAxis.children[index])).toBe(true)
+      expect(paneAxisElement.children[0].model).toBe(modelChildren[0])
       expectResizeElement(1)
+      expect(paneAxisElement.children[2].model).toBe(modelChildren[1])

-      model.add(modelChildren[2])
-      model.add(modelChildren[3])
-      expectTestItemElement(i) for i in [0, 2, 4, 6]
+      paneAxis.addChild(modelChildren[2])
+      paneAxis.addChild(modelChildren[3])
+      expectPaneAxisElement(i) for i in [0, 2, 4, 6]
       expectResizeElement(i) for i in [1, 3, 5]

-      model.remove(modelChildren[2])
+      # test removeChild
+      paneAxis.removeChild(modelChildren[2])
       # modelChildren[3] replace modelChildren[2]
-      expect(paneAxis.children[4]).toBe(modelChildren[3])
+      expect(paneAxisElement.children[4].model).toBe(modelChildren[3])
       expectResizeElement(i) for i in [1, 3]

-      model.replace(0, modelChildren[0], modelChildren[4])
-      expect(paneAxis.children[0]).toBe(modelChildren[4])
+      # test replaceChild
+      paneAxis.replaceChild(modelChildren[0], modelChildren[4])
+      expect(paneAxisElement.children[0].model).toBe(modelChildren[4])
       expectResizeElement(i) for i in [1, 3]


Listen for package events and update view on state changes

--- src/app/package-config-view.coffee
+++ src/app/package-config-view.coffee
@@ -91,26 +91,21 @@
         @togglePackageEnablement()
         return

-      packageManagerCallback = =>
-        @defaultAction.enable()
-        @updatePackageState()
-        @updateDefaultAction()

       @defaultAction.disable()
       if @installed
         if @updateAvailable
           @defaultAction.text('Upgrading\u2026')
-          packageManager.install(@pack, packageManagerCallback)
+          packageManager.install @pack, (error) =>
+            @packageEventEmitter.trigger('package-upgraded', error, @pack)
         else
           @defaultAction.text('Uninstalling\u2026')
           packageManager.uninstall @pack, (error) =>
             @packageEventEmitter.trigger('package-uninstalled', error, @pack)
-            packageManagerCallback()
       else
         @defaultAction.text('Installing\u2026')
         packageManager.install @pack, (error) =>
           @packageEventEmitter.trigger('package-installed', error, @pack)
-          packageManagerCallback()

     @updateDefaultAction()

@@ -120,6 +115,12 @@
       @updatePackageState()
       @updateDefaultAction()
       @updateEnabledState()
+
+    @packageEventEmitter.on 'package-installed package-uninstalled package-upgraded', (error, pack) =>
+      if pack?.name is @pack.name
+        @defaultAction.enable()
+        @updatePackageState()
+        @updateDefaultAction()

   togglePackageEnablement: ->
     if @disabled


param passing to code blocks

param passing to code blocks

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/showell/CoffeeCoffee.git/'


Use forward slashes in sh path

Use forward slashes in sh path

--- src/browser/squirrel-update.coffee
+++ src/browser/squirrel-update.coffee
@@ -117,7 +117,7 @@

     atomShCommandPath = path.join(binFolder, 'atom')
     relativeAtomShPath = path.relative(binFolder, path.join(appFolder, 'resources', 'cli', 'atom.sh'))
-    atomShCommand = "#!/bin/sh\r\n\"$0\\#{relativeAtomPath}\" \"$@\""
+    atomShCommand = "#!/bin/sh\r\n\"$0/#{relativeAtomShPath.replace(/\\/g, '/')}\" \"$@\""

     apmCommandPath = path.join(binFolder, 'apm.cmd')
     relativeApmPath = path.relative(binFolder, path.join(process.resourcesPath, 'app', 'apm', 'node_modules', 'atom-package-manager', 'bin', 'apm.cmd'))


:memo: Doc removeCommandsFromPath

:memo: Doc removeCommandsFromPath

--- src/browser/squirrel-update.coffee
+++ src/browser/squirrel-update.coffee
@@ -89,7 +89,7 @@
     deleteFromRegistry directoryKeyPath, ->
       deleteFromRegistry(backgroundKeyPath, callback)

-# Add apm and atom.exe to the PATH
+# Add atom and apm to the PATH
 #
 # This is done by adding .cmd shims to the root bin folder in the Atom
 # install directory that point to the newly installed versions inside
@@ -131,6 +131,7 @@
       else
         callback()

+# Remove atom and apm from the PATH
 removeCommandsFromPath = (callback) ->
   getPath (error, pathEnv) ->
     return callback(error) if error?


Hide "Settings" tab

Hide "Settings" tab

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/AppGyver/kitchensink.git/'


Add ability to deploy to production (#20)

error: pathspec 'scripts/deploy.coffee' did not match any file(s) known to git

--- scripts/deploy.coffee
+++ scripts/deploy.coffee
@@ -0,0 +1,28 @@
+# Description:
+#   Causes heart attacks.
+#
+# Commands:
+#   hubot deploy to production - Deploy Ralph to production.
+
+apps = [
+  'argos',
+  'levelup-order-ahead-production',
+  'levelup-production',
+  'order-ahead-network-production',
+  'plutus-production'
+]
+
+emojis = [
+  ':+1:',
+  ':dance:',
+  ':party_poop:',
+  ':party_try_not_to_cry:',
+  ':partydumpster:',
+  ':shush:',
+  ':spinner:'
+]
+
+module.exports = (robot) ->
+  robot.respond /deploy\s+to\s+prod(?:uction)?/i, (msg) ->
+    reply = "ok, deploying myself to #{msg.random(apps)} #{msg.random(emojis)}"
+    msg.send reply


add ids

add ids

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/leonidas/qa-reports.git/'


Add initial username check

Add initial username check

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/tombell/hubot-github-identity.git/'


Alter defaults for contacts

Alter defaults for contacts

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/timdavies/trunk.git/'


Add new landing page module.

Add new landing page module.

error: pathspec 'src/landing.coffee' did not match any file(s) known to git

--- src/landing.coffee
+++ src/landing.coffee
@@ -0,0 +1,18 @@
+define 'app/landing', () ->
+
+    clear_landing_page = ->
+        # The transitions triggered by removing the class landing from body are defined
+        # in the file landing-page.less.
+        # When key animations have ended a 'landing-page-cleared' event is triggered.
+        if $('body').hasClass('landing')
+            $('body').removeClass('landing')
+            $('.service-sidebar').on('transitionend webkitTransitionEnd oTransitionEnd MSTransitionEnd', (event) ->
+                if not event.originalEvent
+                    return
+                if event.originalEvent.propertyName is 'top'
+                    app.vent.trigger('landing-page-cleared')
+                    $(@).off('transitionend webkitTransitionEnd oTransitionEnd MSTransitnd')
+                )
+    return {
+        clear: clear_landing_page
+    }


SensorBrowser added

SensorBrowser added

error: pathspec 'app/coffeescripts/SensorCollection.coffee' did not match any file(s) known to git

--- app/coffeescripts/SensorCollection.coffee
+++ app/coffeescripts/SensorCollection.coffee
@@ -0,0 +1,22 @@
+class window.sirius.SensorCollection extends Backbone.Collection
+  $a = window.sirius
+  model: $a.Sensor
+
+  initialize:(@models) ->
+    @models.forEach((sensor) -> sensor.set('selected', false))
+
+  getBrowserColumnData: () ->
+    @models.map((sensor) ->
+            [
+              sensor.get('id'),
+              sensor.get('type'),
+              sensor.get('link_type'),
+              sensor.get('link_reference').get('id'),
+              sensor.get('description').get('text')
+            ]
+    )
+
+  setSelected: (sensors) ->
+    _.each(sensors, (sensor) ->
+      sensor.set('selected', true) if !sensor.get('selected')
+    )


Env variable rename for Octobot

Env variable rename for Octobot

error: pathspec 'scripts/octobot.coffee' did not match any file(s) known to git

--- scripts/octobot.coffee
+++ scripts/octobot.coffee
@@ -0,0 +1,168 @@
+# Description:
+#   Hubot interface to octopus deploy
+#
+# Commands:
+#   hubot octo promote <project> from <env1> to <env2> - Hubot deploys the latest release of <project> on <env1> to <env2>
+#   hubot octo deploy <project> version <version> to <env> - Hubot deploys the specified version of <project> to <env>
+#   hubot octo status - Hubot prints a dashboard of environments and currently deployed versions.
+#
+# Configuration:
+#   HUBOT_OCTOPUS_URL_BASE: required
+#   HUBOT_OCTOPUS_KEY: required
+#
+# Author:
+#   JD Courtoy
+
+
+_ = require('underscore')._
+q = require('q')
+util = require('util')
+
+apikey = process.env.HUBOT_OCTOPUS_KEY
+urlBase = process.env.HUBOT_OCTOPUS_URL_BASE
+
+module.exports = (robot) ->
+  robot.respond /(octopus|octo) status$/i, (msg) ->
+    getItems(robot, "api/dashboard")
+      .then (data) ->
+        m = "We're currently rolling with:"
+        for proj in data.Projects
+          if proj
+            m = m + "\n Project: " + proj.Name
+            projItems = _.filter(data.Items, (i) -> if i.ProjectId == proj.Id then i)
+
+            if projItems && projItems.length > 0
+              for item in projItems
+                if item
+                  enviro = _.find(data.Environments, (env) -> env.Id == item.EnvironmentId)
+                  tabset = enviro.Name.length > "\t" ? " : \t" : " : \t\t"
+                  formata = "\n  > %s\t\t : %s - %s"
+                  formatb = "\n  > %s\t : %s - %s"
+                  format = if enviro.Name.length >= 5 then formatb else formata
+                  m = m + util.format(format, enviro.Name, item.ReleaseVersion, item.State)
+            else
+              m = m + "\n  > No Deployments"
+        msg.send m
+      .catch (error) ->
+        msg.send error
+
+  robot.respond /(octo promote) (.+) (from) (.+) (to) (.+)/i, (msg) ->
+    projectName = msg.match[2]
+    sourceEnvName = msg.match[4]
+    targetEnvName = msg.match[6]
+
+    getItem(robot, "api/projects", findByName(projectName))
+      .then (project) ->
+        if (!project)
+          throw new Error("Could not find project #{projectName}");
+
+        this.project = project
+        getItem(robot, "api/environments", findByName(sourceEnvName))
+      .then (sourceEnv) ->
+        if (!sourceEnv)
+          throw new Error("Could not find environment #{sourceEnvName}");
+
+        this.sourceEnv = sourceEnv
+        getItem(robot, "api/environments", findByName(targetEnvName))
+      .then (targetEnv) ->
+        if (!targetEnv)
+          throw new Error("Could not find environment #{targetEnvName}");
+
+        this.targetEnv = targetEnv
+        mostRecentRelease(robot, this.project)
+      .then (prevRelease) ->
+        if (!prevRelease)
+          throw new Error("Could not find previous release");
+
+        this.prevRelease = prevRelease
+        deployRelease(robot, prevRelease, targetEnv)
+      .then (deployment) ->
+        msg.send "Promoted #{this.prevRelease.Version} from #{sourceEnvName} to #{targetEnvName}"
+      .catch (error) ->
+        msg.send error
+
+  robot.respond /(octopus|octo) deploy (.+) version (.+) (to) (.+)/i, (msg) ->
+    projectName = msg.match[2]
+    version = msg.match[3]
+    targetEnvName = msg.match[5]
+    getItem(robot, "api/projects", findByName(projectName))
+    .then (project) ->
+      if (!project)
+        throw new Error("Could not find project #{projectName}");
+      this.project = project
+      getItem(robot, "api/environments", findByName(targetEnvName))
+    .then (targetEnv) ->
+      if (!targetEnv)
+        throw new Error("Could not find environment #{targetEnvName}");
+      this.targetEnv = targetEnv
+      findRelease(robot, this.project, version)
+    .then (release) ->
+      if (!release)
+        throw new Error("Could not find previous release");
+      this.release = release
+      deployRelease(robot, release, targetEnv)
+    .then (deployment) ->
+      msg.send "Promoting #{this.release.Version} to #{targetEnvName}"
+    .catch (error) ->
+      msg.send error
+
+createHTTPCall = (robot, urlPath) ->
+  robot.http("#{urlBase}/#{urlPath}")
+       .header("X-Octopus-ApiKey", apikey)
+       .header("content-type", "application/json")
+
+deployRelease = (robot, release, environment) ->
+  deferred = q.defer()
+  deployment =
+    Comments: "Deployed from Hubot"
+    EnvironmentId: environment.Id
+    ReleaseId: release.Id
+
+  createHTTPCall(robot, "/api/deployments")
+  .post(JSON.stringify(deployment)) (err, res, body) ->
+    if(err)
+      deferred.reject err
+    else
+      deferred.resolve (JSON.parse body)
+  deferred.promise
+
+getItems = (robot, urlPath) ->
+  deferred = q.defer()
+  createHTTPCall(robot,urlPath)
+  .get() (err, res, body) ->
+    if err
+      deferred.reject(err)
+    else
+      items = (JSON.parse body)
+      deferred.resolve(items)
+  deferred.promise
+
+getItem = (robot, urlPath, selectFunc) ->
+  deferred = q.defer()
+  createHTTPCall(robot, urlPath)
+  .get() (err, res, body) ->
+    if err
+      deferred.reject(err)
+    else
+      items = (JSON.parse body).Items
+      deferred.resolve(selectFunc(items))
+  deferred.promise
+
+findByName = (name)->
+  (items) ->_.find(items, (item) -> item.Name == name)
+
+findByFirst = () ->
+  (items) -> _.first(items)
+
+findByVersion = (version) ->
+  (items) -> _.find(items, (item)-> item.Version == version)
+
+mostRecentRelease = (robot, project) ->
+  releasesUrl = project.Links["Releases"].replace /{.*}/, ""
+  getItem(robot, releasesUrl, findByFirst())
+  .then (val) -> val
+
+findRelease = (robot, project, version) ->
+  releasesUrl = project.Links["Releases"].replace /{.*}/,""
+  getItem(robot, releasesUrl, findByVersion(version))
+  .then (val) -> val


Add Coffeescript version of countdown.js.

error: pathspec 'examples/countdown.coffee' did not match any file(s) known to git

--- examples/countdown.coffee
+++ examples/countdown.coffee
@@ -0,0 +1,8 @@
+t = 10
+while t > 0
+    console.log t
+    phantom.sleep 1000
+    t = t - 1
+
+console.log 'BLAST OFF'
+phantom.exit()


忍とお喋りするスクリプト追加

忍とお喋りするスクリプト追加

error: pathspec 'scripts/shinobu.coffee' did not match any file(s) known to git

--- scripts/shinobu.coffee
+++ scripts/shinobu.coffee
@@ -0,0 +1,58 @@
+# Description:
+#   忍野忍 bot
+#
+# Dependencies:
+#   None
+#
+# Configuration:
+#
+# Commands:
+#   None
+#
+# Notes:
+#
+
+cute_shinobu = [
+  "うぬは儂が頭を撫でろと言えば、いつでもどこでも、忠実に撫でねばならんのじゃぞ？",
+  "年季の違いというものを思い知らせてやる。",
+  "どうした？お前様よ。考え事か？",
+  "ぱないの！",
+  "大丈夫じゃよ。待機中、儂は影の中でＤＳをやっておるから。",
+  "提案なのじゃが、お前様よ。今すぐ儂を殺して、今度こそ掛け値ない人間に戻ってみるというなは如何かな？",
+  "……何をじろじろ見とる。このような幼児の裸に興味津々とは、お前様は真性の変態か。",
+  "ま、死ぬときは一緒なのじゃから――生きるときは、尚一緒かの。",
+  "世界と女の子を天秤にかけて、女の子を選ぶという奴か。今時じゃの。",
+  "キスショット・アセロラオリオン・ハートアンダーブレードって、３回に１回くらい、うっかり忘れる。忍野忍と短くなって、正直、ほっとしておるくらいじゃ",
+]
+
+module.exports = (robot) ->
+
+  robot.hear /:shinobu|@shinobu/i, (msg) ->
+    msg.send msg.random cute_shinobu
+
+  robot.hear /おののき|斧乃木/i, (msg) ->
+    msg.send "かっ……資料も文献もロクに残存しておらん、極東のマイナー妖怪が。二度とキメ顔などできなくしてやるわ。"
+
+  robot.hear /大好き/i, (msg) ->
+    msg.send msg.random [
+      "今のところ儂はお前様のことを気に入っておるのじゃよ。",
+      "むうう。お前様、さては男の中の男じゃな。",
+    ]
+
+  robot.hear /ドーナッツ/i, (msg) ->
+    msg.send msg.random [
+      "ぱないの！",
+      "儂を店まで連れて行くがよい。この目で見て選びたいのじゃ。",
+      "お前様よ。儂が極秘ルートから入手した情報によると、ミスタードーナツが今、全品百円セールを行っておるらしいのじゃ。",
+    ]
+
+  robot.hear /死のう/i, (msg) ->
+    msg.send msg.random [
+      "死ぬときは一緒じゃと、言ったろう。"
+    ]
+
+  robot.hear /暴走/i, (msg) ->
+    msg.send msg.random [
+      "うおっ！超可愛い！後ろから襲ってハグしてきてもよいかのっ！"
+    ]
+


fixed window location when logging out

fixed window location when logging out


Log server start with brunch logger.

Log server start with brunch logger.

--- src/helpers.coffee
+++ src/helpers.coffee
@@ -53,27 +53,25 @@

 startDefaultServer = (port, path, callback) ->
   server = express.createServer()
-  server.configure ->
-    server.use express.static path
-    server.set 'views', path
-    server.set 'view options', layout: no
-    server.register '.html', compile: (str, options) -> (locals) -> str
-  server.get '/', (req, res) ->
-    res.render 'index.html'
+  server.use express.static path
+  server.all '/*', (request, response) ->
+    response.sendfile sysPath.join path, 'index.html'
   server.listen parseInt port, 10
   server.on 'listening', callback
-  logger.info "application started on http://localhost:#{port}/"
   server

 exports.startServer = (config, callback = (->)) ->
+  onListening = ->
+    logger.info "application started on http://localhost:#{config.server.port}/"
+    callback()
   if config.server.path
     try
       server = require sysPath.resolve config.server.path
-      server.startServer config.server.port, config.paths.public, callback
+      server.startServer config.server.port, config.paths.public, onListening
     catch error
       logger.error "couldn\'t load server #{config.server.path}: #{error}"
   else
-    startDefaultServer config.server.port, config.paths.public, callback
+    startDefaultServer config.server.port, config.paths.public, onListening

 exports.replaceSlashes = replaceSlashes = (config) ->
   changePath = (string) -> string.replace(/\//g, '\\')


fix login

fix login

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/YY030913/tp.git/'


Update configuration

Update configuration

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/ehmicky/myos.git/'


Update configuration

Update configuration


fixed android navbar for preloads

fixed android navbar for preloads

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/AppGyver/supersonic.git/'


Update current test instance AMI identifier

--- scripts/test-instance/instance-ami.coffee
+++ scripts/test-instance/instance-ami.coffee
@@ -1,7 +1,8 @@
 module.exports  =
-  current: 'ami-5dd50436'
+  current: 'ami-bf235ad5'

   # Ordered by creation date
   list: [
     'ami-5dd50436'
+    'ami-bf235ad5'
   ]


Use forum.postPosition()

Use forum.postPosition()

--- resources/assets/coffee/forum/topic-ajax.coffee
+++ resources/assets/coffee/forum/topic-ajax.coffee
@@ -45,7 +45,7 @@
   window.forum.setTotalPosts window.forum.totalPosts() + countDifference

   for post in window.forum.posts by -1
-    originalPosition = parseInt post.getAttribute('data-post-position'), 10
+    originalPosition = forum.postPosition(post)

     break if originalPosition < data.postPosition


Update config require

Update config require

--- spec/install-spec.coffee
+++ spec/install-spec.coffee
@@ -99,7 +99,7 @@

       describe "when the package is already in the cache", ->
         it "installs it from the cache", ->
-          cachePath = path.join(require('../lib/config').getPackageCacheDirectory(), 'test-module2', '2.0.0', 'package.tgz')
+          cachePath = path.join(require('../lib/apm').getPackageCacheDirectory(), 'test-module2', '2.0.0', 'package.tgz')
           testModuleDirectory = path.join(atomHome, 'packages', 'test-module2')

           callback = jasmine.createSpy('callback')


Add SendResponse test file

Add SendResponse test file

error: pathspec 'spec/SendResponse.coffee' did not match any file(s) known to git

--- spec/SendResponse.coffee
+++ spec/SendResponse.coffee
@@ -0,0 +1,36 @@
+noflo = require 'noflo'
+chai = require 'chai' unless chai
+SendResponse = require '../components/SendResponse.coffee'
+
+describe 'SendResponse component', ->
+  c = null
+  message = null
+  observe = null
+  response = null
+  start = null
+
+  beforeEach ->
+    c = SendResponse.getComponent()
+    message = noflo.internalSocket.createSocket()
+    observe = noflo.internalSocket.createSocket()
+    response = noflo.internalSocket.createSocket()
+    start = noflo.internalSocket.createSocket()
+    out = noflo.internalSocket.createSocket()
+
+    c.inPorts.message.attach message
+    c.inPorts.observe.attach observe
+    c.inPorts.response.attach response
+    c.inPorts.start.attach start
+    c.outPorts.out.attach out
+
+  describe 'when instantiated', ->
+    it 'should have a "message" inport', ->
+      chai.expect(c.inPorts.message).to.be.an 'object'
+    it 'should have a "observe" outport', ->
+      chai.expect(c.inPorts.observe).to.be.an 'object'
+    it 'should have a "response" inport', ->
+      chai.expect(c.inPorts.response).to.be.an 'object'
+    it 'should have a "start" outport', ->
+      chai.expect(c.inPorts.start).to.be.an 'object'
+    it 'should have a "out" outport', ->
+      chai.expect(c.outPorts.out).to.be.an 'object'


add main file

add main file

error: pathspec 'lib/atom-angularjs.coffee' did not match any file(s) known to git

--- lib/atom-angularjs.coffee
+++ lib/atom-angularjs.coffee
@@ -0,0 +1,6 @@
+module.exports =
+  activate: (state) ->
+    console.log('activate')
+
+  deactivate: ->
+    console.log('deactivate')


Fix atom.project.path deprecated called

Fix atom.project.path deprecated called

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/rafalprzywarski/test-status.git/'


Use directory symlink class

Use directory symlink class

--- lib/directory-view.coffee
+++ lib/directory-view.coffee
@@ -17,7 +17,7 @@
     @expand() if isExpanded

     if @directory.symlink
-      iconClass = 'icon-file-symlink-file'
+      iconClass = 'icon-file-symlink-directory'
     else
       iconClass = 'icon-file-directory'


Update routes for sidebar colors

Update routes for sidebar colors

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/jlgasparrini/sistema-legislativo-digital.git/'


Create jquery.disableSelection.coffee

Create jquery.disableSelection.coffee

error: pathspec 'jquery.disableSelection.coffee' did not match any file(s) known to git

--- jquery.disableSelection.coffee
+++ jquery.disableSelection.coffee
@@ -0,0 +1,4 @@
+( ($) ->
+    $.fn.disableSelection = ->
+        this.attr('unselectable', 'on').css('user-select', 'none').on('selectstart', false)
+)(jQuery)


added .coffee for messenger javascritp

added .coffee for messenger javascritp

error: pathspec 'app/assets/coffeescripts/messenger.coffee' did not match any file(s) known to git

--- app/assets/coffeescripts/messenger.coffee
+++ app/assets/coffeescripts/messenger.coffee
@@ -0,0 +1,12 @@
+###
+  messenger's coffee-script code
+###
+
+jQuery ->
+  jQuery(".messenger-off").click ->
+    jQuery(".messenger-off").hide()
+    jQuery(".messenger").show()
+
+  jQuery(".messenger .header").click ->
+    jQuery(".messenger").hide()
+    jQuery(".messenger-off").show()


start of download server

start of download server

 On branch master

	new file:   download_app/app/controllers/main.coffee

error: pathspec 'download_app/app/controllers/main.coffee' did not match any file(s) known to git

--- download_app/app/controllers/main.coffee
+++ download_app/app/controllers/main.coffee
@@ -0,0 +1 @@
+exports.controllers = (use, handler) ->


actually stop following after N redirects

--- server.coffee
+++ server.coffee
@@ -95,13 +95,15 @@
           when 301, 302
             if remaining_redirects <= 0
               four_oh_four(resp, "Exceeded max depth")
-            is_finished = false
-            newUrl = Url.parse srcResp.headers['location']
-            unless newUrl.host? and newUrl.hostname?
-              newUrl.host = newUrl.hostname = url.hostname
-              newUrl.protocol = url.protocol
+            else
+              is_finished = false
+              newUrl = Url.parse srcResp.headers['location']
+              unless newUrl.host? and newUrl.hostname?
+                newUrl.host = newUrl.hostname = url.hostname
+                newUrl.protocol = url.protocol

-            process_url newUrl, transferred_headers, resp, remaining_redirects - 1
+              console.log newUrl
+              process_url newUrl, transferred_headers, resp, remaining_redirects - 1
           when 304
             resp.writeHead srcResp.statusCode, newHeaders
           else


Adjustable content-length limit

Adjustable content-length limit

--- server.coffee
+++ server.coffee
@@ -11,6 +11,7 @@
 camo_hostname   = process.env.CAMO_HOSTNAME        || "unknown"
 logging_enabled = process.env.CAMO_LOGGING_ENABLED || "disabled"
 connect_timeout = process.env.CAMO_CONNECT_TIMEOUT || 10
+content_length_limit = parseInt(process.env.CAMO_LENGTH_LIMIT || 5242880, 10)

 debug_log = (msg) ->
   if logging_enabled == "debug"
@@ -73,7 +74,7 @@

       content_length = srcResp.headers['content-length']

-      if content_length > 5242880
+      if content_length > content_length_limit
         srcResp.destroy()
         four_oh_four(resp, "Content-Length exceeded", url)
       else


Add modification for disabling bracket-matcher package for latex.tex.text scope to config.cson

error: pathspec 'atom/bin/atom/config-modifications.cson' did not match any file(s) known to git

--- atom/bin/atom/config-modifications.cson
+++ atom/bin/atom/config-modifications.cson
@@ -0,0 +1,3 @@
+".latex.tex.text":
+  "bracket-matcher":
+    autocompleteCharacters: []


Revert "Merge branch 'master' of github.com:stevenbristol/turbolinks"

This reverts commit c85a02674e8ebfcdb0b5233837b32cbdbbf1ad29, reversing
changes made to 3b7b5c781e281b76413ab4efa401a90afbf7e4a4.

--- lib/assets/javascripts/turbolinks.js.coffee
+++ lib/assets/javascripts/turbolinks.js.coffee
@@ -155,14 +155,14 @@
 handleClick = (event) ->
   unless event.defaultPrevented
     link = extractLink event
-    if link?.nodeName is 'A' and !ignoreClick(event, link)
+    if link.nodeName is 'A' and !ignoreClick(event, link)
       visit link.href
       event.preventDefault()

 extractLink = (event) ->
   link = event.target
-  link = link.parentNode until link is document or !link or link.nodeName is 'A'
+  link = link.parentNode until link is document or link.nodeName is 'A'
   link

 samePageLink = (link) ->


fix IE8 crashes caused by calling document.addEventListener and document.createEvent

--- lib/assets/javascripts/turbolinks.js.coffee
+++ lib/assets/javascripts/turbolinks.js.coffee
@@ -10,7 +10,7 @@
 xhr            = null

-fetchReplacement = (url) ->
+fetchReplacement = (url) ->
   rememberReferer()
   cacheCurrentPage()
   triggerEvent 'page:fetch', url: url
@@ -269,13 +269,14 @@
   htmlExtensions

 installDocumentReadyPageEventTriggers = ->
-  document.addEventListener 'DOMContentLoaded', ( ->
-    triggerEvent 'page:change'
-    triggerEvent 'page:update'
-  ), true
+  if browserSupportsCustomEvents
+    document.addEventListener 'DOMContentLoaded', ( ->
+      triggerEvent 'page:change'
+      triggerEvent 'page:update'
+    ), true

 installJqueryAjaxSuccessPageUpdateTrigger = ->
-  if typeof jQuery isnt 'undefined'
+  if browserSupportsCustomEvents and typeof jQuery isnt 'undefined'
     jQuery(document).on 'ajaxSuccess', (event, xhr, settings) ->
       return unless jQuery.trim xhr.responseText
       triggerEvent 'page:update'
@@ -305,6 +306,9 @@
   popCookie('request_method') in ['GET','']

 browserSupportsTurbolinks = browserSupportsPushState and browserIsntBuggy and requestMethodIsSafe
+
+browserSupportsCustomEvents =
+  document.addEventListener and document.createEvent

 installDocumentReadyPageEventTriggers()
 installJqueryAjaxSuccessPageUpdateTrigger()


moved var declaration

moved var declaration

--- lib/assets/javascripts/turbolinks.js.coffee
+++ lib/assets/javascripts/turbolinks.js.coffee
@@ -1,9 +1,9 @@
-initialized  = false
-currentState = null
-referer      = document.location.href
-assets       = []
-pageCache    = []
-
+initialized    = false
+currentState   = null
+referer        = document.location.href
+assets         = []
+pageCache      = []
+createDocument = null

 visit = (url) ->
   if browserSupportsPushState
@@ -91,7 +91,7 @@

 rememberCurrentAssets = ->
   assets = extractAssets document
-
+
 rememberInitialPage = ->
   unless initialized
     rememberCurrentUrl()
@@ -127,8 +127,6 @@
   title = doc.querySelector 'title'
   [ title?.textContent, doc.body ]

-createDocument = null
-
 browserCompatibleDocumentParser = ->
   createDocumentUsingParser = (html) ->
     (new DOMParser).parseFromString html, 'text/html'


Documatic support

Documatic support

error: pathspec 'lib/view/documatic-view.coffee' did not match any file(s) known to git

--- lib/view/documatic-view.coffee
+++ lib/view/documatic-view.coffee
@@ -0,0 +1,32 @@
+{$, $$$, ScrollView} = require 'atom'
+url = require 'url'
+module.exports =
+class DocumaticView extends ScrollView
+  @content:  ->
+    @div class: 'ask-stack-result native-key-bindings', tabindex: -1, =>
+      #@div outlet:'Output'
+      @iframe outlet:'Src', width: '100%', height:'100%', frameborder:'0'
+
+
+
+  initialize:(uri) ->
+    url= uri.substr(25, uri.length)
+    @Src[0].src=url
+    #@content(namespace)
+    super
+  show: () ->
+    #@Output.html("")
+    #@Output.html("")
+  destroy: ->
+    @unsubscribe()
+
+  getTitle: ->
+    'documatic'
+
+  getUri: ->
+    'cache-studio://documatic-view'
+
+  getIconName: ->
+    'three-bars'
+
+  handleEvents: ->


Notification message

Notification message

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/GregDesplaces/classe-1914.git/'


xdescibed config spec

xdescibed config spec

error: pathspec 'test/integration/config-sent-spec.coffee' did not match any file(s) known to git

--- test/integration/config-sent-spec.coffee
+++ test/integration/config-sent-spec.coffee
@@ -0,0 +1,292 @@
+_              = require 'lodash'
+mongojs        = require 'mongojs'
+redis          = require 'ioredis'
+async          = require 'async'
+bcrypt         = require 'bcrypt'
+RedisNS        = require '@octoblu/redis-ns'
+
+TestDispatcher = require './test-dispatcher'
+JobManager     = require 'meshblu-core-job-manager'
+HydrantManager = require 'meshblu-core-manager-hydrant'
+
+xdescribe 'ConfigSent: send', ->
+  beforeEach (done) ->
+    @db            = mongojs 'meshblu-core-test'
+    @devices       = @db.collection 'devices'
+    @subscriptions = @db.collection 'subscriptions'
+    @uuidAliasResolver =
+      resolve: (uuid, callback) =>
+        callback null, uuid
+
+    @subscriptions.drop =>
+      @devices.drop =>
+        done()
+
+  beforeEach (done) ->
+    @redisUri = process.env.REDIS_URI
+    @dispatcher = new TestDispatcher
+    client = new RedisNS 'meshblu-test', redis.createClient(@redisUri)
+    client.del 'request:queue', done
+
+  beforeEach 'create sender device', (done) ->
+    @auth =
+      uuid: 'sender-uuid'
+      token: 'leak'
+
+    @senderDevice =
+      uuid: 'sender-uuid'
+      type: 'device:sender'
+      token: bcrypt.hashSync @auth.token, 8
+      meshblu:
+        version: '2.0.0'
+        whitelists:
+          config:
+            sent: 'spy-uuid': {}
+
+    @devices.insert @senderDevice, done
+
+  beforeEach 'create spy device', (done) ->
+    @spyDevice =
+      uuid: 'spy-uuid'
+      type: 'device:spy'
+      meshblu:
+        version: '2.0.0'
+        whitelists:
+          config:
+            received: 'nsa-uuid': {}
+
+    @devices.insert @spyDevice, done
+
+  beforeEach 'create nsa device', (done) ->
+    @nsaDevice =
+      uuid: 'nsa-uuid'
+      type: 'device:nsa'
+
+    @devices.insert @nsaDevice, done
+
+  context 'When sending a config message', ->
+    context "sender-uuid receiving its sent messages", ->
+      @timeout 5000
+      beforeEach 'create config sent subscription', (done) ->
+        subscription =
+          type: 'config.sent'
+          emitterUuid: 'sender-uuid'
+          subscriberUuid: 'sender-uuid'
+
+        @subscriptions.insert subscription, done
+
+      beforeEach 'create config received subscription', (done) ->
+        subscription =
+          type: 'config.received'
+          emitterUuid: 'sender-uuid'
+          subscriberUuid: 'sender-uuid'
+
+        @subscriptions.insert subscription, done
+
+      beforeEach 'create UpdateDevice job', (done) ->
+        doneTwice = _.after 2, done
+        job =
+          metadata:
+            auth: @auth
+            toUuid: 'sender-uuid'
+            jobType: 'UpdateDevice'
+          data:
+            $set:
+              foo: 'bar'
+
+        client = new RedisNS 'messages', redis.createClient(@redisUri)
+        @hydrant = new HydrantManager {client, @uuidAliasResolver}
+        @hydrant.connect uuid: @auth.uuid, (error) =>
+          return done(error) if error?
+
+          @hydrant.once 'message', (@message) =>
+            @hydrant.close()
+            doneTwice()
+
+          @dispatcher.generateJobs job, (error, @generatedJobs) => doneTwice()
+
+      it 'should deliver the sent config to the sender', ->
+        expect(@message).to.exist
+
+    context 'subscribed to someone elses sent configs', ->
+      @timeout 5000
+      beforeEach 'create config sent subscription', (done) ->
+        subscription =
+          type: 'config.sent'
+          emitterUuid: 'sender-uuid'
+          subscriberUuid: 'spy-uuid'
+
+        @subscriptions.insert subscription, done
+
+      beforeEach 'create config received subscription', (done) ->
+        subscription =
+          type: 'config.received'
+          emitterUuid: 'spy-uuid'
+          subscriberUuid: 'spy-uuid'
+
+        @subscriptions.insert subscription, done
+
+      beforeEach (done) ->
+        doneTwice = _.after 2, done
+        job =
+          metadata:
+            auth: @auth
+            toUuid: 'sender-uuid'
+            jobType: 'UpdateDevice'
+          data:
+            $set:
+              foo: 'bar'
+
+        client = new RedisNS 'messages', redis.createClient(@redisUri)
+        @hydrant = new HydrantManager {client, @uuidAliasResolver}
+        @hydrant.connect uuid: 'spy-uuid', (error) =>
+          return done(error) if error?
+
+          @hydrant.once 'message', (@message) =>
+            @hydrant.close()
+            doneTwice()
+
+          @dispatcher.generateJobs job, (error, @generatedJobs) => doneTwice()
+
+      it 'should deliver the sent config to the receiver', ->
+        expect(@message).to.exist
+
+    context 'subscribed to someone elses sent config, but is not authorized', ->
+      @timeout 5000
+      beforeEach 'create config sent subscription', (done) ->
+        subscription =
+          type: 'config.sent'
+          emitterUuid: 'sender-uuid'
+          subscriberUuid: 'nsa-uuid'
+
+        @subscriptions.insert subscription, done
+
+      beforeEach 'create broadcast received subscription', (done) ->
+        subscription =
+          type: 'config.received'
+          emitterUuid: 'nsa-uuid'
+          subscriberUuid: 'nsa-uuid'
+
+        @subscriptions.insert subscription, done
+
+      beforeEach (done) ->
+        job =
+          metadata:
+            auth: @auth
+            toUuid: 'sender-uuid'
+            jobType: 'UpdateDevice'
+          data:
+            $set:
+              foo: 'bar'
+
+        client = new RedisNS 'messages', redis.createClient(@redisUri)
+        @hydrant = new HydrantManager {client, @uuidAliasResolver}
+        @hydrant.connect uuid: 'nsa-uuid', (error) =>
+          return done(error) if error?
+
+          @hydrant.once 'message', (@message) => @hydrant.close()
+
+          @dispatcher.generateJobs job, (error, @generatedJobs) =>
+            setTimeout done, 2000
+
+      it 'should not deliver the sent config to the receiver', ->
+        expect(@message).to.not.exist
+
+    context 'subscribed to someone elses received config', ->
+      @timeout 5000
+      beforeEach 'create config sent subscription', (done) ->
+        subscription =
+          type: 'config.sent'
+          emitterUuid: 'sender-uuid'
+          subscriberUuid: 'spy-uuid'
+
+        @subscriptions.insert subscription, done
+
+      beforeEach 'create config received subscription', (done) ->
+        subscription =
+          type: 'config.received'
+          emitterUuid: 'spy-uuid'
+          subscriberUuid: 'nsa-uuid'
+
+        @subscriptions.insert subscription, done
+
+      beforeEach 'create config received subscription', (done) ->
+        subscription =
+          type: 'config.received'
+          emitterUuid: 'nsa-uuid'
+          subscriberUuid: 'nsa-uuid'
+
+        @subscriptions.insert subscription, done
+
+      beforeEach (done) ->
+        doneTwice = _.after 2, done
+        job =
+          metadata:
+            auth: @auth
+            toUuid: 'sender-uuid'
+            jobType: 'UpdateDevice'
+          data:
+            $set:
+              foo: 'bar'
+
+        client = new RedisNS 'messages', redis.createClient(@redisUri)
+        @hydrant = new HydrantManager {client, @uuidAliasResolver}
+        @hydrant.connect uuid: 'nsa-uuid', (error) =>
+          return done(error) if error?
+
+          @hydrant.once 'message', (@message) =>
+            @hydrant.close()
+            doneTwice()
+
+          @dispatcher.generateJobs job, (error, @generatedJobs) => doneTwice()
+
+      it 'should deliver the sent config to the receiver', ->
+        expect(@message).to.exist
+
+    context 'subscribed to someone elses received configs, but is not authorized', ->
+      @timeout 5000
+      beforeEach 'create config sent subscription', (done) ->
+        subscription =
+          type: 'config.sent'
+          emitterUuid: 'sender-uuid'
+          subscriberUuid: 'spy-uuid'
+
+        @subscriptions.insert subscription, done
+
+      beforeEach 'create config received subscription', (done) ->
+        subscription =
+          type: 'config.received'
+          emitterUuid: 'spy-uuid'
+          subscriberUuid: 'nsa-uuid'
+
+        @subscriptions.insert subscription, done
+
+      beforeEach 'create config received subscription', (done) ->
+        subscription =
+          type: 'config.received'
+          emitterUuid: 'nsa-uuid'
+          subscriberUuid: 'nsa-uuid'
+
+        @subscriptions.insert subscription, done
+
+      beforeEach (done) ->
+        job =
+          metadata:
+            auth: @auth
+            toUuid: 'sender-uuid'
+            jobType: 'UpdateDevice'
+          data:
+            $set:
+              foo: 'bar'
+
+        client = new RedisNS 'messages', redis.createClient(@redisUri)
+        @hydrant = new HydrantManager {client, @uuidAliasResolver}
+        @hydrant.connect uuid: 'spy-uuid', (error) =>
+          return done(error) if error?
+          @hydrant.once 'message', (@message) => @hydrant.close()
+
+          @dispatcher.generateJobs job, (error, @generatedJobs) =>
+            setTimeout done, 2000
+
+      it 'should not deliver the sent message to the receiver', ->
+        expect(@message).to.not.exist


Add Coffeescript version of rasterize.js.

error: pathspec 'examples/rasterize.coffee' did not match any file(s) known to git

--- examples/rasterize.coffee
+++ examples/rasterize.coffee
@@ -0,0 +1,21 @@
+if phantom.state.length is 0
+    if phantom.args.length < 2 or phantom.args.length > 3
+        console.log 'Usage: rasterize.js URL filename [paperwidth*paperheight|paperformat]'
+        console.log '  paper (pdf output) examples: "5in*7.5in", "10cm*20cm", "A4", "Letter"'
+        phantom.exit()
+    else
+        address = phantom.args[0]
+        phantom.state = 'rasterize'
+        phantom.viewportSize = { width: 600, height: 600 }
+        if phantom.args.length is 3 and phantom.args[1].substr(-4) is ".pdf"
+            size = phantom.args[2].split '*'
+            if size.length is 2
+                phantom.paperSize = { width: size[0], height: size[1], border: '0px' }
+            else
+                phantom.paperSize = { format: phantom.args[2], orientation: 'portrait', border: '1cm' }
+        phantom.open(address)
+else
+    output = phantom.args[1]
+    phantom.sleep 200
+    phantom.render output
+    phantom.exit()