add acl-generator

add acl-generator

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

--- src/lib/acl-generator.coffee
+++ src/lib/acl-generator.coffee
@@ -0,0 +1,166 @@
+
+
+###*
+generate ACL
+ACL is Array of access control information
+
+@class AclGenerator
+###
+class AclGenerator
+
+    constructor: (@modelSetting) ->
+        @acl = []
+
+
+    ###*
+    get ACL by aclType
+
+    @method generateByType
+    @public
+    @param {String} aclType
+    return {Array} ACL
+    ###
+    generateByType: (aclType) ->
+
+        aclType ?= 'admin'
+
+        switch aclType
+
+            when 'admin'
+                @adminACL()
+
+            when 'owner'
+                @ownerACL()
+
+            when 'public-read'
+                @publicReadACL()
+
+            else
+                throw new Error """unknown aclType: #{aclType}"""
+
+        return @acl
+
+
+    ###*
+    append ACL allowing accesses only from admin
+
+    @method adminACL
+    @private
+    ###
+    adminACL: ->
+        @commonACL()
+
+        if @modelSetting.isUserModel()
+            @adminUserACL()
+
+
+
+    ###*
+    append ACL allowing accesses from the accessToken of model's owners
+
+    @method ownerACL
+    @private
+    ###
+    ownerACL: ->
+
+        @commonACL()
+
+        accessTypes = ['READ', 'WRITE', 'EXECUTE']
+
+        for accessType in accessTypes
+            @acl.push
+                accessType: accessType
+                principalType: 'ROLE'
+                principalId: '$owner'
+                permission: 'ALLOW'
+
+
+    ###*
+    append ACL allowing accesses from READ access to everyone
+
+    @method publicReadACL
+    @private
+    ###
+    publicReadACL: ->
+        @commonACL()
+        @acl.push
+            accessType: 'READ'
+            principalType: 'ROLE'
+            principalId: '$everyone'
+            permission: 'ALLOW'
+
+
+    ###*
+    append basic ACL, which allow accesses only from admin
+
+    @method commonACL
+    @private
+    ###
+    commonACL: ->
+        # set everyone access denied and admin access allowed
+        @acl.push
+            accessType: '*'
+            principalType: 'ROLE'
+            principalId: '$everyone'
+            permission: 'DENY'
+
+        @acl.push
+            accessType: '*'
+            principalType: 'ROLE'
+            principalId: 'admin'
+            permission: 'ALLOW'
+
+        if @modelSetting.isUserModel()
+            @userACL()
+
+
+    ###*
+    append ACL for User model
+
+    @method userACL
+    @private
+    ###
+    userACL: ->
+        # admin cannot logout. avoid CSRF attacks which make admin logout.
+        @acl.push
+            accessType: 'EXECUTE'
+            principalType: 'ROLE'
+            principalId: 'admin'
+            permission: 'DENY'
+            property: 'logout'
+
+        # user creation is denied by default.
+        @acl.push
+            accessType: 'WRITE'
+            principalType: 'ROLE'
+            principalId: '$everyone'
+            permission: 'DENY'
+            property: 'create'
+
+
+    ###*
+    append ACL for User model handled by admin,
+    denying login from everyone. Login must be executed via admin access.
+
+    @method adminUserACL
+    @private
+    ###
+    adminUserACL: ->
+        # login is denied by default
+        @acl.push
+            accessType: 'EXECUTE'
+            principalType: 'ROLE'
+            principalId: '$everyone'
+            permission: 'DENY'
+            property: 'login'
+
+        @acl.push
+            accessType: 'EXECUTE'
+            principalType: 'ROLE'
+            principalId: 'admin'
+            permission: 'ALLOW'
+            property: 'login'
+
+
+
+module.exports = AclGenerator


Create he.js.coffee

Create he.js.coffee

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/prognostikos/uploadcare-widget.git/'


Create tr.js.coffee

Create tr.js.coffee

Turkish localization for the widget.

error: pathspec 'app/assets/javascripts/uploadcare/locale/tr.js.coffee' did not match any file(s) known to git

--- app/assets/javascripts/uploadcare/locale/tr.js.coffee
+++ app/assets/javascripts/uploadcare/locale/tr.js.coffee
@@ -0,0 +1,106 @@
+# Note: Turkish locale by fiatux.com
+uploadcare.namespace 'uploadcare.locale.translations', (ns) ->
+  ns.tr =
+    uploading: 'Yükleniyor... Lütfen bekleyin.'
+    loadingInfo: 'Bilgiler yükleniyor...'
+    errors:
+      default: 'Hata'
+      baddata: 'Geçersiz değer'
+      size: 'Dosya çok büyük'
+      upload: 'Yüklenemedi'
+      user: 'Yükleme iptal edildi'
+      info: 'Bilgiler getirilemedi'
+      image: 'Sadece resim dosyası yüklenebilir'
+      createGroup: 'Dosya grubu yaratılamıyor'
+      deleted: 'Dosya silinmiş'
+    draghere: 'Buraya bir dosya bırakın'
+    file:
+      one: '%1 dosya'
+      other: '%1 dosya'
+    buttons:
+      cancel: 'İptal'
+      remove: 'Kaldır'
+      choose:
+        files:
+          one: 'Dosya Seçin'
+          other: 'Dosya Seçin'
+        images:
+          one: 'Resim Dosyası Seçin'
+          other: 'Resim Dosyası Seçin'
+    dialog:
+      done: 'Bitti'
+      showFiles: 'Dosyaları Göster'
+      tabs:
+        file:
+          drag: 'Braya bir dosya bakın'
+          nodrop: 'Bilgisayarınızdan dosya yükleyin'
+          or: 'or'
+          button: 'Bilgisayardan bir dosya seç'
+          also: 'Diğer yükleme seçenekleri'
+          tabNames:
+            facebook: 'Facebook'
+            dropbox: 'Dropbox'
+            gdrive: 'Google Drive'
+            instagram: 'Instagram'
+            vk: 'VK'
+            evernote: 'Evernote'
+            box: 'Box'
+            skydrive: 'SkyDrive'
+            url: 'Dış Bağlantılar'
+        url:
+          title: 'Webden dosyalar'
+          line1: 'Webden herhangi bir dosya seçin.'
+          line2: 'Dosya bağlantısını sağlayın.'
+          input: 'Bağlantınızı buraya yapıştırın...'
+          button: 'Yükle'
+        preview:
+          unknownName: 'bilinmeyen'
+          change: 'İptal'
+          back: 'Geri'
+          done: 'Ekle'
+          unknown:
+            title: 'Yükleniyor... Önizleme için lütfen bekleyin.'
+            done: 'Önizlemeyi geç ve kabul et'
+          regular:
+            title: 'Bu dosya eklensin mi?'
+            line1: 'Yukarıdaki dosyayı eklemek üzeresiniz.'
+            line2: 'Lütfen onaylayın.'
+          image:
+            title: 'Bu görsel eklensin mi?'
+            change: 'İptal'
+          crop:
+            title: 'Bu görseli kes ve ekle'
+            done: 'Bitti'
+          error:
+            default:
+              title: 'Aman!'
+              text: 'Yükleme sırasında bir hata oluştu.'
+              back: 'Lütfen tekrar deneyin.'
+            image:
+              title: 'Sadece resim dosyaları kabul edilmektedir.'
+              text: 'Lütfen başka bir dosya ile tekrar deneyin.'
+              back: 'Resim dosyası seç'
+            size:
+              title: 'Seçtiğiniz dosya limitleri aşıyor.'
+              text: 'Lütfen başka bir dosya ile tekrar deneyin.'
+          multiple:
+            title: '%files% dosya seçtiniz'
+            question: 'Bu dosyaların hepsini eklemek istiyor musunuz?'
+            tooManyFiles: 'Fazla sayıda dosya seçtiniz, en fazla %max% dosya olabilir.'
+            tooFewFiles: '%files% dosya seçtiniz, en az %min% dosya olmalıdır.'
+            clear: 'Hepsini kaldır'
+            done: 'Bitti'
+      footer:
+        text: 'Dosya yükleme, saklama ve işleme servisi'
+        link: 'Uploadcare.com'
+    crop:
+      error:
+        title: 'Hata'
+        text: 'Resim dosyası yüklenemedi'
+      done: 'Bitti'
+
+
+uploadcare.namespace 'uploadcare.locale.pluralize', (ns) ->
+  ns.tr = (n) ->
+    return 'one' if n == 1
+    'other'


Actually fixes bug and improves pageview reporting

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/jhabdas/hopstop.git/'


chartkick update

chartkick update

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/patleb/admineer.git/'


env is a property, not a var of its own.

--- src/application.coffee
+++ src/application.coffee
@@ -69,7 +69,7 @@
 			Cmd: ['/bin/bash', '-c', '/start']
 			Volumes:
 				'/dev': {}
-			Env: env
+			Env: app.env
 		)
 	.then (container) ->
 		console.log('Starting container:', app.imageId)


do not close select list only if left click


ckeditor

ckeditor

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/juanfgs/eoswebdevelopment.git/'


Add consolidate task

Add consolidate task

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

--- grunt/consolidate.coffee
+++ grunt/consolidate.coffee
@@ -0,0 +1,9 @@
+module.exports =
+  options:
+    engine: 'handlebars'
+  test:
+    options:
+      local:
+        script: 'spec/base'
+    files:
+      'test/browser/base.html': 'test/templates/browser.html'


Delete dummy text

Delete dummy text

--- app/profile.cjsx
+++ app/profile.cjsx
@@ -47,7 +47,6 @@
   render: ->
     if @props.user?

-
Yo, {@props.user.display_name}!

Your favourites

             {
<Thumbnail subject={favourite} />
 for favourite in @state.favourites}


buttonwithmenu: closing portal is handled by isOpened props

--- client/app/lib/components/buttonwithmenu/index.coffee
+++ client/app/lib/components/buttonwithmenu/index.coffee
@@ -17,10 +17,18 @@
     menuClassName:''

+  constructor: (props) ->
+
+    super props
+
+    @state = { isMenuOpen : null }
+
+
   renderListMenu: ->

     onClick = (item) => (event) =>
       item.onClick event
+      @setState { isMenuOpen: false }

     @props.items.map (item) ->

{item.title}


[fix] [web] Fixed crashing when no dashboardPagePlugin elements are available

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/'


apparently db.stats.objects isn't the actual document count...

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/phillips1012/pasteHTML.git/'


Do not grab back focus if Vimium is disabled.

--- content_scripts/vimium_frontend.coffee
+++ content_scripts/vimium_frontend.coffee
@@ -149,7 +149,6 @@
   new NormalMode
   new PassKeysMode
   new InsertMode permanent: true
-  new GrabBackFocus
   Scroller.init settings

 #
@@ -159,6 +158,8 @@
   settings.addEventListener("load", LinkHints.init.bind(LinkHints))
   settings.load()

+  # Note. checkIfEnabledForUrl() must come after initializeModes(), here, because checkIfEnabledForUrl() may
+  # install an additional mode (GrabBackFocus).
   initializeModes()
   checkIfEnabledForUrl()
   refreshCompletionKeys()
@@ -229,7 +230,9 @@
       do (type) -> installListener window, type, (event) -> handlerStack.bubbleEvent type, event
     installListener document, "DOMActivate", (event) -> handlerStack.bubbleEvent 'DOMActivate', event
     installedListeners = true
+    # Other one-time initialization operations.
     FindModeHistory.init()
+    new GrabBackFocus if isEnabledForUrl

 #
 # Whenever we get the focus:


Fix regex searching.

Fix regex searching.

--- content_scripts/vimium_frontend.coffee
+++ content_scripts/vimium_frontend.coffee
@@ -585,7 +585,7 @@
   # sequentially so the browser handles the scrolling / text selection.
   if findModeQuery.isRegex
     try
-      pattern = new RegExp(findModeQuery.parsedQuery, "g" + (findModeQuery.ignoreCase ? "i" : ""))
+      pattern = new RegExp(findModeQuery.parsedQuery, "g" + (if findModeQuery.ignoreCase then "i" else ""))
     catch error
       # if we catch a SyntaxError, assume the user is not done typing yet and return quietly
       return


Fixed missing @

Fixed missing @

--- src/index.coffee
+++ src/index.coffee
@@ -87,7 +87,7 @@
       for file in fs.readdirSync(path)
         fullPath = sysPath.join path, file
         if fs.statSync(fullPath).isDirectory()
-          res = res.concat readdirRecursiveSync(fullPath, filterFunc)
+          res = res.concat @readdirRecursiveSync(fullPath, filterFunc)
         else if filterFunc(file, path)
           res.push fullPath
       res


Remove bot name from guild listing

Remove bot name from guild listing

remote: Repository unavailable due to DMCA takedown.
remote: See the takedown notice for more details:
remote:   https://github.com/github/dmca/blob/master/2018/2018-09-28-TeraPC.md.
fatal: unable to access 'https://github.com/meishuu/tera-discord-relay.git/': The requested URL returned error: 403


Fix tests

Fix tests

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/osokay/IotServerCore.git/'


Refactoring to follow testing convetions in this codebase

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/CrowdTwist/widgets-js-sdk.git/'


Fix PropTypes check + code check (again)

--- src/index.cjsx
+++ src/index.cjsx
@@ -8,17 +8,17 @@
   propTypes:
     spinnerName: React.PropTypes.string.isRequired
     noFadeIn: React.PropTypes.bool
-    overrideSpinnerClassName: React.PropTypes.bool
+    overrideSpinnerClassName: React.PropTypes.string

   getDefaultProps: ->
     spinnerName: 'three-bounce'
     noFadeIn: false
-    overrideSpinnerClassName: false
+    overrideSpinnerClassName: ""

   render: ->
     classTests = {
       "fade-in": not @props.noFadeIn
-      spinner: not @props.overrideSpinnerClassName
+      spinner: @props.overrideSpinnerClassName is ""
     }
     classTests[@props.overrideSpinnerClassName] = @props.overrideSpinnerClassName
     classes = cx(classTests)


It always has abort() if not null

It always has abort() if not null

--- resources/assets/coffee/react/beatmap-discussions/main.coffee
+++ resources/assets/coffee/react/beatmap-discussions/main.coffee
@@ -71,7 +71,7 @@
     $.unsubscribe '.beatmapDiscussions'

     Timeout.clear @checkNewTimeout
-    @checkNewAjax?.abort?()
+    @checkNewAjax?.abort()

   render: ->


Adds `ensureLoggedOut` middleware

Adds `ensureLoggedOut` middleware

error: pathspec 'lib/middleware/ensure_logged_out.coffee' did not match any file(s) known to git

--- lib/middleware/ensure_logged_out.coffee
+++ lib/middleware/ensure_logged_out.coffee
@@ -0,0 +1,3 @@
+module.exports = (req, res, next) ->
+  return res.redirect('/') if req.user?.id
+  next()


im rock james...bitch

im rock james...bitch

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

--- scripts/rick.coffee
+++ scripts/rick.coffee
@@ -0,0 +1,17 @@
+# Rick James
+#
+#
+#
+module.exports = (robot) ->
+  robot.hear /(rick)/i, (msg) ->
+    imageMe msg
+
+imageMe = (msg) ->
+  msg.http('http://ajax.googleapis.com/ajax/services/search/images')
+    .query(v: "1.0", rsz: '8', q: 'rick james')
+    .get() (err, res, body) ->
+      images = JSON.parse(body)
+      images = images.responseData.results
+      if images.length > 0
+          image = msg.random images
+          msg.send "#{image.unescapedUrl}#.png"


Update test environment AMI

Update test environment AMI

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/'


Add EnvironmentMainScene

Add EnvironmentMainScene

error: pathspec 'client/landing/app/Applications/Environments.kdapplication/views/environmentsmainscene.coffee' did not match any file(s) known to git

--- client/landing/app/Applications/Environments.kdapplication/views/environmentsmainscene.coffee
+++ client/landing/app/Applications/Environments.kdapplication/views/environmentsmainscene.coffee
@@ -0,0 +1,76 @@
+class EnvironmentsMainScene extends JView
+
+  constructor:(options={}, data)->
+    options.cssClass = KD.utils.curry 'environment-content', options.cssClass
+    super options, data
+
+  viewAppended:->
+
+    # Action Area for Domains
+    @addSubView actionArea = new KDView cssClass : 'action-area'
+
+    # Domain Creation form in actionArea
+    actionArea.addSubView @domainCreateForm = new DomainCreationForm
+
+    # Domain Creation form connections
+    @domainCreateForm.on 'CloseClicked', =>
+      @scene.unsetClass 'out'
+      @scene.off "click"
+
+    # Main scene for DIA
+    @addSubView @scene = new EnvironmentScene
+
+    # Domains Container
+    domainsContainer = new EnvironmentDomainContainer
+    @scene.addContainer domainsContainer
+    domainsContainer.on "itemRemoved", @domainCreateForm.bound "updateDomains"
+
+    # VMs / Machines Container
+    machinesContainer = new EnvironmentMachineContainer
+    @scene.addContainer machinesContainer
+
+    @_containers = [domainsContainer, machinesContainer]
+    for container in @_containers
+      container.on 'DataLoaded', @scene.bound 'updateConnections'
+
+    @refreshContainers()
+
+    @domainCreateForm.on 'DomainSaved', domainsContainer.bound 'loadItems'
+    KD.getSingleton("vmController").on 'VMListChanged', \
+                                        @bound 'refreshContainers'
+
+    # Plus button on domainsContainer opens up the action area
+    domainsContainer.on 'PlusButtonClicked', =>
+      return unless KD.isLoggedIn()
+        new KDNotificationView title: "You need to login to add a new domain."
+
+      return if machinesContainer.diaCount() is 0
+        new KDNotificationView
+          title: "You need to have at least one VM to manage domains."
+
+      @scene.setClass 'out'
+      @domainCreateForm.emit 'DomainNameShouldFocus'
+      @utils.defer =>
+        @scene.once 'click', => @domainCreateForm.emit 'CloseClicked'
+
+    vmController = KD.getSingleton 'vmController'
+
+    vmController.on "VMPlansFetchStart", =>
+      machinesContainer.showLoader()
+
+    vmController.on "VMPlansFetchEnd", =>
+      machinesContainer.hideLoader()
+
+    # Plus button on machinesContainer uses the vmController
+    machinesContainer.on 'PlusButtonClicked', =>
+      return unless KD.isLoggedIn()
+        new KDNotificationView
+          title: "You need to login to create a new machine."
+
+      vmController.createNewVM()
+
+  refreshContainers:->
+    # After Domains and Machines container load finished
+    # Call updateConnections to draw lines between corresponding objects
+    @scene.whenItemsLoadedFor @_containers, =>
+      @scene.updateConnections()


Conceptualize a static caching pattern.

Conceptualize a static caching pattern.

[#57874256]

--- client/helpers/payments.coffee
+++ client/helpers/payments.coffee
@@ -20,6 +20,11 @@
 Template.payment.amount = ->
   accounting.formatMoney @amount

+# TODO: Statically cache expenses and incomes in this context to avoid
+# some lookups
+# Think about if the cache might be sticky in ways I don't want
+
+paymentExpenses = {}
 Template.payment.expense = ->
   if @expenseId
     expense = Expenses.findOne @expenseId
@@ -29,6 +34,7 @@
       expense
     else {}

+paymentIncomes = {}
 Template.payment.income = ->
   if @incomeId
     income = Incomes.findOne @incomeId


Allow operations to be added to a PathView

--- src/packages/command-panel/lib/path-view.coffee
+++ src/packages/command-panel/lib/path-view.coffee
@@ -5,18 +5,16 @@

 module.exports =
 class PathView extends View
-  @content: ({path, operations, previewList} = {}) ->
+  @content: ({path, previewList} = {}) ->
     classes = ['path']
     classes.push('readme') if fs.isReadmePath(path)
     @li class: classes.join(' '), =>
       @div outlet: 'pathDetails', class: 'path-details', =>
         @span class: 'path-name', path
-        @span "(#{operations.length})", class: 'path-match-number'
+        @span outlet: 'description', class: 'path-match-number'
       @ul outlet: 'matches', class: 'matches', =>
-        for operation in operations
-          @subview "operation#{operation.index}", new OperationView({operation, previewList})

-  initialize: ({@previewList}) ->
+  initialize: ({operations, @previewList}) ->
     @pathDetails.on 'mousedown', => @toggle(true)
     @subscribe @previewList, 'command-panel:collapse-result', =>
       @collapse(true) if @isSelected()
@@ -26,6 +24,12 @@
       if @hasClass('selected')
         @toggle(true)
         false
+
+    @addOperation(operation) for operation in operations
+
+  addOperation: (operation) ->
+    @matches.append new OperationView({operation, @previewList})
+    @description.text("(#{@matches.find('li').length})")

   isSelected: ->
     @hasClass('selected') or @find('.selected').length


Invoke the jasmine from node_modules.

Invoke the jasmine from node_modules.

--- Gruntfile.coffee
+++ Gruntfile.coffee
@@ -45,7 +45,7 @@
           failOnError: true

       test:
-        command: 'jasmine-focused --captureExceptions --forceexit --coffee spec/'
+        command: 'node node_modules/jasmine-focused/bin/jasmine-focused --captureExceptions --forceexit --coffee spec/'
         options:
           stdout: true
           stderr: true


Update some test browser versions

Update some test browser versions

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/seedtigo/engine.git/'


Add PORT env var support

Add PORT env var support

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/leandrooriente/racha-conta.git/'


tell the broker to not expect acks

tell the broker to not expect acks

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/'


Split publish into its two components

Split publish into its two components

--- lib/publishConfig.coffee
+++ lib/publishConfig.coffee
@@ -3,6 +3,7 @@
 Publisher = require './Publisher'
 SimpleAuth = require './SimpleAuth'

+PUBLISHER = new Publisher namespace: 'meshblu'
 Device = null #circular dependencies are awesome.

 class PublishConfig
@@ -12,15 +13,12 @@
     @forwardedFor = _.union @forwardedFor, [@uuid]

   publish: (callback) =>
-    publisher = new Publisher namespace: 'meshblu'
-    publisher.publish 'config', @uuid, @config, (error) =>
-      return callback error if error?
-      @fetchDevice @uuid, (error, device) =>
-        return callback error if error?
-        configForward = device?.meshblu?.configForward ? []
-        async.eachSeries configForward, @forwardPublish, callback
+    async.series [@doPublish, @forwardPublishToDevices], callback

   # Private(ish) methods
+  doPublish: (callback) =>
+    PUBLISHER.publish 'config', @uuid, @config, callback
+
   fetchDevice: (uuid, callback) =>
     device = new Device {uuid}, {@database}
     device.fetch (error, result) =>
@@ -48,6 +46,14 @@
         forwardedFor: @forwardedFor
       publishConfig.publish callback

+  forwardPublishToDevices: (callback) =>
+    @fetchDevice @uuid, (error, device) =>
+      return callback error if error?
+      return callback null unless device? and device.meshblu?
+
+      configForward = device.meshblu.configForward ? []
+      async.eachSeries configForward, @forwardPublish, callback
+
   shouldSend: ({fromUuid, toUuid}, callback) =>
     return callback null, false if _.contains @forwardedFor, toUuid


fix live update mode

fix live update mode

--- app/assets/javascripts/rails_admin/rails_admin_nestable.js.coffee
+++ app/assets/javascripts/rails_admin/rails_admin_nestable.js.coffee
@@ -25,7 +25,7 @@
   $tree_nodes_max_depth = $tree_nodes.data('max-depth')
   $live_update = $('#rails_admin_nestable input[type=checkbox]')
   $update_button = $('#rails_admin_nestable button')
-  live_update_mode = ($live_update.prop('checked') == undefined) ? true : false
+  live_update_mode = if (!$live_update.length && !$update_button.length) then true else $live_update.prop('checked')
   $('#rails_admin_nestable button').prop('disabled', $live_update.prop('checked'))

   $live_update.change ->


Disconnect socket on rateLimit exceeded

Disconnect socket on rateLimit exceeded

--- lib/MeshbluWebsocketHandler.coffee
+++ lib/MeshbluWebsocketHandler.coffee
@@ -51,7 +51,7 @@
       return @sendError error.message, event.data if error?

       @rateLimit @socket.id, type, (error) =>
-        return @sendError error.message, event.data, 429 if error?
+        return @closeWithError error, [type,data], 429 if error?
         return @emit type, data if type == 'identity'

         @authDevice @uuid, @token, (error, authedDevice)=>
@@ -59,6 +59,10 @@
           @authedDevice = authedDevice

           @emit type, data
+
+  closeWithError: (error, frame, code) =>
+    @sendError error.message, frame, 429
+    @socket.close 429, error.message

   # message handlers
   device: (data) =>
@@ -172,9 +176,11 @@

   rateLimit: (id, type, callback=->) =>
     throttle = @throttles[type] ? @throttles.query
+
     callback() unless throttle?
     throttle.rateLimit id, (error, isLimited) =>
       debug 'rateLimit', id, type, isLimited
+
       return callback error if error?
       return callback new Error('request exceeds rate limit') if isLimited
       callback()
@@ -238,4 +244,6 @@
   onSocketData: (data) =>
     @sendFrame 'data', data

+
+
 module.exports = MeshbluWebsocketHandler


landing: teams: added a create with already member form


Fixed: notification was not sent by email if set on 'BOTH'. Close #179

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/clochix/cozy-home.git/'


missed a file to fix

missed a file to fix

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/0xenvision/negotiator-inator.git/'


Make web component drawers reacting on CSS visibility changes

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/'


Delete badly authenticated users.

Delete badly authenticated users.

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/philbooth/GitHubReminder.git/'


ask if a required parameter is missing

ask if a required parameter is missing

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/'


coffee-linter installed no more guess work

--- src/beautifiers/puppet-fix.coffee
+++ src/beautifiers/puppet-fix.coffee
@@ -24,9 +24,9 @@
       '--fix'
       tempFile = @tempFile("input", text)
       ], {
-        ignoreReturnCode: true
-        help: {
-          link: "http://puppet-lint.com/"
+      ignoreReturnCode: true
+      help: {
+        link: "http://puppet-lint.com/"
         }
       })
       .then(=>


add bill model

add bill model

error: pathspec 'server/models/bill.coffee' did not match any file(s) known to git

--- server/models/bill.coffee
+++ server/models/bill.coffee
@@ -0,0 +1,14 @@
+cozydb = require 'cozydb'
+
+module.exports = Bill = cozydb.getModel 'Bill',
+    type: type: String, default: 'hosting'
+    date: Date
+    vendor: type: String, default: 'Digital Ocean'
+    amount: Number
+    plan: String
+    fileId: String
+
+
+Bill.all = (callback) ->
+    Bill.request 'byDate', callback
+


hide badge if 0 count

hide badge if 0 count

--- resources/assets/coffee/react/_components/playmode-tabs.coffee
+++ resources/assets/coffee/react/_components/playmode-tabs.coffee
@@ -39,7 +39,9 @@
             'data-mode': mode
             'data-disabled': disabled
             osu.trans "beatmaps.mode.#{mode}"
-            span className: 'page-mode-link__badge', _.size(@props.beatmaps[mode]) if @props.showCounts
+            if @props.showCounts
+              count = _.size(@props.beatmaps[mode])
+              span className: 'page-mode-link__badge', count if count > 0
             span className: 'page-mode-link__stripe'


Modify navigation event to use WindowFacade


Fix attachment upload link bug caused by introduction of zen mode.

--- app/assets/javascripts/markdown_area.js.coffee
+++ app/assets/javascripts/markdown_area.js.coffee
@@ -12,13 +12,13 @@
   btnAlert = "<button type=\"button\"" + alertAttr + ">×</button>"
   project_image_path_upload = window.project_image_path_upload or null

-  $("textarea.markdown-area").wrap "

"
-
+  $("textarea.markdown-area").wrap "

"
+
   $(".div-dropzone").parent().addClass "div-dropzone-wrapper"

   $(".div-dropzone").append divHover
   $(".div-dropzone-hover").append iconPicture
-  $(".div-dropzone").append divSpinner
+  $(".div-dropzone").append divSpinner
   $(".div-dropzone-spinner").append iconSpinner
   $(".div-dropzone-spinner").css
     "opacity": 0
@@ -27,12 +27,12 @@
   dropzone = $(".div-dropzone").dropzone(
     url: project_image_path_upload
     dictDefaultMessage: ""
-    clickable: false
+    clickable: true
     paramName: "markdown_img"
     maxFilesize: 10
     uploadMultiple: false
     acceptedFiles: "image/jpg,image/jpeg,image/gif,image/png"
-    headers:
+    headers:
       "X-CSRF-Token": $("meta[name=\"csrf-token\"]").attr("content")

     previewContainer: false
@@ -91,7 +91,7 @@
   handlePaste = (e) ->
     e.preventDefault()
     my_event = e.originalEvent
-
+
     if my_event.clipboardData and my_event.clipboardData.items
       processItem(my_event)

@@ -115,7 +115,7 @@
         return item
       i++
     return false
-
+
   pasteText = (text) ->
     caretStart = $(child)[0].selectionStart
     caretEnd = $(child)[0].selectionEnd
@@ -126,12 +126,12 @@
     $(child).val beforeSelection + text + afterSelection
     $(".markdown-area").trigger "input"

-  getFilename = (e) ->
+  getFilename = (e) ->
     if window.clipboardData and window.clipboardData.getData
       value = window.clipboardData.getData("Text")
     else if e.clipboardData and e.clipboardData.getData
       value = e.clipboardData.getData("text/plain")
-
+
     value = value.split("\r")
     value.first()

@@ -154,7 +154,7 @@

       success: (e, textStatus, response) ->
         insertToTextArea(filename, formatLink(response.responseJSON.link))
-
+
       error: (response) ->
         showError(response.responseJSON.message)

@@ -190,7 +190,7 @@

   $(".markdown-selector").click (e) ->
     e.preventDefault()
-    $(@).closest(".div-dropzone-wrapper").find(".div-dropzone").click()
+    $(@).closest(".note-write-holder").find(".div-dropzone").click()
     return

   return


Added existence check question marks.

Added existence check question marks.

--- client/app/lib/machinesharemanager.coffee
+++ client/app/lib/machinesharemanager.coffee
@@ -67,13 +67,13 @@
     { socialapi, groupsController } = kd.singletons

     socialapi.channel.byId { id: channelId }, (err, channel) ->
-      return callback err   if err
+      return callback err  if err

       group = groupsController.getCurrentGroup()
       socialapi.registerAndOpenChannel group, channel, (err, pubnubChannel) ->

-        return callback err   if err
+        return callback err  if err

-        pubnubChannel.channel.once 'RemovedFromChannel', ->
+        pubnubChannel?.channel?.once 'RemovedFromChannel', ->
           dataProvider.fetch ->
             kd.singletons.mainView.activitySidebar.redrawMachineList()


Don't freeze sourcefiles.

Don't freeze sourcefiles.

--- src/fs_utils/source_file.coffee
+++ src/fs_utils/source_file.coffee
@@ -15,7 +15,6 @@
       fileName = "brunch_#{@compilerName}_#{sysPath.basename @path}"
       @realPath = @path
       @path = sysPath.join 'vendor', 'scripts', fileName
-    Object.freeze this

   # Defines a requirejs module in scripts & templates.
   # This allows brunch users to use `require 'module/name'` in browsers.


test concept to switch output format based on assemble task dest format.

--- src/helpers/helpers-html.coffee
+++ src/helpers/helpers-html.coffee
@@ -11,11 +11,22 @@
   Usage: {{link 'href' 'title' 'class'}}
   ###
   Handlebars.registerHelper "href", (url, text, linkClass) ->
-      url = Handlebars.Utils.escapeExpression(url)
+      url  = Handlebars.Utils.escapeExpression(url)
       text = Handlebars.Utils.escapeExpression(text)
       linkClass = ""  if Utils.isUndefined(linkClass)
-      result = '' + text + ''
+      md   = '[' + text + '](' + url + ')'
+      html = '' + text + ''
+      result = Utils.switchOutput(options.ext, md, html)
       Utils.safeString(result)
+
+  ###
+  List:

+  ###
+  Handlebars.registerHelper "switch", (src) ->
+    md = '# ' + src
+    html = '
' + src + '
'
+    output = Utils.switchOutput(options.ext, md, html)
+    Utils.safeString(output)

   Handlebars.registerHelper "css", (context) ->
@@ -30,11 +41,9 @@
           return css
         else css

-
-
   Handlebars.registerHelper "js", (context) ->
-      ext = Utils.getExt(context)
-      js  = Utils.safeString('')
+      ext    = Utils.getExt(context)
+      js     = Utils.safeString('')
       coffee = Utils.safeString('')
       switch ext
         when "js"


bug fix

bug fix


message typo fix

message typo fix


fixes

fixes


bug fix to null endpoints

bug fix to null endpoints


destroying services

destroying services


delay the fadein to wait for flickity

delay the fadein to wait for flickity

--- apps/artwork/client/setup_artwork_rails.coffee
+++ apps/artwork/client/setup_artwork_rails.coffee
@@ -47,7 +47,9 @@

           $('#artwork-rails').append view.render().$el

-        $('#artwork-rails').attr 'data-state', 'fade-in'
+        _.delay =>
+          $('#artwork-rails').attr 'data-state', 'fade-in'
+        , 700
       else
         return unless artist.related().artworks.length
         $('#artist-artworks-section').addClass('is-fade-in').show()


Add commands for brightness and saturation.

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/lmjohns3/thorax-media.git/'


inc polling time

inc polling time

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/Snitzle/hummingbird.git/'


rebuild and organize gulpfile

rebuild and organize gulpfile

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/Bit18/cyoab_modular_repo.git/'


Update gulpfile.coffee

Update gulpfile.coffee

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/Hiroto-K/EncryptionHelper.git/'


Add gulpfile.coffee.

Add gulpfile.coffee.

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

--- gulpfile.coffee
+++ gulpfile.coffee
@@ -0,0 +1,22 @@
+gulp       = require 'gulp'
+gutil      = require 'gulp-util'
+coffee     = require 'gulp-coffee'
+mocha      = require 'gulp-mocha'
+watch      = require 'gulp-watch'
+clean      = require 'rimraf'
+coffeelint = require 'gulp-coffeelint'
+
+require 'coffee-script/register'
+
+gulp.task 'mocha', ->
+  gulp.src 'test/*.coffee'
+    .pipe mocha { reporter: 'spec'}
+
+gulp.task 'coffeelint', ->
+  gulp.src(['scripts/*.coffee', 'test/*.coffee'])
+    .pipe coffeelint()
+    .pipe coffeelint.reporter 'default'
+
+gulp.task 'watch', ->
+  gulp
+    .watch ['scripts/*.coffee', 'test/*.coffee'], ['mocha', 'coffeelint']


updated to atom-shell 0.18.1

updated to atom-shell 0.18.1

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/olmokramer/atom-shell-layoutbuilder.git/'


Only reset page to login if we successfully reset password.

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/alpire/picoCTF-web.git/'


Fixed recording days calendar highlight issue which is occurred after new year

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/evercam/evercam-dashboard.git/'


Fix availableKpis updating before load

Fix availableKpis updating before load

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/xaun/impac-angular.git/'


Removed the animate method for ios devices


Fixed recording tab issue

Fixed recording tab issue


Fixed the zoom function bug on recording tab. (#2220)


Fix up new jasmine tests

Fix up new jasmine tests

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/bmedx/modulestore.git/'


sidebar: create SidebarMessagesListItem

sidebar: create SidebarMessagesListItem

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/'


Fix job error handling.

Fix job error handling.


Update doc strings

Update doc strings

--- src/config.coffee
+++ src/config.coffee
@@ -319,11 +319,11 @@
   # than {::onDidChange} in that it will immediately call your callback with the
   # current value of the config entry.
   #
-  # * `keyPath` The {String} name of the key to observe
-  # * `callback` The {Function} to call when the value of the key changes.
-  #   The first argument will be the new value of the key and the
-  #   second argument will be an {Object} with a `previous` property
-  #   that is the prior value of the key.
+  # * `keyPath` {String} name of the key to observe
+  # * `callback` {Function} to call when the value of the key changes.
+  #   * `value` the new value of the key
+  #   * `event` {Object}
+  #     * `previous` the prior value of the key.
   #
   # Returns a {Disposable} with the following keys on which you can call
   # `.dispose()` to unsubscribe.
@@ -341,11 +341,11 @@

   # Essential: Add a listener for changes to a given key path.
   #
-  # * `keyPath` The {String} name of the key to observe
-  # * `callback` The {Function} to call when the value of the key changes.
-  #   The first argument will be the new value of the key and the
-  #   second argument will be an {Object} with a `previous` property
-  #   that is the prior value of the key.
+  # * `keyPath` {String} name of the key to observe
+  # * `callback` {Function} to call when the value of the key changes.
+  #   * `value` the new value of the key
+  #   * `event` {Object}
+  #     * `previous` the prior value of the key.
   #
   # Returns a {Disposable} with the following keys on which you can call
   # `.dispose()` to unsubscribe.


chore (document-events) Fool supersonic to think it is visible when run in a document-less environment.


removing old permission

removing old permission

error: pathspec 'server/startup/migrations/v24.coffee' did not match any file(s) known to git

--- server/startup/migrations/v24.coffee
+++ server/startup/migrations/v24.coffee
@@ -0,0 +1,5 @@
+Meteor.startup ->
+	Migrations.add
+		version: 24
+		up: ->
+			RocketChat.models.Permissions.remove({ _id: 'access-rocket-permissions' })


Helper for calling window.location.replace

This way it can be stubbed out when testing

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

--- src/helpers/window.coffee
+++ src/helpers/window.coffee
@@ -0,0 +1,6 @@
+module.exports = {
+
+  replaceBrowserLocation: (url) ->
+    window.location.replace(url)
+
+}


Nope. no cp

Nope. no cp

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/demhydraz/til.git/'


Use today's date for mock bookings api 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/Bogdan-p/bookingbug-angular.git/'


Window is no longer a Pane

Window is no longer a Pane

--- src/window.coffee
+++ src/window.coffee
@@ -3,8 +3,10 @@
 Chrome = require 'chrome'
 Pane = require 'pane'

+{bindKey} = require 'keybinder'
+
 module.exports =
-class Window extends Pane
+class Window
   controller: null
   document: null
   nswindow: null
@@ -18,12 +20,15 @@
     'Command-Ctrl-R'  : @reload

   constructor: (options={}) ->
-    super options
+    for option, value of options
+      @[option] = value
+
+    for shortcut, method of @keymap()
+      bindKey @, shortcut, method

     Editor = require 'editor'
     @document = new Editor

-  initialize: ->
     @nswindow = @controller?.window

   addPane: ({position, html}) ->


Remove unncessary emptying of results

Remove unncessary emptying of results

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/'


preserve ordering of multiple buckets in partner rails

--- apps/partner2/components/fixed_cells_count_carousel/view.coffee
+++ apps/partner2/components/fixed_cells_count_carousel/view.coffee
@@ -28,7 +28,9 @@
     Q.allSettled(
       _.map @fetchOptions, (options) =>
         @collection.fetch data: options, remove: false
-    ).then =>
+    ).then (values) =>
+      objects = [].concat.apply [], _.pluck values, 'value'
+      @collection.reset objects
       @collection

   # Only keep the first cellsCountPerPage * pagesCount items.


CLIO-23420: Fix for first example, set to empty array when searchString is empty

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/seanhealy/lib-themisui.git/'


Add google analytics

Add google analytics

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/sledghammer/pole_territorial_du_perche.git/'


HelpController: Initial commit for HelpController


bug fix

bug fix

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/'


changing the way run local works

changing the way run local works


Fixed: github was not mocked resulting in errors while running tests

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/clochix/cozy-home.git/'


Make inherit work

Make inherit work

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/freyproject/frey.git/'


Add method for Route instantiation and remove unused options.

Minimal update to app/App class to reflect framework updates. This
change also passes the router instance to the server and fixes
StaticController instantiation to reflect new constructor signature.

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/RobotSnacks/stout-server.git/'


Attempt to fix insertBefore error in IE9


Abort previous api request on send next

Abort previous api request on send next


:memo: Mention ignoring cache errors

:memo: Mention ignoring cache errors

--- src/install.coffee
+++ src/install.coffee
@@ -394,7 +394,9 @@

   buildModuleCache: (packageName, callback) ->
     packageDirectory = path.join(@atomPackagesDirectory, packageName)
-    RebuildModuleCache.buildCache packageDirectory, -> callback()
+    RebuildModuleCache.buildCache packageDirectory, ->
+      # Ignore cache errors and just finish the install
+      callback()

   warmCompileCache: (packageName, callback) ->
     packageDirectory = path.join(@atomPackagesDirectory, packageName)


client: home: added a subclass for the stacks topnav tabhandle

to enable route changes.

error: pathspec 'client/home/lib/stacks/homestackstabhandle.coffee' did not match any file(s) known to git

--- client/home/lib/stacks/homestackstabhandle.coffee
+++ client/home/lib/stacks/homestackstabhandle.coffee
@@ -0,0 +1,18 @@
+kd = require 'kd'
+
+module.exports = class HomeStacksTabHandle extends kd.TabHandleView
+
+  constructor: (options = {}, data) ->
+
+    options.tagName         = 'a'
+    options.attributes    or= {}
+    options.attributes.href = "/Home/Stacks/#{kd.utils.slugify options.pane.name}"
+
+    super options, data
+
+
+  # click: (event) ->
+
+  #   kd.utils.stopDOMEvent event
+
+  #   return no


Tests: Environments: Helpers: Improve pause.


stdoutg -> stdout

stdoutg -> stdout

--- src/browser/squirrel-update.coffee
+++ src/browser/squirrel-update.coffee
@@ -93,7 +93,7 @@
   getPath = (callback) ->
     spawnReg ['query', environmentKeyPath, '/v', 'Path'], (error, stdout) ->
       console.log error
-      console.log stdoutg
+      console.log stdout
       return callback(error) if error?

       lines = stdout.split(/[\r\n]+/).filter (line) -> line


:lipstick:

:lipstick:

--- spec/text-editor-component-spec.coffee
+++ spec/text-editor-component-spec.coffee
@@ -1196,7 +1196,7 @@
         expect(componentNode.querySelector('.test-highlight')).toBeFalsy()
         expect(componentNode.querySelector('.new-test-highlight')).toBeTruthy()

-  describe "overlay decoration rendering", ->
+  fdescribe "overlay decoration rendering", ->
     [item] = []
     beforeEach ->
       item = document.createElement('div')
@@ -1278,8 +1278,6 @@
         wrapperNode.style.width = windowWidth + 'px'
         wrapperNode.style.height = windowHeight + 'px'

-        editor.setScrollTop(0)
-        editor.setScrollLeft(0)
         component.measureHeightAndWidth()
         nextAnimationFrame()


[Gutter] Move line number gutter tests to be under .gutters in TextEditorPresenter specs

--- spec/text-editor-presenter-spec.coffee
+++ spec/text-editor-presenter-spec.coffee
@@ -1772,357 +1772,6 @@
                 pixelPosition: {top: 10, left: 0}
               }

-    # TODO jssln Move this under '.gutters'
-    describe "when the gutter is the line-number gutter", ->
-      getLineNumberGutterState = (presenter) ->
-        gutterDescriptions = presenter.getState().gutters
-        for description in gutterDescriptions
-          gutter = description.gutter
-          return description if gutter.name is 'line-number'
-
-      describe ".visible", ->
-        it "is true iff the editor isn't mini, ::isLineNumberGutterVisible is true on the editor, and the 'editor.showLineNumbers' config is enabled", ->
-          presenter = buildPresenter()
-
-          expect(editor.isLineNumberGutterVisible()).toBe true
-          expect(getLineNumberGutterState(presenter).visible).toBe true
-
-          expectStateUpdate presenter, -> editor.setMini(true)
-          expect(getLineNumberGutterState(presenter)).toBeUndefined()
-
-          expectStateUpdate presenter, -> editor.setMini(false)
-          expect(getLineNumberGutterState(presenter).visible).toBe true
-
-          expectStateUpdate presenter, -> editor.setLineNumberGutterVisible(false)
-          expect(getLineNumberGutterState(presenter).visible).toBe false
-
-          expectStateUpdate presenter, -> editor.setLineNumberGutterVisible(true)
-          expect(getLineNumberGutterState(presenter).visible).toBe true
-
-          expectStateUpdate presenter, -> atom.config.set('editor.showLineNumbers', false)
-          expect(getLineNumberGutterState(presenter).visible).toBe false
-
-        it "gets updated when the editor's grammar changes", ->
-          presenter = buildPresenter()
-
-          atom.config.set('editor.showLineNumbers', false, scopeSelector: '.source.js')
-          expect(getLineNumberGutterState(presenter).visible).toBe true
-          stateUpdated = false
-          presenter.onDidUpdateState -> stateUpdated = true
-
-          waitsForPromise -> atom.packages.activatePackage('language-javascript')
-
-          runs ->
-            expect(stateUpdated).toBe true
-            expect(getLineNumberGutterState(presenter).visible).toBe false
-
-      describe ".content.maxLineNumberDigits", ->
-        it "is set to the number of digits used by the greatest line number", ->
-          presenter = buildPresenter()
-          expect(editor.getLastBufferRow()).toBe 12
-          expect(getLineNumberGutterState(presenter).content.maxLineNumberDigits).toBe 2
-
-          editor.setText("1\n2\n3")
-          expect(getLineNumberGutterState(presenter).content.maxLineNumberDigits).toBe 1
-
-      describe ".content.lineNumbers", ->
-        lineNumberStateForScreenRow = (presenter, screenRow) ->
-          editor = presenter.model
-          bufferRow = editor.bufferRowForScreenRow(screenRow)
-          wrapCount = screenRow - editor.screenRowForBufferRow(bufferRow)
-          if wrapCount > 0
-            key = bufferRow + '-' + wrapCount
-          else
-            key = bufferRow
-
-          getLineNumberGutterState(presenter).content.lineNumbers[key]
-
-        it "contains states for line numbers that are visible on screen, plus and minus the overdraw margin", ->
-          editor.foldBufferRow(4)
-          editor.setSoftWrapped(true)
-          editor.setEditorWidthInChars(50)
-          presenter = buildPresenter(explicitHeight: 25, scrollTop: 30, lineHeight: 10, lineOverdrawMargin: 1)
-
-          expect(lineNumberStateForScreenRow(presenter, 1)).toBeUndefined()
-          expectValues lineNumberStateForScreenRow(presenter, 2), {screenRow: 2, bufferRow: 2, softWrapped: false, top: 2 * 10}
-          expectValues lineNumberStateForScreenRow(presenter, 3), {screenRow: 3, bufferRow: 3, softWrapped: false, top: 3 * 10}
-          expectValues lineNumberStateForScreenRow(presenter, 4), {screenRow: 4, bufferRow: 3, softWrapped: true, top: 4 * 10}
-          expectValues lineNumberStateForScreenRow(presenter, 5), {screenRow: 5, bufferRow: 4, softWrapped: false, top: 5 * 10}
-          expectValues lineNumberStateForScreenRow(presenter, 6), {screenRow: 6, bufferRow: 7, softWrapped: false, top: 6 * 10}
-          expectValues lineNumberStateForScreenRow(presenter, 7), {screenRow: 7, bufferRow: 8, softWrapped: false, top: 7 * 10}
-          expect(lineNumberStateForScreenRow(presenter, 8)).toBeUndefined()
-
-        it "includes states for all line numbers if no ::explicitHeight is assigned", ->
-          presenter = buildPresenter(explicitHeight: null)
-          expect(lineNumberStateForScreenRow(presenter, 0)).toBeDefined()
-          expect(lineNumberStateForScreenRow(presenter, 12)).toBeDefined()
-
-        it "updates when ::scrollTop changes", ->
-          editor.foldBufferRow(4)
-          editor.setSoftWrapped(true)
-          editor.setEditorWidthInChars(50)
-          presenter = buildPresenter(explicitHeight: 25, scrollTop: 30, lineOverdrawMargin: 1)
-
-          expect(lineNumberStateForScreenRow(presenter, 1)).toBeUndefined()
-          expectValues lineNumberStateForScreenRow(presenter, 2), {bufferRow: 2}
-          expectValues lineNumberStateForScreenRow(presenter, 7), {bufferRow: 8}
-          expect(lineNumberStateForScreenRow(presenter, 8)).toBeUndefined()
-
-          expectStateUpdate presenter, -> presenter.setScrollTop(20)
-
-          expect(lineNumberStateForScreenRow(presenter, 0)).toBeUndefined()
-          expectValues lineNumberStateForScreenRow(presenter, 1), {bufferRow: 1}
-          expectValues lineNumberStateForScreenRow(presenter, 6), {bufferRow: 7}
-          expect(lineNumberStateForScreenRow(presenter, 7)).toBeUndefined()
-
-        it "updates when ::explicitHeight changes", ->
-          editor.foldBufferRow(4)
-          editor.setSoftWrapped(true)
-          editor.setEditorWidthInChars(50)
-          presenter = buildPresenter(explicitHeight: 25, scrollTop: 30, lineOverdrawMargin: 1)
-
-          expect(lineNumberStateForScreenRow(presenter, 1)).toBeUndefined()
-          expectValues lineNumberStateForScreenRow(presenter, 2), {bufferRow: 2}
-          expectValues lineNumberStateForScreenRow(presenter, 7), {bufferRow: 8}
-          expect(lineNumberStateForScreenRow(presenter, 8)).toBeUndefined()
-
-          expectStateUpdate presenter, -> presenter.setExplicitHeight(35)
-
-          expect(lineNumberStateForScreenRow(presenter, 0)).toBeUndefined()
-          expectValues lineNumberStateForScreenRow(presenter, 2), {bufferRow: 2}
-          expectValues lineNumberStateForScreenRow(presenter, 8), {bufferRow: 8}
-          expect(lineNumberStateForScreenRow(presenter, 9)).toBeUndefined()
-
-        it "updates when ::lineHeight changes", ->
-          editor.foldBufferRow(4)
-          editor.setSoftWrapped(true)
-          editor.setEditorWidthInChars(50)
-          presenter = buildPresenter(explicitHeight: 25, scrollTop: 0, lineOverdrawMargin: 0)
-
-          expectValues lineNumberStateForScreenRow(presenter, 0), {bufferRow: 0}
-          expectValues lineNumberStateForScreenRow(presenter, 3), {bufferRow: 3}
-          expect(lineNumberStateForScreenRow(presenter, 4)).toBeUndefined()
-
-          expectStateUpdate presenter, -> presenter.setLineHeight(5)
-
-          expectValues lineNumberStateForScreenRow(presenter, 0), {bufferRow: 0}
-          expectValues lineNumberStateForScreenRow(presenter, 5), {bufferRow: 4}
-          expect(lineNumberStateForScreenRow(presenter, 6)).toBeUndefined()
-
-        it "updates when the editor's content changes", ->
-          editor.foldBufferRow(4)
-          editor.setSoftWrapped(true)
-          editor.setEditorWidthInChars(50)
-          presenter = buildPresenter(explicitHeight: 35, scrollTop: 30, lineOverdrawMargin: 0)
-
-          expect(lineNumberStateForScreenRow(presenter, 2)).toBeUndefined()
-          expectValues lineNumberStateForScreenRow(presenter, 3), {bufferRow: 3}
-          expectValues lineNumberStateForScreenRow(presenter, 4), {bufferRow: 3}
-          expectValues lineNumberStateForScreenRow(presenter, 5), {bufferRow: 4}
-          expectValues lineNumberStateForScreenRow(presenter, 6), {bufferRow: 7}
-          expectValues lineNumberStateForScreenRow(presenter, 7), {bufferRow: 8}
-          expect(lineNumberStateForScreenRow(presenter, 8)).toBeUndefined()
-
-          expectStateUpdate presenter, ->
-            editor.getBuffer().insert([3, Infinity], new Array(25).join("x "))
-
-          expect(lineNumberStateForScreenRow(presenter, 2)).toBeUndefined()
-          expectValues lineNumberStateForScreenRow(presenter, 3), {bufferRow: 3}
-          expectValues lineNumberStateForScreenRow(presenter, 4), {bufferRow: 3}
-          expectValues lineNumberStateForScreenRow(presenter, 5), {bufferRow: 3}
-          expectValues lineNumberStateForScreenRow(presenter, 6), {bufferRow: 4}
-          expectValues lineNumberStateForScreenRow(presenter, 7), {bufferRow: 7}
-          expect(lineNumberStateForScreenRow(presenter, 8)).toBeUndefined()
-
-        it "does not remove out-of-view line numbers corresponding to ::mouseWheelScreenRow until ::stoppedScrollingDelay elapses", ->
-          presenter = buildPresenter(explicitHeight: 25, lineOverdrawMargin: 1, stoppedScrollingDelay: 200)
-
-          expect(lineNumberStateForScreenRow(presenter, 0)).toBeDefined()
-          expect(lineNumberStateForScreenRow(presenter, 4)).toBeDefined()
-          expect(lineNumberStateForScreenRow(presenter, 5)).toBeUndefined()
-
-          presenter.setMouseWheelScreenRow(0)
-          expectStateUpdate presenter, -> presenter.setScrollTop(35)
-
-          expect(lineNumberStateForScreenRow(presenter, 0)).toBeDefined()
-          expect(lineNumberStateForScreenRow(presenter, 1)).toBeUndefined()
-          expect(lineNumberStateForScreenRow(presenter, 7)).toBeDefined()
-          expect(lineNumberStateForScreenRow(presenter, 8)).toBeUndefined()
-
-          expectStateUpdate presenter, -> advanceClock(200)
-
-          expect(lineNumberStateForScreenRow(presenter, 0)).toBeUndefined()
-          expect(lineNumberStateForScreenRow(presenter, 1)).toBeUndefined()
-          expect(lineNumberStateForScreenRow(presenter, 7)).toBeDefined()
-          expect(lineNumberStateForScreenRow(presenter, 8)).toBeUndefined()
-
-        it "correctly handles the first screen line being soft-wrapped", ->
-          editor.setSoftWrapped(true)
-          editor.setEditorWidthInChars(30)
-          presenter = buildPresenter(explicitHeight: 25, scrollTop: 50)
-
-          expectValues lineNumberStateForScreenRow(presenter, 5), {screenRow: 5, bufferRow: 3, softWrapped: true}
-          expectValues lineNumberStateForScreenRow(presenter, 6), {screenRow: 6, bufferRow: 3, softWrapped: true}
-          expectValues lineNumberStateForScreenRow(presenter, 7), {screenRow: 7, bufferRow: 4, softWrapped: false}
-
-        describe ".decorationClasses", ->
-          it "adds decoration classes to the relevant line number state objects, both initially and when decorations change", ->
-            marker1 = editor.markBufferRange([[4, 0], [6, 2]], invalidate: 'touch')
-            decoration1 = editor.decorateMarker(marker1, type: 'line-number', class: 'a')
-            presenter = buildPresenter()
-            marker2 = editor.markBufferRange([[4, 0], [6, 2]], invalidate: 'touch')
-            decoration2 = editor.decorateMarker(marker2, type: 'line-number', class: 'b')
-
-            expect(lineNumberStateForScreenRow(presenter, 3).decorationClasses).toBeNull()
-            expect(lineNumberStateForScreenRow(presenter, 4).decorationClasses).toEqual ['a', 'b']
-            expect(lineNumberStateForScreenRow(presenter, 5).decorationClasses).toEqual ['a', 'b']
-            expect(lineNumberStateForScreenRow(presenter, 6).decorationClasses).toEqual ['a', 'b']
-            expect(lineNumberStateForScreenRow(presenter, 7).decorationClasses).toBeNull()
-
-            expectStateUpdate presenter, -> editor.getBuffer().insert([5, 0], 'x')
-            expect(marker1.isValid()).toBe false
-            expect(lineNumberStateForScreenRow(presenter, 4).decorationClasses).toBeNull()
-            expect(lineNumberStateForScreenRow(presenter, 5).decorationClasses).toBeNull()
-            expect(lineNumberStateForScreenRow(presenter, 6).decorationClasses).toBeNull()
-
-            expectStateUpdate presenter, -> editor.undo()
-            expect(lineNumberStateForScreenRow(presenter, 3).decorationClasses).toBeNull()
-            expect(lineNumberStateForScreenRow(presenter, 4).decorationClasses).toEqual ['a', 'b']
-            expect(lineNumberStateForScreenRow(presenter, 5).decorationClasses).toEqual ['a', 'b']
-            expect(lineNumberStateForScreenRow(presenter, 6).decorationClasses).toEqual ['a', 'b']
-            expect(lineNumberStateForScreenRow(presenter, 7).decorationClasses).toBeNull()
-
-            expectStateUpdate presenter, -> marker1.setBufferRange([[2, 0], [4, 2]])
-            expect(lineNumberStateForScreenRow(presenter, 1).decorationClasses).toBeNull()
-            expect(lineNumberStateForScreenRow(presenter, 2).decorationClasses).toEqual ['a']
-            expect(lineNumberStateForScreenRow(presenter, 3).decorationClasses).toEqual ['a']
-            expect(lineNumberStateForScreenRow(presenter, 4).decorationClasses).toEqual ['a', 'b']
-            expect(lineNumberStateForScreenRow(presenter, 5).decorationClasses).toEqual ['b']
-            expect(lineNumberStateForScreenRow(presenter, 6).decorationClasses).toEqual ['b']
-            expect(lineNumberStateForScreenRow(presenter, 7).decorationClasses).toBeNull()
-
-            expectStateUpdate presenter, -> decoration1.destroy()
-            expect(lineNumberStateForScreenRow(presenter, 2).decorationClasses).toBeNull()
-            expect(lineNumberStateForScreenRow(presenter, 3).decorationClasses).toBeNull()
-            expect(lineNumberStateForScreenRow(presenter, 4).decorationClasses).toEqual ['b']
-            expect(lineNumberStateForScreenRow(presenter, 5).decorationClasses).toEqual ['b']
-            expect(lineNumberStateForScreenRow(presenter, 6).decorationClasses).toEqual ['b']
-            expect(lineNumberStateForScreenRow(presenter, 7).decorationClasses).toBeNull()
-
-            expectStateUpdate presenter, -> marker2.destroy()
-            expect(lineNumberStateForScreenRow(presenter, 2).decorationClasses).toBeNull()
-            expect(lineNumberStateForScreenRow(presenter, 3).decorationClasses).toBeNull()
-            expect(lineNumberStateForScreenRow(presenter, 4).decorationClasses).toBeNull()
-            expect(lineNumberStateForScreenRow(presenter, 5).decorationClasses).toBeNull()
-            expect(lineNumberStateForScreenRow(presenter, 6).decorationClasses).toBeNull()
-            expect(lineNumberStateForScreenRow(presenter, 7).decorationClasses).toBeNull()
-
-          it "honors the 'onlyEmpty' option on line-number decorations", ->
-            presenter = buildPresenter()
-            marker = editor.markBufferRange([[4, 0], [6, 1]])
-            decoration = editor.decorateMarker(marker, type: 'line-number', class: 'a', onlyEmpty: true)
-
-            expect(lineNumberStateForScreenRow(presenter, 4).decorationClasses).toBeNull()
-            expect(lineNumberStateForScreenRow(presenter, 5).decorationClasses).toBeNull()
-            expect(lineNumberStateForScreenRow(presenter, 6).decorationClasses).toBeNull()
-
-            expectStateUpdate presenter, -> marker.clearTail()
-
-            expect(lineNumberStateForScreenRow(presenter, 4).decorationClasses).toBeNull()
-            expect(lineNumberStateForScreenRow(presenter, 5).decorationClasses).toBeNull()
-            expect(lineNumberStateForScreenRow(presenter, 6).decorationClasses).toEqual ['a']
-
-          it "honors the 'onlyNonEmpty' option on line-number decorations", ->
-            presenter = buildPresenter()
-            marker = editor.markBufferRange([[4, 0], [6, 2]])
-            decoration = editor.decorateMarker(marker, type: 'line-number', class: 'a', onlyNonEmpty: true)
-
-            expect(lineNumberStateForScreenRow(presenter, 4).decorationClasses).toEqual ['a']
-            expect(lineNumberStateForScreenRow(presenter, 5).decorationClasses).toEqual ['a']
-            expect(lineNumberStateForScreenRow(presenter, 6).decorationClasses).toEqual ['a']
-
-            expectStateUpdate presenter, -> marker.clearTail()
-
-            expect(lineNumberStateForScreenRow(presenter, 6).decorationClasses).toBeNull()
-
-          it "honors the 'onlyHead' option on line-number decorations", ->
-            presenter = buildPresenter()
-            marker = editor.markBufferRange([[4, 0], [6, 2]])
-            decoration = editor.decorateMarker(marker, type: 'line-number', class: 'a', onlyHead: true)
-
-            expect(lineNumberStateForScreenRow(presenter, 4).decorationClasses).toBeNull()
-            expect(lineNumberStateForScreenRow(presenter, 5).decorationClasses).toBeNull()
-            expect(lineNumberStateForScreenRow(presenter, 6).decorationClasses).toEqual ['a']
-
-          it "does not decorate the last line of a non-empty line-number decoration range if it ends at column 0", ->
-            presenter = buildPresenter()
-            marker = editor.markBufferRange([[4, 0], [6, 0]])
-            decoration = editor.decorateMarker(marker, type: 'line-number', class: 'a')
-
-            expect(lineNumberStateForScreenRow(presenter, 4).decorationClasses).toEqual ['a']
-            expect(lineNumberStateForScreenRow(presenter, 5).decorationClasses).toEqual ['a']
-            expect(lineNumberStateForScreenRow(presenter, 6).decorationClasses).toBeNull()
-
-          it "does not apply line-number decorations to mini editors", ->
-            editor.setMini(true)
-            presenter = buildPresenter()
-            marker = editor.markBufferRange([[0, 0], [0, 0]])
-            decoration = editor.decorateMarker(marker, type: 'line-number', class: 'a')
-            # A mini editor will have no gutters.
-            expect(getLineNumberGutterState(presenter)).toBeUndefined()
-
-            expectStateUpdate presenter, -> editor.setMini(false)
-            expect(lineNumberStateForScreenRow(presenter, 0).decorationClasses).toEqual ['cursor-line', 'cursor-line-no-selection', 'a']
-
-            expectStateUpdate presenter, -> editor.setMini(true)
-            expect(getLineNumberGutterState(presenter)).toBeUndefined()
-
-          it "only applies line-number decorations to screen rows that are spanned by their marker when lines are soft-wrapped", ->
-            editor.setText("a line that wraps, ok")
-            editor.setSoftWrapped(true)
-            editor.setEditorWidthInChars(16)
-            marker = editor.markBufferRange([[0, 0], [0, 2]])
-            editor.decorateMarker(marker, type: 'line-number', class: 'a')
-            presenter = buildPresenter(explicitHeight: 10)
-
-            expect(lineNumberStateForScreenRow(presenter, 0).decorationClasses).toContain 'a'
-            expect(lineNumberStateForScreenRow(presenter, 1).decorationClasses).toBeNull()
-
-            marker.setBufferRange([[0, 0], [0, Infinity]])
-            expect(lineNumberStateForScreenRow(presenter, 0).decorationClasses).toContain 'a'
-            expect(lineNumberStateForScreenRow(presenter, 1).decorationClasses).toContain 'a'
-
-        describe ".foldable", ->
-          it "marks line numbers at the start of a foldable region as foldable", ->
-            presenter = buildPresenter()
-            expect(lineNumberStateForScreenRow(presenter, 0).foldable).toBe true
-            expect(lineNumberStateForScreenRow(presenter, 1).foldable).toBe true
-            expect(lineNumberStateForScreenRow(presenter, 2).foldable).toBe false
-            expect(lineNumberStateForScreenRow(presenter, 3).foldable).toBe false
-            expect(lineNumberStateForScreenRow(presenter, 4).foldable).toBe true
-            expect(lineNumberStateForScreenRow(presenter, 5).foldable).toBe false
-
-          it "updates the foldable class on the correct line numbers when the foldable positions change", ->
-            presenter = buildPresenter()
-            editor.getBuffer().insert([0, 0], '\n')
-            expect(lineNumberStateForScreenRow(presenter, 0).foldable).toBe false
-            expect(lineNumberStateForScreenRow(presenter, 1).foldable).toBe true
-            expect(lineNumberStateForScreenRow(presenter, 2).foldable).toBe true
-            expect(lineNumberStateForScreenRow(presenter, 3).foldable).toBe false
-            expect(lineNumberStateForScreenRow(presenter, 4).foldable).toBe false
-            expect(lineNumberStateForScreenRow(presenter, 5).foldable).toBe true
-            expect(lineNumberStateForScreenRow(presenter, 6).foldable).toBe false
-
-          it "updates the foldable class on a line number that becomes foldable", ->
-            presenter = buildPresenter()
-            expect(lineNumberStateForScreenRow(presenter, 11).foldable).toBe false
-
-            editor.getBuffer().insert([11, 44], '\n    fold me')
-            expect(lineNumberStateForScreenRow(presenter, 11).foldable).toBe true
-
-            editor.undo()
-            expect(lineNumberStateForScreenRow(presenter, 11).foldable).toBe false
-
     describe ".height", ->
       it "tracks the computed content height if ::autoHeight is true so the editor auto-expands vertically", ->
         presenter = buildPresenter(explicitHeight: null, autoHeight: true)
@@ -2179,6 +1828,356 @@
           expect(getStateForGutterWithName(presenter, 'test-gutter').visible).toBe true
           gutter.destroy()
           expect(getStateForGutterWithName(presenter, 'test-gutter')).toBeUndefined()
+
+      describe "for a gutter description that corresponds to the line-number gutter", ->
+        getLineNumberGutterState = (presenter) ->
+          gutterDescriptions = presenter.getState().gutters
+          for description in gutterDescriptions
+            gutter = description.gutter
+            return description if gutter.name is 'line-number'
+
+        describe ".visible", ->
+          it "is true iff the editor isn't mini, ::isLineNumberGutterVisible is true on the editor, and the 'editor.showLineNumbers' config is enabled", ->
+            presenter = buildPresenter()
+
+            expect(editor.isLineNumberGutterVisible()).toBe true
+            expect(getLineNumberGutterState(presenter).visible).toBe true
+
+            expectStateUpdate presenter, -> editor.setMini(true)
+            expect(getLineNumberGutterState(presenter)).toBeUndefined()
+
+            expectStateUpdate presenter, -> editor.setMini(false)
+            expect(getLineNumberGutterState(presenter).visible).toBe true
+
+            expectStateUpdate presenter, -> editor.setLineNumberGutterVisible(false)
+            expect(getLineNumberGutterState(presenter).visible).toBe false
+
+            expectStateUpdate presenter, -> editor.setLineNumberGutterVisible(true)
+            expect(getLineNumberGutterState(presenter).visible).toBe true
+
+            expectStateUpdate presenter, -> atom.config.set('editor.showLineNumbers', false)
+            expect(getLineNumberGutterState(presenter).visible).toBe false
+
+          it "gets updated when the editor's grammar changes", ->
+            presenter = buildPresenter()
+
+            atom.config.set('editor.showLineNumbers', false, scopeSelector: '.source.js')
+            expect(getLineNumberGutterState(presenter).visible).toBe true
+            stateUpdated = false
+            presenter.onDidUpdateState -> stateUpdated = true
+
+            waitsForPromise -> atom.packages.activatePackage('language-javascript')
+
+            runs ->
+              expect(stateUpdated).toBe true
+              expect(getLineNumberGutterState(presenter).visible).toBe false
+
+        describe ".content.maxLineNumberDigits", ->
+          it "is set to the number of digits used by the greatest line number", ->
+            presenter = buildPresenter()
+            expect(editor.getLastBufferRow()).toBe 12
+            expect(getLineNumberGutterState(presenter).content.maxLineNumberDigits).toBe 2
+
+            editor.setText("1\n2\n3")
+            expect(getLineNumberGutterState(presenter).content.maxLineNumberDigits).toBe 1
+
+        describe ".content.lineNumbers", ->
+          lineNumberStateForScreenRow = (presenter, screenRow) ->
+            editor = presenter.model
+            bufferRow = editor.bufferRowForScreenRow(screenRow)
+            wrapCount = screenRow - editor.screenRowForBufferRow(bufferRow)
+            if wrapCount > 0
+              key = bufferRow + '-' + wrapCount
+            else
+              key = bufferRow
+
+            getLineNumberGutterState(presenter).content.lineNumbers[key]
+
+          it "contains states for line numbers that are visible on screen, plus and minus the overdraw margin", ->
+            editor.foldBufferRow(4)
+            editor.setSoftWrapped(true)
+            editor.setEditorWidthInChars(50)
+            presenter = buildPresenter(explicitHeight: 25, scrollTop: 30, lineHeight: 10, lineOverdrawMargin: 1)
+
+            expect(lineNumberStateForScreenRow(presenter, 1)).toBeUndefined()
+            expectValues lineNumberStateForScreenRow(presenter, 2), {screenRow: 2, bufferRow: 2, softWrapped: false, top: 2 * 10}
+            expectValues lineNumberStateForScreenRow(presenter, 3), {screenRow: 3, bufferRow: 3, softWrapped: false, top: 3 * 10}
+            expectValues lineNumberStateForScreenRow(presenter, 4), {screenRow: 4, bufferRow: 3, softWrapped: true, top: 4 * 10}
+            expectValues lineNumberStateForScreenRow(presenter, 5), {screenRow: 5, bufferRow: 4, softWrapped: false, top: 5 * 10}
+            expectValues lineNumberStateForScreenRow(presenter, 6), {screenRow: 6, bufferRow: 7, softWrapped: false, top: 6 * 10}
+            expectValues lineNumberStateForScreenRow(presenter, 7), {screenRow: 7, bufferRow: 8, softWrapped: false, top: 7 * 10}
+            expect(lineNumberStateForScreenRow(presenter, 8)).toBeUndefined()
+
+          it "includes states for all line numbers if no ::explicitHeight is assigned", ->
+            presenter = buildPresenter(explicitHeight: null)
+            expect(lineNumberStateForScreenRow(presenter, 0)).toBeDefined()
+            expect(lineNumberStateForScreenRow(presenter, 12)).toBeDefined()
+
+          it "updates when ::scrollTop changes", ->
+            editor.foldBufferRow(4)
+            editor.setSoftWrapped(true)
+            editor.setEditorWidthInChars(50)
+            presenter = buildPresenter(explicitHeight: 25, scrollTop: 30, lineOverdrawMargin: 1)
+
+            expect(lineNumberStateForScreenRow(presenter, 1)).toBeUndefined()
+            expectValues lineNumberStateForScreenRow(presenter, 2), {bufferRow: 2}
+            expectValues lineNumberStateForScreenRow(presenter, 7), {bufferRow: 8}
+            expect(lineNumberStateForScreenRow(presenter, 8)).toBeUndefined()
+
+            expectStateUpdate presenter, -> presenter.setScrollTop(20)
+
+            expect(lineNumberStateForScreenRow(presenter, 0)).toBeUndefined()
+            expectValues lineNumberStateForScreenRow(presenter, 1), {bufferRow: 1}
+            expectValues lineNumberStateForScreenRow(presenter, 6), {bufferRow: 7}
+            expect(lineNumberStateForScreenRow(presenter, 7)).toBeUndefined()
+
+          it "updates when ::explicitHeight changes", ->
+            editor.foldBufferRow(4)
+            editor.setSoftWrapped(true)
+            editor.setEditorWidthInChars(50)
+            presenter = buildPresenter(explicitHeight: 25, scrollTop: 30, lineOverdrawMargin: 1)
+
+            expect(lineNumberStateForScreenRow(presenter, 1)).toBeUndefined()
+            expectValues lineNumberStateForScreenRow(presenter, 2), {bufferRow: 2}
+            expectValues lineNumberStateForScreenRow(presenter, 7), {bufferRow: 8}
+            expect(lineNumberStateForScreenRow(presenter, 8)).toBeUndefined()
+
+            expectStateUpdate presenter, -> presenter.setExplicitHeight(35)
+
+            expect(lineNumberStateForScreenRow(presenter, 0)).toBeUndefined()
+            expectValues lineNumberStateForScreenRow(presenter, 2), {bufferRow: 2}
+            expectValues lineNumberStateForScreenRow(presenter, 8), {bufferRow: 8}
+            expect(lineNumberStateForScreenRow(presenter, 9)).toBeUndefined()
+
+          it "updates when ::lineHeight changes", ->
+            editor.foldBufferRow(4)
+            editor.setSoftWrapped(true)
+            editor.setEditorWidthInChars(50)
+            presenter = buildPresenter(explicitHeight: 25, scrollTop: 0, lineOverdrawMargin: 0)
+
+            expectValues lineNumberStateForScreenRow(presenter, 0), {bufferRow: 0}
+            expectValues lineNumberStateForScreenRow(presenter, 3), {bufferRow: 3}
+            expect(lineNumberStateForScreenRow(presenter, 4)).toBeUndefined()
+
+            expectStateUpdate presenter, -> presenter.setLineHeight(5)
+
+            expectValues lineNumberStateForScreenRow(presenter, 0), {bufferRow: 0}
+            expectValues lineNumberStateForScreenRow(presenter, 5), {bufferRow: 4}
+            expect(lineNumberStateForScreenRow(presenter, 6)).toBeUndefined()
+
+          it "updates when the editor's content changes", ->
+            editor.foldBufferRow(4)
+            editor.setSoftWrapped(true)
+            editor.setEditorWidthInChars(50)
+            presenter = buildPresenter(explicitHeight: 35, scrollTop: 30, lineOverdrawMargin: 0)
+
+            expect(lineNumberStateForScreenRow(presenter, 2)).toBeUndefined()
+            expectValues lineNumberStateForScreenRow(presenter, 3), {bufferRow: 3}
+            expectValues lineNumberStateForScreenRow(presenter, 4), {bufferRow: 3}
+            expectValues lineNumberStateForScreenRow(presenter, 5), {bufferRow: 4}
+            expectValues lineNumberStateForScreenRow(presenter, 6), {bufferRow: 7}
+            expectValues lineNumberStateForScreenRow(presenter, 7), {bufferRow: 8}
+            expect(lineNumberStateForScreenRow(presenter, 8)).toBeUndefined()
+
+            expectStateUpdate presenter, ->
+              editor.getBuffer().insert([3, Infinity], new Array(25).join("x "))
+
+            expect(lineNumberStateForScreenRow(presenter, 2)).toBeUndefined()
+            expectValues lineNumberStateForScreenRow(presenter, 3), {bufferRow: 3}
+            expectValues lineNumberStateForScreenRow(presenter, 4), {bufferRow: 3}
+            expectValues lineNumberStateForScreenRow(presenter, 5), {bufferRow: 3}
+            expectValues lineNumberStateForScreenRow(presenter, 6), {bufferRow: 4}
+            expectValues lineNumberStateForScreenRow(presenter, 7), {bufferRow: 7}
+            expect(lineNumberStateForScreenRow(presenter, 8)).toBeUndefined()
+
+          it "does not remove out-of-view line numbers corresponding to ::mouseWheelScreenRow until ::stoppedScrollingDelay elapses", ->
+            presenter = buildPresenter(explicitHeight: 25, lineOverdrawMargin: 1, stoppedScrollingDelay: 200)
+
+            expect(lineNumberStateForScreenRow(presenter, 0)).toBeDefined()
+            expect(lineNumberStateForScreenRow(presenter, 4)).toBeDefined()
+            expect(lineNumberStateForScreenRow(presenter, 5)).toBeUndefined()
+
+            presenter.setMouseWheelScreenRow(0)
+            expectStateUpdate presenter, -> presenter.setScrollTop(35)
+
+            expect(lineNumberStateForScreenRow(presenter, 0)).toBeDefined()
+            expect(lineNumberStateForScreenRow(presenter, 1)).toBeUndefined()
+            expect(lineNumberStateForScreenRow(presenter, 7)).toBeDefined()
+            expect(lineNumberStateForScreenRow(presenter, 8)).toBeUndefined()
+
+            expectStateUpdate presenter, -> advanceClock(200)
+
+            expect(lineNumberStateForScreenRow(presenter, 0)).toBeUndefined()
+            expect(lineNumberStateForScreenRow(presenter, 1)).toBeUndefined()
+            expect(lineNumberStateForScreenRow(presenter, 7)).toBeDefined()
+            expect(lineNumberStateForScreenRow(presenter, 8)).toBeUndefined()
+
+          it "correctly handles the first screen line being soft-wrapped", ->
+            editor.setSoftWrapped(true)
+            editor.setEditorWidthInChars(30)
+            presenter = buildPresenter(explicitHeight: 25, scrollTop: 50)
+
+            expectValues lineNumberStateForScreenRow(presenter, 5), {screenRow: 5, bufferRow: 3, softWrapped: true}
+            expectValues lineNumberStateForScreenRow(presenter, 6), {screenRow: 6, bufferRow: 3, softWrapped: true}
+            expectValues lineNumberStateForScreenRow(presenter, 7), {screenRow: 7, bufferRow: 4, softWrapped: false}
+
+          describe ".decorationClasses", ->
+            it "adds decoration classes to the relevant line number state objects, both initially and when decorations change", ->
+              marker1 = editor.markBufferRange([[4, 0], [6, 2]], invalidate: 'touch')
+              decoration1 = editor.decorateMarker(marker1, type: 'line-number', class: 'a')
+              presenter = buildPresenter()
+              marker2 = editor.markBufferRange([[4, 0], [6, 2]], invalidate: 'touch')
+              decoration2 = editor.decorateMarker(marker2, type: 'line-number', class: 'b')
+
+              expect(lineNumberStateForScreenRow(presenter, 3).decorationClasses).toBeNull()
+              expect(lineNumberStateForScreenRow(presenter, 4).decorationClasses).toEqual ['a', 'b']
+              expect(lineNumberStateForScreenRow(presenter, 5).decorationClasses).toEqual ['a', 'b']
+              expect(lineNumberStateForScreenRow(presenter, 6).decorationClasses).toEqual ['a', 'b']
+              expect(lineNumberStateForScreenRow(presenter, 7).decorationClasses).toBeNull()
+
+              expectStateUpdate presenter, -> editor.getBuffer().insert([5, 0], 'x')
+              expect(marker1.isValid()).toBe false
+              expect(lineNumberStateForScreenRow(presenter, 4).decorationClasses).toBeNull()
+              expect(lineNumberStateForScreenRow(presenter, 5).decorationClasses).toBeNull()
+              expect(lineNumberStateForScreenRow(presenter, 6).decorationClasses).toBeNull()
+
+              expectStateUpdate presenter, -> editor.undo()
+              expect(lineNumberStateForScreenRow(presenter, 3).decorationClasses).toBeNull()
+              expect(lineNumberStateForScreenRow(presenter, 4).decorationClasses).toEqual ['a', 'b']
+              expect(lineNumberStateForScreenRow(presenter, 5).decorationClasses).toEqual ['a', 'b']
+              expect(lineNumberStateForScreenRow(presenter, 6).decorationClasses).toEqual ['a', 'b']
+              expect(lineNumberStateForScreenRow(presenter, 7).decorationClasses).toBeNull()
+
+              expectStateUpdate presenter, -> marker1.setBufferRange([[2, 0], [4, 2]])
+              expect(lineNumberStateForScreenRow(presenter, 1).decorationClasses).toBeNull()
+              expect(lineNumberStateForScreenRow(presenter, 2).decorationClasses).toEqual ['a']
+              expect(lineNumberStateForScreenRow(presenter, 3).decorationClasses).toEqual ['a']
+              expect(lineNumberStateForScreenRow(presenter, 4).decorationClasses).toEqual ['a', 'b']
+              expect(lineNumberStateForScreenRow(presenter, 5).decorationClasses).toEqual ['b']
+              expect(lineNumberStateForScreenRow(presenter, 6).decorationClasses).toEqual ['b']
+              expect(lineNumberStateForScreenRow(presenter, 7).decorationClasses).toBeNull()
+
+              expectStateUpdate presenter, -> decoration1.destroy()
+              expect(lineNumberStateForScreenRow(presenter, 2).decorationClasses).toBeNull()
+              expect(lineNumberStateForScreenRow(presenter, 3).decorationClasses).toBeNull()
+              expect(lineNumberStateForScreenRow(presenter, 4).decorationClasses).toEqual ['b']
+              expect(lineNumberStateForScreenRow(presenter, 5).decorationClasses).toEqual ['b']
+              expect(lineNumberStateForScreenRow(presenter, 6).decorationClasses).toEqual ['b']
+              expect(lineNumberStateForScreenRow(presenter, 7).decorationClasses).toBeNull()
+
+              expectStateUpdate presenter, -> marker2.destroy()
+              expect(lineNumberStateForScreenRow(presenter, 2).decorationClasses).toBeNull()
+              expect(lineNumberStateForScreenRow(presenter, 3).decorationClasses).toBeNull()
+              expect(lineNumberStateForScreenRow(presenter, 4).decorationClasses).toBeNull()
+              expect(lineNumberStateForScreenRow(presenter, 5).decorationClasses).toBeNull()
+              expect(lineNumberStateForScreenRow(presenter, 6).decorationClasses).toBeNull()
+              expect(lineNumberStateForScreenRow(presenter, 7).decorationClasses).toBeNull()
+
+            it "honors the 'onlyEmpty' option on line-number decorations", ->
+              presenter = buildPresenter()
+              marker = editor.markBufferRange([[4, 0], [6, 1]])
+              decoration = editor.decorateMarker(marker, type: 'line-number', class: 'a', onlyEmpty: true)
+
+              expect(lineNumberStateForScreenRow(presenter, 4).decorationClasses).toBeNull()
+              expect(lineNumberStateForScreenRow(presenter, 5).decorationClasses).toBeNull()
+              expect(lineNumberStateForScreenRow(presenter, 6).decorationClasses).toBeNull()
+
+              expectStateUpdate presenter, -> marker.clearTail()
+
+              expect(lineNumberStateForScreenRow(presenter, 4).decorationClasses).toBeNull()
+              expect(lineNumberStateForScreenRow(presenter, 5).decorationClasses).toBeNull()
+              expect(lineNumberStateForScreenRow(presenter, 6).decorationClasses).toEqual ['a']
+
+            it "honors the 'onlyNonEmpty' option on line-number decorations", ->
+              presenter = buildPresenter()
+              marker = editor.markBufferRange([[4, 0], [6, 2]])
+              decoration = editor.decorateMarker(marker, type: 'line-number', class: 'a', onlyNonEmpty: true)
+
+              expect(lineNumberStateForScreenRow(presenter, 4).decorationClasses).toEqual ['a']
+              expect(lineNumberStateForScreenRow(presenter, 5).decorationClasses).toEqual ['a']
+              expect(lineNumberStateForScreenRow(presenter, 6).decorationClasses).toEqual ['a']
+
+              expectStateUpdate presenter, -> marker.clearTail()
+
+              expect(lineNumberStateForScreenRow(presenter, 6).decorationClasses).toBeNull()
+
+            it "honors the 'onlyHead' option on line-number decorations", ->
+              presenter = buildPresenter()
+              marker = editor.markBufferRange([[4, 0], [6, 2]])
+              decoration = editor.decorateMarker(marker, type: 'line-number', class: 'a', onlyHead: true)
+
+              expect(lineNumberStateForScreenRow(presenter, 4).decorationClasses).toBeNull()
+              expect(lineNumberStateForScreenRow(presenter, 5).decorationClasses).toBeNull()
+              expect(lineNumberStateForScreenRow(presenter, 6).decorationClasses).toEqual ['a']
+
+            it "does not decorate the last line of a non-empty line-number decoration range if it ends at column 0", ->
+              presenter = buildPresenter()
+              marker = editor.markBufferRange([[4, 0], [6, 0]])
+              decoration = editor.decorateMarker(marker, type: 'line-number', class: 'a')
+
+              expect(lineNumberStateForScreenRow(presenter, 4).decorationClasses).toEqual ['a']
+              expect(lineNumberStateForScreenRow(presenter, 5).decorationClasses).toEqual ['a']
+              expect(lineNumberStateForScreenRow(presenter, 6).decorationClasses).toBeNull()
+
+            it "does not apply line-number decorations to mini editors", ->
+              editor.setMini(true)
+              presenter = buildPresenter()
+              marker = editor.markBufferRange([[0, 0], [0, 0]])
+              decoration = editor.decorateMarker(marker, type: 'line-number', class: 'a')
+              # A mini editor will have no gutters.
+              expect(getLineNumberGutterState(presenter)).toBeUndefined()
+
+              expectStateUpdate presenter, -> editor.setMini(false)
+              expect(lineNumberStateForScreenRow(presenter, 0).decorationClasses).toEqual ['cursor-line', 'cursor-line-no-selection', 'a']
+
+              expectStateUpdate presenter, -> editor.setMini(true)
+              expect(getLineNumberGutterState(presenter)).toBeUndefined()
+
+            it "only applies line-number decorations to screen rows that are spanned by their marker when lines are soft-wrapped", ->
+              editor.setText("a line that wraps, ok")
+              editor.setSoftWrapped(true)
+              editor.setEditorWidthInChars(16)
+              marker = editor.markBufferRange([[0, 0], [0, 2]])
+              editor.decorateMarker(marker, type: 'line-number', class: 'a')
+              presenter = buildPresenter(explicitHeight: 10)
+
+              expect(lineNumberStateForScreenRow(presenter, 0).decorationClasses).toContain 'a'
+              expect(lineNumberStateForScreenRow(presenter, 1).decorationClasses).toBeNull()
+
+              marker.setBufferRange([[0, 0], [0, Infinity]])
+              expect(lineNumberStateForScreenRow(presenter, 0).decorationClasses).toContain 'a'
+              expect(lineNumberStateForScreenRow(presenter, 1).decorationClasses).toContain 'a'
+
+          describe ".foldable", ->
+            it "marks line numbers at the start of a foldable region as foldable", ->
+              presenter = buildPresenter()
+              expect(lineNumberStateForScreenRow(presenter, 0).foldable).toBe true
+              expect(lineNumberStateForScreenRow(presenter, 1).foldable).toBe true
+              expect(lineNumberStateForScreenRow(presenter, 2).foldable).toBe false
+              expect(lineNumberStateForScreenRow(presenter, 3).foldable).toBe false
+              expect(lineNumberStateForScreenRow(presenter, 4).foldable).toBe true
+              expect(lineNumberStateForScreenRow(presenter, 5).foldable).toBe false
+
+            it "updates the foldable class on the correct line numbers when the foldable positions change", ->
+              presenter = buildPresenter()
+              editor.getBuffer().insert([0, 0], '\n')
+              expect(lineNumberStateForScreenRow(presenter, 0).foldable).toBe false
+              expect(lineNumberStateForScreenRow(presenter, 1).foldable).toBe true
+              expect(lineNumberStateForScreenRow(presenter, 2).foldable).toBe true
+              expect(lineNumberStateForScreenRow(presenter, 3).foldable).toBe false
+              expect(lineNumberStateForScreenRow(presenter, 4).foldable).toBe false
+              expect(lineNumberStateForScreenRow(presenter, 5).foldable).toBe true
+              expect(lineNumberStateForScreenRow(presenter, 6).foldable).toBe false
+
+            it "updates the foldable class on a line number that becomes foldable", ->
+              presenter = buildPresenter()
+              expect(lineNumberStateForScreenRow(presenter, 11).foldable).toBe false
+
+              editor.getBuffer().insert([11, 44], '\n    fold me')
+              expect(lineNumberStateForScreenRow(presenter, 11).foldable).toBe true
+
+              editor.undo()
+              expect(lineNumberStateForScreenRow(presenter, 11).foldable).toBe false

       describe "for a gutter description that corresponds to a custom gutter", ->
         describe ".content", ->


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/'


Cleanup regex and support for jruby on heroku

--- src/helpers.coffee
+++ src/helpers.coffee
@@ -223,8 +223,7 @@
   conventions.ignored ?= paths.ignored ? [
     /[\\/]_/
     /vendor[\\/]node[\\/]/
-    /vendor[\\/]bundle[\\/]/
-    /vendor[\\/]ruby-.*[\\/]/
+    /vendor[\\/](j?ruby-.*|bundle)[\\/]/
   ]
   conventions.vendor  ?= /(^bower_components|vendor)[\\/]/


serve /test directory with integrated default server

--- src/helpers.coffee
+++ src/helpers.coffee
@@ -132,6 +132,8 @@
     response.header 'Cache-Control', 'no-cache'
     next()
   server.use express.static path
+  server.all '/test/*', (request, response) ->
+    response.sendfile sysPath.normalize request.url.substr(1)
   server.all '/*', (request, response) ->
     response.sendfile sysPath.join path, 'index.html'
   server.listen parseInt port, 10


Slave: Fix an error in handoff logic for listeners who disconnect

--- src/streammachine/slave/index.coffee
+++ src/streammachine/slave/index.coffee
@@ -265,11 +265,12 @@
                 # hard as we can to get it all there
                 d = require("domain").create()
                 d.on "error", (err) =>
+                    console.error "Handoff error: #{err}"
                     @log.error "Send handoff listener for #{l.id} hit error: #{err}"
                     d.exit()
                     sFunc()

-                d.run =>
+                d.run =>
                     l.obj.prepForHandoff =>
                         lobj =
                             timer:  null,
@@ -291,6 +292,10 @@

                             # mark them as in-flight
                             @_inflight = lobj.opts.key
+
+                        else
+                            @log.debug "Lost listener #{lobj.opts.id} during taxi. Moving on."
+                            sFunc()

             else
                 # all done!
@@ -301,7 +306,7 @@
         translator.on "stream_listener_ok", (msg) =>
             console.log "Got ACK on ", msg
             if @_inflight == msg.key
-                @log.info "Successful ack for listener #{msg.key}."
+                @log.info "Successful ack for listener #{msg.key}. Boarding length is #{@_boarding.length}"

             @_inflight = null