hold notification when clicked

hold notification when clicked

--- lib/notification-element.coffee
+++ lib/notification-element.coffee
@@ -45,6 +45,7 @@
 class NotificationElement
   animationDuration: 360
   visibilityDuration: 5000
+  autohideTimeout: null

   constructor: (@model) ->
     @fatalTemplate = TemplateHelper.create(FatalMetaNotificationTemplate)
@@ -62,6 +63,9 @@
       @model.onDidDismiss => @removeNotification()
     else
       @autohide()
+      @element.addEventListener 'click', =>
+        clearTimeout(@autohideTimeout)
+        @element.classList.add('has-close')

     @element.issue = @issue
     @element.getRenderPromise = @getRenderPromise.bind(this)
@@ -259,7 +263,7 @@
       container.style.display = 'none'

   autohide: ->
-    setTimeout =>
+    @autohideTimeout = setTimeout =>
       @removeNotification()
     , @visibilityDuration


Notification's filename use base name

Notification's filename use base name

--- lib/rubocop-auto-correct.coffee
+++ lib/rubocop-auto-correct.coffee
@@ -83,7 +83,11 @@
       if rubocop.stdout.match("corrected")
         buffer.setTextViaDiff(fs.readFileSync(tempFilePath, 'utf-8'))
         if atom.config.get('rubocop-auto-correct.notification')
-          atom.notifications.addSuccess(rubocop.stdout)
+          re = /^.+?(:[0-9]+:[0-9]+:.*$)/mg
+          offenses = rubocop.stdout.match(re)
+          offenses.map (offense) ->
+            message = offense.replace(re, buffer.getBaseName() + "$1")
+            atom.notifications.addSuccess(message)

   makeTempFile: (filename) ->
     directory = temp.mkdirSync()


Explanation comment

Explanation comment

--- lib/search-results-model.coffee
+++ lib/search-results-model.coffee
@@ -3,6 +3,14 @@

 # Will be one of these per editor. We will swap the buffers in and out as the
 # user opens/closes buffers.
+#
+# TODO/FIXME - This thing hooks the current buffer's contents-modified event.
+# It will run the search and keep the markers in memory even when the find box
+# is not open. This can be fixed by hooking the searchModel's 'activated' and
+# 'deactivated' events and unbinding from the buffer. But then the find-next
+# (cmd+g) behavior becomes a different code path. To keep things simple for
+# now, I'm going to leave it this way. If it's slow, we can implement the
+# optimization.
 module.exports =
 class SearchResultsModel extends EventEmitter
   # options -


Removed pointless ?= check

Removed pointless ?= check

--- core/app/backbone/views/evidence/add_evidence_form_view.coffee
+++ core/app/backbone/views/evidence/add_evidence_form_view.coffee
@@ -31,7 +31,7 @@
       fact_id: @collection.fact.id
       argumentTypeModel: @_argumentTypeModel

-    @_addCommentView ?= new AddCommentView
+    @_addCommentView = new AddCommentView
       addToCollection: @collection
       argumentTypeModel: @_argumentTypeModel


fix bug - To Open bookmarks

fix bug - To Open bookmarks

--- lib/web-shortcutter-view.coffee
+++ lib/web-shortcutter-view.coffee
@@ -1,6 +1,6 @@
 {SelectListView, $, $$} = require 'atom-space-pen-views'
 fs = require 'fs'
-shell = require 'shell'
+open = require 'open'

 module.exports =
 class WebShortcutterView extends SelectListView
@@ -22,11 +22,7 @@
     "<li>#{item.name}</li>"

   confirmed: (item) ->
-    thisPlatform = process.platform
-    switch thisPlatform
-      when 'win32' then shell.openExternal(item.url)
-      when 'darwin' then exec (item.url)
-      when 'linux' then exec (item.url)
+    open item.url
     @hide();

   cancelled: ->


Cleanup

Cleanup

--- framer/Animation.coffee
+++ framer/Animation.coffee
@@ -125,8 +125,6 @@
 		@_animator.on "stop",  => @emit "stop"
 		@_animator.on "end",   => @emit "end"

-		console.log @_repeatCounter
-
 		# See if we need to repeat this animation
 		# Todo: more repeat behaviours:
 		# 1) add (from end position) 2) reverse (loop between a and b)


Turned readonly setting to warning

Turned readonly setting to warning

--- framer/BaseClass.coffee
+++ framer/BaseClass.coffee
@@ -28,7 +28,7 @@

 		# If no setter was given, this must be a readonly class
 		if not descriptor.set
-			descriptor.set = -> throw Error("#{@constructor.name}.#{propertyName} property is readonly")
+			descriptor.set = -> console.warn("#{@constructor.name}.#{propertyName} property is readonly")

 		# Set the getter/setter as setProperty on this object so we can access and override it easily
 		getName = "get#{capitalizeFirstLetter(propertyName)}"


temporarily create the user in cobalt as well - until we've merged them completely

--- client/code/view/admin_content.coffee
+++ client/code/view/admin_content.coffee
@@ -10,6 +10,22 @@
   render: ->
     @$el.empty()
     @$el.load '/tpl/admin_content'
+
+  # Temporary Cobalt creation
+
+  # Request to Cobalt here?
+  createCobaltProfile: (profile, callback) ->
+    $.ajax
+      url: "#{window.boxServer}/#{profile.shortName}"
+      type: 'POST'
+      dataType: 'json'
+      data:
+        apikey: window.user.real.apiKey
+        displayname: profile.displayName
+        email: profile.email[0]
+        newApikey: profile.apikey
+      success: (cobaltProfile) =>
+        callback cobaltProfile

   createProfile: (e) ->
     e.preventDefault()
@@ -29,8 +45,9 @@
         dataType: 'json'
         success: (newProfile) =>
           console.log newProfile
-          url = "#{location.origin}/set-password/#{newProfile.token}"
-          @$el.children('form').html "
New profile “#{newProfile.shortName}” created.
They can set their password here.
"
+          @createCobaltProfile newProfile, (cobaltProfile) =>
+            url = "#{location.origin}/set-password/#{newProfile.token}"
+            @$el.children('form').html "
New profile “#{newProfile.shortName}” created.
They can set their password here.
"
         error: (jqxhr, textStatus, errorThrown) ->
           if errorThrown == 'Forbidden'
             alert("Hmmm... computer says no. Is your API key a valid staff key?")


legal: update copyright last updated date

--- client/legal/lib/copyrightview.coffee
+++ client/legal/lib/copyrightview.coffee
@@ -10,7 +10,7 @@
   pistachio : ->
     """

-
(last modified on May 17th, 2014)

+
(last modified on May 5th, 2015)

         If you believe that material available on the Koding Service


fix minor typos

fix minor typos

--- library/exposure/session.coffee
+++ library/exposure/session.coffee
@@ -64,12 +64,12 @@
     # the storage to destroy a session with the specified session ID.
     # The session may or may not exist. Please refer to the `Connect`.
     destory: (sid, callback) ->
-        @emit "session-destroy", sid, callback
+        this.emit "session-destroy", sid, callback
         assert _.isString qualified = @namespaced sid
+        assert _.isObject(@redis), "no Redis client yet"
         message = "Redis session engine error at destroy"
-        assert _.isObject(@redis), "no Redis client yet"
-        message = "Destroying a Redis stored session %"
-        logger.debug message.gray, "#{sid}".underline
+        success = "Destroying a Redis stored session %s"
+        logger.debug message.gray, try sid.underline
         @redis.del qualified, (error, trailings...) ->
             logger.error message.red, error if error
             return callback.call this, error if error


reduce diff size

reduce diff size

--- core/app/backbone/collections/feed_activities.coffee
+++ core/app/backbone/collections/feed_activities.coffee
@@ -23,5 +23,3 @@
   model: Activity

   url: -> '/api/beta/feed/personal'
-
-


Hackathon: fixed simple require

Hackathon: fixed simple require

--- client/landing/site.hackathon/coffee/core/kodingrouter.coffee
+++ client/landing/site.hackathon/coffee/core/kodingrouter.coffee
@@ -56,6 +56,11 @@
   requireApp: (name, callback)->

     {mainView : {mainTabView}} = KD.singletons
+
+    if app = @appControllers[name]
+      pane = mainTabView.getPaneByName name
+      return callback? app, pane
+
     AppClass              = KD.getAppClass name
     app                   = new AppClass
     view                  = app.getView()


minor: fixed alignment

minor: fixed alignment

--- client/landing/site.landing/coffee/core/mainheaderview.coffee
+++ client/landing/site.landing/coffee/core/mainheaderview.coffee
@@ -4,9 +4,9 @@

   constructor: (options = {}, data) ->

-    options.tagName or    = 'header'
-    options.domId   or    = 'main-header'
-    options.attributes or = testpath : 'main-header'
+    options.tagName    or= 'header'
+    options.domId      or= 'main-header'
+    options.attributes or= testpath : 'main-header'

     super options, data


removed app shortcut

removed app shortcut

--- core/app/backbone/controllers/conversations_controller.coffee
+++ core/app/backbone/controllers/conversations_controller.coffee
@@ -1,13 +1,11 @@
-app = FactlinkApp
-
 class window.ConversationsController extends Backbone.Factlink.BaseController

   routes: ['showConversations', 'showMessages']

   onShow: ->
-    app.closeAllContentRegions()
+    FactlinkApp.closeAllContentRegions()
     @main ?= new TabbedMainRegionLayout()
-    app.mainRegion.show(@main)
+    FactlinkApp.mainRegion.show(@main)

   showConversations: ->
     @conversations ?= new Conversations()
@@ -20,7 +18,7 @@

   showMessages: (conversation_id, message_id=null)->
     @main = new TabbedMainRegionLayout()
-    app.mainRegion.show(@main)
+    FactlinkApp.mainRegion.show(@main)

     @conversation = new Conversation(id: conversation_id)
     FactlinkApp.Sidebar.showForTopicsAndActivateCorrectItem(null, currentUser)


Fix broken import

Fix broken import

--- lib/changes/status-list-element.coffee
+++ lib/changes/status-list-element.coffee
@@ -12,7 +12,7 @@

 GitIndex        = require './git-changes'
 CommitMessageElement = require './commit-message-element'
-UndoCommitElement    = require './undo-commit-view'
+UndoCommitElement    = require './undo-commit-element'
 StatusList        = require './status-list'
 observe = require '../observe'


controlsViews: add control-specific classnames

--- coffee/src/views/controls_view.coffee
+++ coffee/src/views/controls_view.coffee
@@ -95,6 +95,7 @@

 class FullscreenControlView extends IconControlView
   controlName: => 'FullscreenControl'
+  className: @classNameExtend 'fullscreen'
   tooltip: => title: 'Fullscreen', delay: show: 1500
   defaults: => _.extend super,
     icon: 'fullscreen'
@@ -103,6 +104,7 @@

 class EditControlView extends IconControlView
   controlName: => 'EditControl'
+  className: @classNameExtend 'edit'
   tooltip: => title: 'Edit', delay: show: 1500
   defaults: => _.extend super,
     icon: 'edit'
@@ -111,6 +113,7 @@

 class SourcesControlView extends IconControlView
   controlName: => 'SourcesControl'
+  className: @classNameExtend 'sources'
   tooltip: => title: 'Sources', delay: show: 1500
   defaults: => _.extend super,
     icon: 'globe'
@@ -119,6 +122,7 @@

 class PreviousControlView extends IconControlView
   controlName: => 'PreviousControl'
+  className: @classNameExtend 'previous'
   tooltip: => title: 'Previous', delay: show: 1500
   defaults: => _.extend super,
     icon: 'arrow-left'
@@ -127,6 +131,7 @@

 class NextControlView extends IconControlView
   controlName: => 'NextControl'
+  className: @classNameExtend 'next'
   tooltip: => title: 'Next', delay: show: 1500
   defaults: => _.extend super,
     icon: 'arrow-right'
@@ -163,6 +168,7 @@

 class AcornControlView extends ImageControlView
   controlName: => 'AcornControl'
+  className: @classNameExtend 'acorn'
   tooltip: => title: 'Website', delay: show: 1500
   defaults: => _.extend super,
     image: acorn.config.img.acornIcon


Added a return statement for empty content.

--- server/lib/crawler/staticpages/feed.coffee
+++ server/lib/crawler/staticpages/feed.coffee
@@ -42,7 +42,7 @@
           createFullHTML = no
           putBody = no
           createActivityContent JAccount, content, {}, createFullHTML, putBody, (error, content)=>
-            queue.next()  if error or not content
+            return queue.next()  if error or not content
             queue.pageContent = queue.pageContent + content
             queue.next()
         else if contentType is "Topics"


Second attempt to fix this package for mini editors

Found method of selecting the active editor mentioned here: https://discuss.atom.io/t/how-can-we-help-you-write-packages/4268/9

--- lib/compatible-view.coffee
+++ lib/compatible-view.coffee
@@ -7,8 +7,8 @@
       @div "The Test package is Alive! It's ALIVE!", class: "message"

   initialize: (serializeState) ->
-    atom.workspaceView.command "compatible:at", => @at()
-    atom.workspaceView.command "compatible:backslash", => @backslash()
+    atom.workspaceView.command "compatible:at", @at
+    atom.workspaceView.command "compatible:backslash", @backslash

   # Returns an object that can be retrieved when package is activated
   serialize: ->
@@ -17,10 +17,10 @@
   destroy: ->
     @detach()

-  at: ->
-    editor = atom.workspace.getActiveEditor()
+  at: (event) ->
+    editor = event.targetView().editor
     editor.insertText('@') if editor

-  backslash: ->
-    editor = atom.workspace.getActiveEditor()
+  backslash: (event) ->
+    editor = event.targetView().editor
     editor.insertText('\\') if editor


Do the same for nextUnresolved?

Do the same for nextUnresolved?

--- lib/conflict-marker.coffee
+++ lib/conflict-marker.coffee
@@ -137,6 +137,8 @@
         target = firstAfter.navigator.nextUnresolved()
       else
         target = firstAfter
+      return unless target?
+
       @focusConflict target

   previousUnresolved: ->


make syncstring_evaluator use server time for recent query; also perturb timestamp if necessary (this is only a "slightly better" solution to some issue, not a real one)

--- src/smc-util/syncstring_evaluator.coffee
+++ src/smc-util/syncstring_evaluator.coffee
@@ -14,13 +14,13 @@
     constructor: (@string, cb) ->
         query =
             eval_inputs :
-                id    : [@string._string_id, misc.seconds_ago(30)]
+                id    : [@string._string_id, misc.server_seconds_ago(30)]
                 input : null
         @_inputs = @string._client.sync_table(query, {}, 1)

         query =
             eval_outputs :
-                id    : [@string._string_id, misc.seconds_ago(30)]
+                id    : [@string._string_id, misc.server_seconds_ago(30)]
                 output : null
         @_outputs = @string._client.sync_table(query, {}, 1)
         @_outputs.setMaxListeners(100)  # in case of many evaluations at once.
@@ -47,7 +47,15 @@
         if @_closed
             opts.cb?("closed")
             return
-        time = @string._client.server_time()  # TODO: need to perturb time if same as last eval
+        time = @string._client.server_time()
+        # Perturb time if it is <= last time when this client did an evaluation.
+        # We do this so that the time below is different than anything else.
+        # TODO: This is NOT 100% yet, due to multiple clients possibly starting
+        # different evaluations simultaneously.
+        if @_last_time? and time <= @_last_time
+            time = @_last_time + 1
+        @_last_time = time
+
         @_inputs.set
             id    : [@string._string_id, time, 0]
             input : misc.copy_without(opts, 'cb')


Change onMouseHoverShow default to 'Type and Info'

--- lib/haskell-ghc-mod.coffee
+++ lib/haskell-ghc-mod.coffee
@@ -81,7 +81,7 @@

     onMouseHoverShow:
       type: 'string'
-      default: 'Info, fallback to Type'
+      default: 'Type and Info'
       enum:
         [ 'Nothing'
         , 'Type'


:bug: Fix a typo

:bug: Fix a typo

--- lib/linter-registry.coffee
+++ lib/linter-registry.coffee
@@ -53,7 +53,7 @@

   triggerLinter: (linter, editor, scopes) ->
     return new Promise((resolve) =>
-      resolve(linter.lint(@editor))
+      resolve(linter.lint(editor))
     ).then((results) =>
       if results then @emitter.emit('did-update-messages', {linter, messages: results, editor})
     ).catch((e) -> helpers.error(e))


on 'canplay' and 'progress' tests added, todo removed

--- spec/javascripts/audio_element_spec.coffee
+++ spec/javascripts/audio_element_spec.coffee
@@ -25,7 +25,6 @@
     expect($audio).toHandle 'progress'
     expect($audio).toHandle 'canplay'

-  # TODO: Test handlers calls
   it 'handler `loadstart` works correctly', ->
     spyOn no1, 'updateDisabledStatus'
     spyOn no1, 'updateButtonPlay'
@@ -48,5 +47,35 @@
   it 'handler `durationchange` works correctly', ->
     spyOn no1, 'updateTimeStatuses'
     expect(no1.updateTimeStatuses).not.toHaveBeenCalled()
-    $(no1.audio).trigger 'timeupdate'
+    $(no1.audio).trigger 'durationchange'
     expect(no1.updateTimeStatuses).toHaveBeenCalled()
+
+  it 'handler `progress` works correctly', ->
+    spyOn no1, 'redrawBufferizationBars'
+    spyOn no1, 'updateDisabledStatus'
+    expect(no1.redrawBufferizationBars).not.toHaveBeenCalled()
+    expect(no1.updateDisabledStatus).not.toHaveBeenCalled()
+    $(no1.audio).trigger 'progress'
+    expect(no1.redrawBufferizationBars).toHaveBeenCalled()
+    expect(no1.updateDisabledStatus).toHaveBeenCalled()
+
+  it 'handler `canplay` works correctly', ->
+    spyOn no1, 'redrawBufferizationBars'
+    spyOn no1, 'updateDisabledStatus'
+    spyOn no1, 'updateButtonPlay'
+    expect(no1.redrawBufferizationBars).not.toHaveBeenCalled()
+    expect(no1.updateDisabledStatus).not.toHaveBeenCalled()
+    expect(no1.updateButtonPlay).not.toHaveBeenCalled()
+    $(no1.audio).trigger 'canplay'
+    expect(no1.redrawBufferizationBars).toHaveBeenCalled()
+    expect(no1.updateDisabledStatus).toHaveBeenCalled()
+    expect(no1.updateButtonPlay).toHaveBeenCalled()
+
+  it 'handler `canplay` condition works correctly', ->
+    spyOn no1, 'play'
+    no1.options.playOnLoad = false
+    $(no1.audio).trigger 'canplay'
+    expect(no1.play).not.toHaveBeenCalled()
+    no1.options.playOnLoad = true
+    $(no1.audio).trigger 'canplay'
+    expect(no1.play).toHaveBeenCalled()


Fix NewBranchForm spec

Fix NewBranchForm spec

--- spec/javascripts/new_branch_spec.js.coffee
+++ spec/javascripts/new_branch_spec.js.coffee
@@ -1,4 +1,4 @@
-#= require jquery.ui.all
+#= require jquery-ui
 #= require new_branch_form

 describe 'Branch', ->


CSS Text setting text bug fixed

CSS Text setting text bug fixed

--- impl/css/level0/text.coffee
+++ impl/css/level0/text.coffee
@@ -147,7 +147,7 @@
 			# update
 			for item in queue
 				val = item._text
-				if val.indexOf('<') isnt -1
+				if val.indexOf('<') isnt -1 or val.indexOf('&#x') isnt -1
 					item._impl.innerElem.innerHTML = val
 				else
 					item._impl.innerElem.textContent = val


Min support was super min.

Min support was super min.

--- lib/mocha-phantomjs.coffee
+++ lib/mocha-phantomjs.coffee
@@ -171,6 +171,12 @@
         process.cursor.CRCleanup = false
       origLog.call console, string

+class Min extends Reporter
+
+  constructor: ->
+    super 'min'
+
+
 reporterString = system.args[2] || 'spec'
 reporterString = reporterString.charAt(0).toUpperCase() + reporterString.slice(1)
 reporterKlass  = try


Set path to default SSL certificates folder

--- server/config/environment/index.coffee
+++ server/config/environment/index.coffee
@@ -23,8 +23,8 @@

   # SSL Certificates
   ssl:
-    key: process.env.SSL_KEY or 'path-to-key'
-    cert: process.env.SSL_CERT or 'path-to-cert'
+    key: process.env.SSL_KEY or './certs/server.key'
+    cert: process.env.SSL_CERT or './certs/server.crt'

   # Should we populate the DB with sample data?
   seedDB: false


Fix accidental indentation resulting in incorrect offset

--- src/trix/models/selection_manager.coffee
+++ src/trix/models/selection_manager.coffee
@@ -145,7 +145,7 @@
             index++
           else
             currentBlockComment = node
-            offset = 0
+          offset = 0

         if node is targetNode
           if container.nodeType is Node.TEXT_NODE and not nodeIsCursorTarget(node)


Account for shadow dom when asserting active element

--- spec/text-editor-component-spec.coffee
+++ spec/text-editor-component-spec.coffee
@@ -1538,7 +1538,8 @@
     it "transfers focus to the hidden input", ->
       expect(document.activeElement).toBe document.body
       componentNode.focus()
-      expect(document.activeElement).toBe inputNode
+      expect(document.activeElement).toBe wrapperNode
+      expect(wrapperNode.shadowRoot.activeElement).toBe inputNode

     it "adds the 'is-focused' class to the editor when the hidden input is focused", ->
       expect(document.activeElement).toBe document.body


default for non-editors is main, not follow

--- lib/runtime/modules.coffee
+++ lib/runtime/modules.coffee
@@ -57,10 +57,9 @@
     return unless @isValidItem item
     client.require =>
       if (item = atom.workspace.getActivePaneItem())
-        reset = if ised then @autodetect else @follow
-        active = item.juliaModule or reset
+        active = item.juliaModule or (if ised then @autodetect else 'Main')
         modules = allmodules().then (modules) =>
-          modules.unshift reset
+          modules.unshift if ised then @autodetect else @follow
           modules
         selector.show(modules, active: active).then (mod) =>
           return unless mod?


fix bug: cant set correct default date for fullcalendar

--- app/assets/javascripts/controllers/calendar.coffee
+++ app/assets/javascripts/controllers/calendar.coffee
@@ -76,8 +76,8 @@
     # set defaultView, because when we change slotEventOverlap
     # ui-calendar will trigger rerender calendar
     $scope.calendarConfig.defaultView = view.type
-    today = currentMachineEvent or moment().utc().startOf('day')
-    if today > view.start and today <= view.end and today != view.start
+    today = if currentMachineEvent then currentMachineEvent.start else moment().utc().startOf('day')
+    if today > view.start and today < view.end and today != view.start
       $scope.calendarConfig.defaultDate = today
     else
       $scope.calendarConfig.defaultDate = view.start


forgot to put in the functionasdasdasd

forgot to put in the functionasdasdasd

--- app/assets/javascripts/mercury/regions/full.coffee
+++ app/assets/javascripts/mercury/regions/full.coffee
@@ -256,7 +256,7 @@
           remove_attrs = []
           for attr in element[0].attributes
             if attr.specified && (/^data-/).test(attr.name)
-              remove_attrs(attr.name)
+              remove_attrs.push(attr.name)
           for remove_attr in remove_attrs
             element.removeAttr(remove_attr)


[fix] Clear directions if there is no valid waypoints

--- app/assets/javascripts/widgets/direction.js.coffee
+++ app/assets/javascripts/widgets/direction.js.coffee
@@ -20,6 +20,7 @@
 print_has_prompted = false
 ready_to_print = false
 template = false
+directionsRenderer = new google.maps.DirectionsRenderer()

 show_content_window = (marker, content) ->
   if marker.info_window
@@ -252,7 +253,8 @@
       ROUTE = result.routes[0]
       callback(routeToPolygon(ROUTE, search_params.radius))

-      gmap.directionsRenderer.setDirections(result)
+      directionsRenderer.setDirections(result)
+      directionsRenderer.setMap(gmap)
     else
       msg = 'Nie znaleziono trasy! Spróbuj ponownie.'
       if envConfig.development
@@ -424,6 +426,8 @@
             loadRelics search_params

       loadRelics Object.clone(search_params)
+  else
+    directionsRenderer.setMap(null)

   false
 , 50


removed unnecessary parameter

removed unnecessary parameter

--- core/app/backbone/models/wheel.coffee
+++ core/app/backbone/models/wheel.coffee
@@ -65,7 +65,7 @@
     disbelieve: is_user_opinion: false
     doubt:      is_user_opinion: false

-  turnOffActiveOpinionType: (toggle_type) ->
+  turnOffActiveOpinionType: ->
     @updateTo @get("authority"), @turned_off_opinion_types()

   turnOnActiveOpinionType: (toggle_type) ->
@@ -89,12 +89,12 @@
       error: =>
         # TODO: This is not a proper undo. Should be restored to the current
         #       state when the request fails.
-        @turnOffActiveOpinionType opinion_type
+        @turnOffActiveOpinionType()
         options.error?()

   unsetActiveOpinionType: (opinion_type, options={}) ->
     fact_id = @get('fact_id')
-    @turnOffActiveOpinionType opinion_type
+    @turnOffActiveOpinionType()
     $.ajax
       type: "DELETE"
       url: "/facts/#{fact_id}/opinion.json"


Fix truncation

Fix truncation

--- plugins/hipchat/index.coffee
+++ plugins/hipchat/index.coffee
@@ -4,10 +4,17 @@
   HIPCHAT_API_ENDPOINT = "https://api.hipchat.com/v1/rooms/message"

   @receiveEvent: (config, event) ->
-    # Build the message
-    message =  "#{event.trigger.message} from #{event.project.name}" + ( if event.error then " in #{event.error.context} (details)" else "")
-    message += "
   #{event.error.exceptionClass}" + (if event.error.message then ": #{event.error.message.truncate(85)}" else "") if event.error
-    message += "
   #{@firstStacktraceLine(event.error.stacktrace)}" if event.error && event.error.stacktrace
+
+    if event.error
+      # Build the message for error notifications
+      error_string = (event.error.exceptionClass + (if event.error.message then ": #{event.error.message}")).truncate(85)
+
+      message =  "#{event.trigger.message} from #{event.project.name} in #{event.error.context} (details)"
+      message += "
   #{error_string}"
+      message += "
   #{@firstStacktraceLine(event.error.stacktrace)}" if event.error.stacktrace
+    else
+      # Build the message for non-error events
+      message =  "#{event.trigger.message} from #{event.project.name}"

     # Build the request
     params =


payment: extend `JPaymentFulfillmentNonce` from `jraphical.Module`

--- workers/social/lib/social/models/payment/nonce.coffee
+++ workers/social/lib/social/models/payment/nonce.coffee
@@ -1,8 +1,8 @@
-{ Model } = require 'bongo'
+{ Module } = require 'jraphical'

-module.exports = class JPaymentFulfillmentNonce extends Model
+module.exports = class JPaymentFulfillmentNonce extends Module

-  { ObjectId } = require 'bongo'
+  { ObjectId, signature } = require 'bongo'

   @set
     schema       :


test exercises without tags

test exercises without tags

--- test/components/qa/exercises.spec.coffee
+++ test/components/qa/exercises.spec.coffee
@@ -1,4 +1,7 @@
 {Testing, expect, sinon, _, ReactTestUtils} = require '../helpers/component-testing'
+
+ld = require 'lodash'
+

 Exercises = require '../../../src/components/qa/exercises'
 {ExerciseActions, ExerciseStore} = require '../../../src/flux/exercise'
@@ -30,7 +33,8 @@
     Testing.renderComponent( Exercises, props: @props ).then ({dom}) ->
       questions = _.map EXERCISES.items, (e) ->
         e.content.questions[0].stem_html
-      renderedQs = _.pluck dom.querySelectorAll('.panel-body .stem'), 'innerHTML'
+
+      renderedQs = _.pluck dom.querySelectorAll('.panel-body .question-stem'), 'textContent'
       expect(renderedQs).to.deep.equal(questions)

   it 'hides answers when previewing 2-step', ->
@@ -45,3 +49,10 @@
       expect(all.length).to.equal(EXERCISES.items.length)
       expect(hidden.length).to.equal(freeResponseCount)
       expect(hidden[0].querySelector('.answers-table').textContent).to.be.empty
+
+  it 'renders exercises even if they dont have tags', ->
+    ex = ld.cloneDeep EXERCISES
+    _.each ex.items, (e) -> e.content.tags = []
+    ExerciseActions.loadedForCourse(ex, COURSE_ID, ['146'])
+    Testing.renderComponent( Exercises, props: @props ).then ({dom, element}) ->
+      expect( dom.querySelectorAll('.exercise').length ).to.equal(5)


profile: removed unneeded instance variables

--- client/landing/app/MainApp/lazy/staticprofilecontroller.coffee
+++ client/landing/app/MainApp/lazy/staticprofilecontroller.coffee
@@ -408,7 +408,7 @@
     @landingView.listenWindowResize()
     @landingView._windowDidResize = =>
       @landingView.setHeight window.innerHeight
-      @profileContentView.setHeight window.innerHeight-@profileTitleView.getHeight()
+      @profileContentView.setHeight window.innerHeight-profileTitleView.getHeight()

     groupKodingLogo = new KDView
@@ -421,17 +421,7 @@
         else
           @mainController.loginScreen.animateToForm 'login'

-    # groupAvatarDrop = new KDView
-    #   lazyDomId : 'landing-page-avatar-drop'
-    #   tooltip   :
-    #     title   : "Click here to go to Koding"
-    #   click     : =>
-    #     if KD.isLoggedIn()
-    #       @lazyDomController.hideLandingPage()
-    #     else
-    #       @mainController.loginScreen.animateToForm 'login'
-
-    @profileTitleView = new KDView
+    profileTitleView = new KDView
       lazyDomId : 'profile-title'

     @profileShowMoreView = new KDView


profile: removed jogging, cleaned up code

--- client/landing/app/MainApp/lazy/staticprofilecontroller.coffee
+++ client/landing/app/MainApp/lazy/staticprofilecontroller.coffee
@@ -14,10 +14,9 @@

   placeholderBioText      = 'Click here to enter a subtitle'

+
   constructor:(options,data)->
     super options,data
-
-    console.time 'StaticProfileController'

     appManager = @getSingleton 'appManager'

@@ -45,6 +44,7 @@
       unless err
         @reviveViewsOnUserLoad user

+
   attachListeners:->

     @on 'CommentLinkReceivedClick', (view)=>
@@ -102,7 +102,6 @@
         @staticDefaultItem.show()
         @staticPageSettingsButton?.hide()
         callback()
-

     @on 'ActivityLinkClicked', (callback=->)=>
@@ -122,14 +121,9 @@

     @on 'CustomizeLinkClicked',=>
-
-      return if KD.whoami().getId() isnt @profileUser.getId()
-
-      # @avatarAreaIconMenu.emit 'CustomizeLinkClicked'
-
-      # reviving customization
-
-      return if @customizeViewsAttached
+      if (KD.whoami().getId() isnt @profileUser.getId()) or @customizeViewsAttached
+        return
+
       @customizeViewsAttached = yes

       types = @getAllowedTypes @profileUser
@@ -187,6 +181,7 @@
           @lazyDomController.hideLandingPage()
         else
           @mainController.loginScreen.animateToForm 'register'
+

   reviveAdminViews:->

@@ -390,9 +385,8 @@
               new KDNotificationView
                 title   : 'Description updated.'

+
   reviveViewsOnPageLoad:->
-
-    console.time 'reviving page elements on pageload.'

     allowedTypes  = ['CBlogPostActivity']
     blockedTypes  = []
@@ -460,23 +454,6 @@
       click :(event)=>
         if event.target.id is 'profile-personal-wrapper'
           @mainController.emit "landingSidebarClicked"
-
-    #
-    # allow for sidebar lock here!
-    # resize avatar to center or something
-    #
-
-    # @profilePersonalWrapperView.on 'mouseenter',(event)=>
-    #     @profilePersonalWrapperView.setWidth 160
-    #     # @profileContentWrapperView.$().css marginLeft : "160px"
-
-    # @profilePersonalWrapperView.on 'mouseleave',(event)=>
-    #   unless @lockSidebar
-    #     @profilePersonalWrapperView.setWidth 50
-    #     # @profileContentWrapperView.$().css marginLeft : "50px"
-
-    # reviving feed type selectors that will activate feed facets
-

     @staticDefaultItem = new KDView
       lazyDomId : 'profile-blog-default-item'
@@ -506,36 +483,8 @@
         color       : '#444'
     @profileLoaderView.hide()

-    # reviving logo for the slideup animation
-    # @profileLogoInfo = new CustomLinkView
-    #   title : 'Go to Koding.com'
-    #   lazyDomId : 'profile-koding-logo-info'
-
-
-    # @profileLogoWrapperView = new KDView
-    #   lazyDomId: 'profile-koding-logo-wrapper'
-    #   bind : 'mouseenter mouseleave'
-    #   click :=> @emit 'LogoClicked'
-
-    # @profileLogoView = new KDView
-    #   lazyDomId: 'profile-koding-logo'
-
-    # @profileLogoWrapperView.on 'mouseenter', (event)=>
-    #     @profileLogoView.setClass 'with-text'
-    #     @profileLogoInfo.setClass 'in'
-
-    # @profileLogoWrapperView.on 'mouseleave', (event)=>
-    #   @profileLogoView.unsetClass 'with-text'
-    #   @profileLogoInfo.unsetClass 'in'
-
-    # @repositionLogoView()
-
-    console.timeEnd 'reviving page elements on pageload.'
-

   reviveViewsOnUserLoad:(user)->
-
-    console.time 'reviving page elements on userload.'

     @utils.defer => @emit 'HomeLinkClicked'

@@ -547,9 +496,6 @@

     else
       @reviveAdminViews()
-
-    console.timeEnd 'reviving page elements on userload.'
-    console.timeEnd 'StaticProfileController'

   appendActivities:(err,activities, type)->
@@ -581,6 +527,7 @@

   reviveVisitorViews:-> # put onboarding stuff here
+

   displaySidebar:(show=yes,delay=250)->
     @utils.wait delay, =>
@@ -607,6 +554,7 @@
         @showWrapper @wrappers[type]
         callback()

+
   addLogicForType:(type,callback=->)->
     switch type
       when 'activity'
@@ -648,11 +596,11 @@
       , (err,activities)=>
         @appendActivities err,activities,'activity'

-
     @controllers['activity'] = activityController
     @wrappers['activity']    = activityListWrapper

     callback()
+

   addAboutLogic:(callback=->)->

@@ -667,11 +615,10 @@
             about : about or ''
           , @profileUser

-
-
           @wrappers['about'] = aboutWrapper
           @showWrapper aboutWrapper
           callback()
+

   addStaticLogic:(callback=->)->

@@ -707,13 +654,11 @@
     @profileShowMoreView.hide()

     for own name,wrapper of @wrappers
-      # log name, wrapper
       wrapper?.hide?()

   showWrapper:(wrapper)->
     @hideWrappers()
     wrapper.show()
-

@@ -761,6 +706,7 @@
       @getDelegate().emit 'DecorateStaticNavLinks', @getDelegate().getAllowedTypes(@getData())

+
 class StaticHandleLink extends CustomLinkView
   constructor:(options,data)->
     options.cssClass = 'static-handle-link'
@@ -784,6 +730,8 @@
     tmpl += " as #{options.handle}" if options.handle isnt ""

     return tmpl
+
+

 class StaticHandleInput extends KDHitEnterInputView
   constructor:(options,data)->
@@ -791,64 +739,66 @@
     options.defaultValue = data.profile.handles?[options.service] or ''
     super options,data

-class StaticAppsListItem extends KDListItemView
-  partial:(data)->
-    # log data
-    "

-       #{data.title}
-
"
-
-class StaticGroupsListItem extends KDListItemView
-  partial:(data)->
-    # log data
-    "

-       #{data.title}
-
"
-
-class StaticTopicsListItem extends KDListItemView
-  constructor:(options,data)->
-     super options,data
-
-     @titleView = new KDCustomHTMLView
-       tagName : 'span'
-       cssClass : 'static-topic-title'
-       partial : @getData().title
-
-  viewAppended:->
-    super
-    @setTemplate @pistachio()
-    @template.update()
-
-  pistachio:->
-    """
-

-       {{> @titleView}}
-

-    """
-
-class StaticMembersListItem extends KDListItemView
-  constructor:(options,data)->
-    super options,data
-    @avatarView = new AvatarView
-      size    : {width: 30, height: 30}
-      noTooltip : no
-      click:->
-    ,@getData()
-
-    @setClass 'static-member'
-
-  viewAppended:->
-    super
-    @setTemplate @pistachio()
-    @template.update()
-
-  pistachio:->
-    """
-    {{> @avatarView}}
-    """
-
-  # partial:(data)->
-  #   {profile} = data
-  #   "

-  #      #{profile.nickname}
-  #
"
+
+
+# class StaticAppsListItem extends KDListItemView
+#   partial:(data)->
+#     # log data
+#     "

+#        #{data.title}
+#
"
+
+
+
+# class StaticGroupsListItem extends KDListItemView
+#   partial:(data)->
+#     # log data
+#     "

+#        #{data.title}
+#
"
+
+
+
+# class StaticTopicsListItem extends KDListItemView
+#   constructor:(options,data)->
+#      super options,data
+
+#      @titleView = new KDCustomHTMLView
+#        tagName : 'span'
+#        cssClass : 'static-topic-title'
+#        partial : @getData().title
+
+#   viewAppended:->
+#     super
+#     @setTemplate @pistachio()
+#     @template.update()
+
+#   pistachio:->
+#     """
+#

+#        {{> @titleView}}
+#

+#     """
+
+
+
+# class StaticMembersListItem extends KDListItemView
+#   constructor:(options,data)->
+#     super options,data
+#     @avatarView = new AvatarView
+#       size    : {width: 30, height: 30}
+#       noTooltip : no
+#       click:->
+#     ,@getData()
+
+#     @setClass 'static-member'
+
+#   viewAppended:->
+#     super
+#     @setTemplate @pistachio()
+#     @template.update()
+
+#   pistachio:->
+#     """
+#     {{> @avatarView}}
+#     """


Fix actual sending of broadcast events. The eventpublisher never sent any broadcasts, because they were not found from the redis database and therefore were reported as non-existant.

--- lib/event.coffee
+++ lib/event.coffee
@@ -28,8 +28,11 @@
                     cb(null)

     exists: (cb) ->
-        @redis.sismember "events", @name, (err, exists) =>
-            cb(exists)
+        if @name is 'broadcast'
+            cb(true)
+        else
+            @redis.sismember "events", @name, (err, exists) =>
+                cb(exists)

     delete: (cb) ->
         @forEachSubscribers (subscriber, subOptions, done) =>


delete wai-aria initializer because structure of emberui has changed and is no longer relevant

--- addon/initializers/eui-wai-aria-initializer.coffee
+++ addon/initializers/eui-wai-aria-initializer.coffee
@@ -1,16 +0,0 @@
-`import Ember from 'ember'`
-
-waiAria =
-  name: 'emberui-wai-aria',
-
-  initialize: (container) ->
-    Ember.TextSupport.reopen {
-      attributeBindings: [
-        'aria-expanded',
-        'aria-autocomplete',
-        'aria-owns',
-        'aria-activedescendant'
-      ]
-    }
-
-`export default waiAria`


fixed #149

fixed #149

--- _assets/js/_nav.coffee
+++ _assets/js/_nav.coffee
@@ -1,6 +1,10 @@
 # current page indicator on sidebar
 $ ->
   setNavigation()
+  revealNavigation()
+
+$(window).resize ->
+  revealNavigation()

 setNavigation = ->
   baseUrl = "/open-source-club-website" # github repo name
@@ -26,3 +30,21 @@
     return

   return
+
+revealNavigation = ->
+  width = $(window).width()
+  height = $(window).height()
+
+  if width > height and height <= 1000
+    console.log 'foooo'
+    $('#page-content-wrapper').scroll ->
+      if $('#page-content-wrapper').scrollTop() > $('.landing').height()
+        $('.navbar').css 'display', 'none'
+        $('#page-content-wrapper').css('margin-top', '0')
+      else
+        $('.navbar').css 'display', ''
+        $('#page-content-wrapper').css('margin-top', '')
+      return
+  return
+
+


fix jasmine js tests for time duration

fix jasmine js tests for time duration

--- js/tests/inner-tests.coffee
+++ js/tests/inner-tests.coffee
@@ -127,9 +127,9 @@

 j.describe "time works", ->
   j.it "over 1 minute is correct", ->
-    @expect(CI.time.as_duration(1000)).toEqual "1s"
-    @expect(CI.time.as_duration(100000)).toEqual "1m 40s"
-    @expect(CI.time.as_duration(1000000)).toEqual "16m 40s"
+    @expect(CI.time.as_duration(1000)).toEqual "00:01"
+    @expect(CI.time.as_duration(100000)).toEqual "01:40"
+    @expect(CI.time.as_duration(1000000)).toEqual "16:40"

 j.describe "headings get link anchors correctly", ->


Bugfixed adding of comments

Bugfixed adding of comments

At first, the form and model weren't correcly reset, now they are.
Binding happens again when resetting the model.

--- core/app/backbone/views/fact_relations/add_comment_view.coffee
+++ core/app/backbone/views/fact_relations/add_comment_view.coffee
@@ -10,7 +10,6 @@

   initialize: ->
     @initializeModel()
-    @bindTo @model, 'change', @render, @

   parseKeyUp: (e) ->
     code = e.keyCode || e.which
@@ -19,6 +18,7 @@

   initializeModel: ->
     @model = new Comment(content: '', created_by: currentUser)
+    @bindTo @model, 'change', @render, @

   templateHelpers: =>
     type_of_action_text: @type_of_action_text()
@@ -33,15 +33,12 @@
     content = @$('.content').val()
     @model.set {content: content}, silent: true

-  clearForm: -> @setFormContent ''
-
   setFormContent: (content) -> @model.set content: content

   showErrorMessage: -> @$('.js-comment-error-message').show()

   addModelSuccess: (model) ->
     @initializeModel()
-    @clearForm()
     model.trigger 'change'

   addModelError: -> @showErrorMessage()


VariablesView: Remove message view.

VariablesView: Remove message view.

I am not sure this is a proper change. I think we should handle `@messageView.updatePartial stateMessage` in somehow. /cc @gokmen

--- client/admin/lib/views/stacks/variablesview.coffee
+++ client/admin/lib/views/stacks/variablesview.coffee
@@ -25,15 +25,7 @@
     super options, data

     { stackTemplate } = @getOptions()
-
-    @addSubView new KDCustomHTMLView
-      cssClass  : 'text header'
-      partial   : 'Define custom variables here'
-
-    @messageView = @addSubView new KDCustomHTMLView
-      cssClass   : 'message-view'
-
-    @editorView  = @addSubView new VariablesEditorView options
+    @editorView       = @addSubView new VariablesEditorView options

     if cred = stackTemplate?.credentials?.custom?.first
       @reviveCredential cred
@@ -96,8 +88,6 @@
     else
       @indicator.unsetClass 'red'

-
-    @messageView.updatePartial stateMessage
     @_state = newState


test: Add integration tests for setup token feature

--- test/integration/AnvilConnectKeys.coffee
+++ test/integration/AnvilConnectKeys.coffee
@@ -213,3 +213,72 @@
       keys.jwks.keys[1].alg.should.equal 'RS256'
       keys.jwks.keys[1].e.should.equal 'AQAB'
       expect(base64url.toBuffer(keys.jwks.keys[1].n).length).to.equal 512
+
+  describe 'generate setup token (static)', ->
+    {token} = {}
+
+    before ->
+      token = AnvilConnectKeys.generateSetupToken(
+        path.join cwd, 'tmp', 'setup', 'setup.token'
+      )
+
+    it 'should create the token folder if needed', ->
+      expect(dirExists(path.join cwd, 'tmp', 'setup')).to.be.true
+
+    it 'should generate a 256-byte token', ->
+      token.length.should.equal 512
+
+    it 'should return the token', ->
+      token.should.be.a.string
+
+    it 'should save the token', ->
+      fs.readFileSync(
+        path.join(cwd, 'tmp', 'setup', 'setup.token'),
+        'utf8'
+      ).should.equal token
+
+  describe 'load setup token (static)', ->
+    {token} = {}
+
+    before ->
+      token = AnvilConnectKeys.generateSetupToken(
+        path.join cwd, 'tmp', 'setup', 'setup.token'
+      )
+
+    it 'should load and return the token', ->
+      fs.readFileSync(
+        path.join(cwd, 'tmp', 'setup', 'setup.token'),
+        'utf8'
+      ).should.equal token
+
+  describe 'generate setup token (instance)', ->
+    {token} = {}
+
+    before ->
+      connectKeys = new AnvilConnectKeys path.join cwd, 'tmp'
+      token = connectKeys.generateSetupToken()
+
+    it 'should generate a 256-byte token', ->
+      token.length.should.equal 512
+
+    it 'should return the token', ->
+      token.should.be.a.string
+
+    it 'should save the token', ->
+      fs.readFileSync(
+        path.join(cwd, 'tmp', 'keys', 'setup.token'),
+        'utf8'
+      ).should.equal token
+
+  describe 'load setup token (instance)', ->
+    {token} = {}
+
+    before ->
+      connectKeys = new AnvilConnectKeys path.join cwd, 'tmp'
+      token = connectKeys.loadSetupToken()
+
+    it 'should load and return the token', ->
+      fs.readFileSync(
+        path.join(cwd, 'tmp', 'keys', 'setup.token'),
+        'utf8'
+      ).should.equal token


test_scatterplot: small change to make NA regions consistent

--- test/scatterplot/test_scatterplot.coffee
+++ test/scatterplot/test_scatterplot.coffee
@@ -130,6 +130,9 @@
         margin:margin
         xlab:"X3"
         ylab:"X1"
+        xNA_size:
+            width:15
+            gap: 10
         yNA:
             handle:true
             force:true
@@ -149,6 +152,9 @@
         xNA:
             handle:false
             force:false
+        yNA_size:
+            width:15
+            gap: 10
         title: "X2 vs X3"})

     svg = d3.select("div#chart3")


Add resizing to toggled image panel

Add resizing to toggled image panel

--- app/assets/javascripts/panels/image_library.coffee
+++ app/assets/javascripts/panels/image_library.coffee
@@ -7,3 +7,7 @@
     super(null, 'insertMedia', title: 'Image Library', appendTo: '.mercury-toolbar-container', closeButton: true)
     @button = $('.mercury-insertMedia-button')
     @loadContent JST['views/image_library']()
+
+  toggle: ->
+    super
+    @resize() if @visible


[TP-11545] Added the tool to the list of syndicated tools

--- app/assets/javascripts/syndication/tools.js.coffee
+++ app/assets/javascripts/syndication/tools.js.coffee
@@ -335,6 +335,14 @@
       height: "1550px"
       title: 'Workplace Pension Contribution Calculator'

+    money_navigator_tool:
+      en:
+        path: 'en/tools/money-navigator-tool'
+      cy:
+        path: 'cy/tools/teclyn-llywio-ariannol'
+      width: "100%"
+      title: 'Money Navigator'
+
     default_dimensions:
       width: "680px"
       height: "1000px"


Fix weird discussion padding bug.

Fix weird discussion padding bug.

--- app/assets/javascripts/views/wip_event_view.coffee
+++ app/assets/javascripts/views/wip_event_view.coffee
@@ -31,7 +31,7 @@
     JST[template_name]

   render: =>
-    $(@el).html(@template().render(@templateAttributes()))
+    $(@el).replaceWith($(@template().render(@templateAttributes())))
     @$('time').timeago() # display new timestamp
     @


[fix] Change slightly latLng if there is more than one marker on the same spot

--- app/assets/javascripts/widgets/direction.js.coffee
+++ app/assets/javascripts/widgets/direction.js.coffee
@@ -85,13 +85,27 @@
     maxZoom: 18
     styles: styles
     gridSize: 40
+    minimumClusterSize: 4

 renderResults = (search_results, last = true, callback) ->
   total = search_results.length
+  random = ->
+    min = .99999995
+    max = 1.0000005
+    Math.random() * (max - min) + min
   $.each search_results, (index) ->
     [@id, @latitude, @longitude] = this if Object.isArray(this)

     latlng = new google.maps.LatLng(@latitude, @longitude)
+
+    # Workaround for relics without proper location
+    # Change slightly latLng if there is more than one marker on the same spot
+    markerClusterer().getMarkers().each (m) ->
+      if m.position.equals(latlng)
+        newLat = latlng.lat() * random()
+        newLng = latlng.lng() * random()
+        latlng = new google.maps.LatLng(newLat, newLng)
+        return

     marker = new google.maps.Marker
       map: gmap


Add some checks and errors for a failed graft.

--- lib/graft.coffee
+++ lib/graft.coffee
@@ -95,6 +95,8 @@
 ###
 addGraft = (jQuery) ->
   $ = jQuery
+  return false if ! $?.fn?
+
   $.fn.graft = (selector, generators, interceptors) ->
     $original = $base = this
     if $original.is('.template')
@@ -177,16 +179,21 @@

     $base

+  return true
+
 graft = (html, generators, callback) ->
   window = jsdom.jsdom(html).createWindow()
   try
     jsdom.jQueryify window, "#{__dirname}/jquery-1.7.2.js", ->
       jquery = window.jQuery

-      addGraft jquery
-      jquery('html').graft generators, graft.interceptors
-
-      callback null, "#{jquery('html').html()}"
+      result = addGraft jquery
+      if result
+        jquery('html').graft generators, graft.interceptors
+
+        callback null, "#{jquery('html').html()}"
+      else
+        callback 'Failed to link graft into DOM.'
   catch error
     callback error


update.

update.

--- src/main/public/nz/SpriteStatus.coffee
+++ src/main/public/nz/SpriteStatus.coffee
@@ -22,6 +22,9 @@
     @interactive    = true
     @checkHierarchy = true

+    @bgColor = 'blanchedalmond'
+    gaugebBrderColor = 'gray'
+
     @fromJSON
       children:
         bg:
@@ -29,7 +32,8 @@
           width:         @width
           height:        @height
           strokeStyle:   'black'
-          fillStyle:     'blanchedalmond'
+          fillStyle:     @bgColor
+          lineWidth:     1
           shadowBlur:    1
           shadowOffsetX: 2
           shadowOffsetY: 2
@@ -43,20 +47,57 @@
           align:     'left'
           baseline:  'top'
           x:         8
-          y:         8
+          y:         10
           originX:   @originX
           originY:   @originY
-          fontSize:  10
+          fontSize:  8
         action:
           type:      'Label'
           fillStyle: 'black'
           align:     'left'
           baseline:  'top'
           x:         8
-          y:         16
+          y:         20
           originX:   @originX
           originY:   @originY
-          fontSize:  10
+          fontSize:  8
+        hpGauge:
+          type:        'tm.ui.FlatGauge'
+          x:           8
+          y:           32
+          width:       @width - 16
+          height:      4
+          originX:     @originX
+          originY:     @originY
+          borderWidth: 1
+          color:       'blue'
+          bgColor:     @bgColor
+          borderColor: gaugebBrderColor
+        mpGauge:
+          type:        'tm.ui.FlatGauge'
+          x:           8
+          y:           40
+          width:       @width - 16
+          height:      4
+          originX:     @originX
+          originY:     @originY
+          borderWidth: 1
+          color:       'green'
+          bgColor:     @bgColor
+          borderColor: gaugebBrderColor
+        spGauge:
+          type:        'tm.ui.FlatGauge'
+          x:           8
+          y:           48
+          width:       @width - 16
+          height:      4
+          originX:     @originX
+          originY:     @originY
+          borderWidth: 1
+          color:       'Cyan'
+          bgColor:     @bgColor
+          borderColor: gaugebBrderColor
+

     #
     @on 'refreshStatus', (e) ->


Fix bots not being able to create rooms, closes #5318

--- packages/rocketchat-authorization/server/startup.coffee
+++ packages/rocketchat-authorization/server/startup.coffee
@@ -13,9 +13,9 @@
 		{ _id: 'ban-user',                      roles : ['admin', 'owner', 'moderator'] }
 		{ _id: 'bulk-create-c',                 roles : ['admin'] }
 		{ _id: 'bulk-register-user',            roles : ['admin'] }
-		{ _id: 'create-c',                      roles : ['admin', 'user'] }
-		{ _id: 'create-d',                      roles : ['admin', 'user'] }
-		{ _id: 'create-p',                      roles : ['admin', 'user'] }
+		{ _id: 'create-c',                      roles : ['admin', 'user', 'bot'] }
+		{ _id: 'create-d',                      roles : ['admin', 'user', 'bot'] }
+		{ _id: 'create-p',                      roles : ['admin', 'user', 'bot'] }
 		{ _id: 'create-user',                   roles : ['admin'] }
 		{ _id: 'clean-channel-history',         roles : ['admin'] } # special permission to bulk delete a channel's mesages
 		{ _id: 'delete-c',                      roles : ['admin'] }


:bug: guard when blockwiseSelections() is empty

--- lib/hover.coffee
+++ lib/hover.coffee
@@ -19,7 +19,7 @@
       when @vimState.isMode('visual', 'linewise')
         swrap(@editor.getLastSelection()).getCharacterwiseHeadPosition()
       when @vimState.isMode('visual', 'blockwise')
-        @vimState.getLastBlockwiseSelections().getHead().getHeadBufferPosition()
+        @vimState.getLastBlockwiseSelections()?.getHead().getHeadBufferPosition()
       else
         @editor.getCursorBufferPosition()


Fix current view bug

Fix current view bug

--- lib/index.coffee
+++ lib/index.coffee
@@ -17,7 +17,7 @@
     @subscriptions = new CompositeDisposable
     @subscriptions.add atom.commands.add 'atom-workspace', 'magic-console:toggle':
       => @toggle()
-    @view = null
+    @views = []
     @blankRuntime = null
     atom.workspace.addOpener (uriToOpen) =>
       try
@@ -30,17 +30,29 @@
       catch error
         return
       if host is 'editor'
-        @view = new ConsoleRuntimeView(editorId: pathname.substring(1))
-        @subscriptions.add @view.onDidDestroy => @blankRuntime.stop()
         @subscriptions.add @view.onDidSave (ev) =>
+        editorId = pathname.substring(1)
+        view = new ConsoleRuntimeView({editorId})
+        changeCount = view.editor.buffer.changeCount.valueOf()
+        @views = [@views..., view]
+        @subscriptions.add view.onDidDestroy =>
+          @blankRuntime.stop()
+          @views = @views.filter (view) -> view.editorId != editorId
+        @subscriptions.add view.onDidSave (ev) =>
           if atom.config.get 'magic-console.evaluateOnSave'
             @runBlank()
-        @view
+        view
       else
-        @view = new ConsoleRuntimeView(filePath: pathname)
         @subscriptions.add @view.onDidDestroy => @blankRuntime.stop()
         # @subscriptions.add @view.onDidSave (ev) => console.log ev
-        @view
+        filePath = pathname
+        view = new ConsoleRuntimeView({filePath})
+        changeCount = view.editor.buffer.changeCount.valueOf()
+        @views = [@views..., view]
+        @subscriptions.add view.onDidDestroy =>
+          @blankRuntime.stop()
+          @views = @views.filter (view) -> view.filePath != filePath
+        view

   deactivate: ->
     @subscriptions.dispose()
@@ -64,13 +76,13 @@
     throw new Error("Packaged not installed: '#{packageName}'") unless atomPackage?
     atomPackage.activateNow()

-  runBlank: ->
     @view.stop()
     @activatePackage('script')
     if @blankRuntime.observers
       @blankRuntime.observers.forEach (observer) -> observer.destroy()
       @blankRuntime.observers = []
-    @blankRuntime.addObserver(new ConsoleRuntimeObserver(@view))
+  runBlank: (view) ->
+    @blankRuntime.addObserver(new ConsoleRuntimeObserver(view))
     @blankRuntime.execute()

   runDefault: ->
@@ -90,4 +102,4 @@
     atom.workspace.open(uri, split: 'right', searchAllPanes: true).then (consoleRuntimeView) =>
       if consoleRuntimeView instanceof ConsoleRuntimeView
         previousActivePane.activate()
-        @runBlank()
+        @runBlank(consoleRuntimeView)


fix error test for stat check because of newer versions of node

--- lib/index.coffee
+++ lib/index.coffee
@@ -39,7 +39,9 @@
         delete @_stats
         @_stats = fs.statSync @path
       catch error
-        if error.errno is 34 then return
+        # errno is 34 in node 0.10.*
+        # errno is -2 in node 0.12.* and 4.* ... so, use 'code'
+        if error.code is 'ENOENT' then return
         else throw error

   refresh: (done) ->


Update index.coffee

Update index.coffee

--- lib/index.coffee
+++ lib/index.coffee
@@ -1,3 +1,6 @@
+# express = require "express"
+# app = module.exports = express()
+
 util = require "util"
 _ = require "underscore"
 path = require "path"
@@ -19,8 +22,12 @@
   # purposefully make this privatish for now
   @file_name = "nedb-filestore.db"
   @file_path = path.join __dirname, "..", "db"
-
   @memory_store = false
+
+  @cache = {}
+  @cache.store = undefined
+  @cache.gc = true
+  @cache.maxAge = 1000 * 60 * 60

   if @memory_store == false
     @ds = new DataStore filename: path.join @file_path, @file_name
@@ -32,13 +39,13 @@
   if opts? then _.extend @, opts

   # define our route uri w/ version, etc
-  @uri = util.format if @version? then @prefix + @version else @prefix
+  uri = util.format if @version? then @prefix + @version else @prefix

   self = @

   # router, output either our errors or a successful response.
   router = (req, res) ->
-    crudify self.ds, req, (err, resp) ->
+    crudify self.ds, req, self.cache, (err, resp) ->
       if err?
         res.status 400 # throw a bad request out there..
         res.send err # send that error baby :/
@@ -49,10 +56,10 @@
   # will fallback to `req.query` and `req.body`
   if @middleware.length > 0
     for mid in @middleware
-      app.all @uri, mid
-      app.all @uri + "/:id", mid
+      app.all uri, mid
+      app.all uri + "/:id", mid

-  app.all @uri, router
+  app.all uri, router

   # set our app to listen for :id
-  app.all @uri + "/:id", router
+  app.all uri + "/:id", router


remove unnecessary function

remove unnecessary function

--- lib/index.coffee
+++ lib/index.coffee
@@ -9,27 +9,18 @@
 _.mixin understream.exports()
 _.mixin require('underscore.string').exports()

-# This function is synchronous, but the only way that map exposes to return an error is via
-# an asynchronous callback
-delimmed_key_and_obj = (field, delim, [key, obj], cb) ->
-  return cb new Error "join key '#{field}' was not a primitive" if _(key).isObject()
-  hash = JSON.stringify key
-  cb null, hash + delim + obj + '\n'
-
 negate = (predicate) -> (args...) -> not predicate args...
-
 partition = (stream, predicate) ->
   [_.stream(stream).filter(predicate).stream(),
    _.stream(stream).filter(negate predicate).stream()]

+understream.mixin (test, msg) ->
+  _.stream().each (obj, cb) ->
+    return setImmediate cb if test obj
+    setImmediate cb, new Error msg
+  .stream()
+, 'assert', true
 understream.mixin fs.createWriteStream, 'writeFile', true
-understream.mixin (test, msg) ->
-  _.stream()
-    .each (obj, cb) ->
-      return cb() if test obj
-      cb new Error msg
-    .stream()
-, 'assert', true

 # join reference: http://www.albany.edu/~ig4895/join.htm
 module.exports = (left, right, options={}) ->
@@ -45,10 +36,10 @@
   file_names = []
   streams = []
   _([[left, 'left'], [right, 'right']]).each ([stream, stream_type]) ->
-    key = options.on[stream_type]
+    field = options.on[stream_type]
     file_name = path.join os.tmpdir(), "#{Date.now()}'-'#{Math.random().toString().split('.')[1]}.json"
     validated = _(stream).stream().assert(_.isObject, 'received non-object in stream')
-      .map((obj) -> [obj[key], JSON.stringify obj]).stream()
+      .map((obj) -> [obj[field], JSON.stringify obj]).stream()

     [have_join_key, dont_have_join_key] = partition validated, ([key, obj]) -> key?

@@ -66,7 +57,12 @@
       .each (obj) -> head.push obj

     streams.push _(have_join_key).stream()
-      .map((obj, cb) -> setImmediate delimmed_key_and_obj, key, options.delim, obj, cb)
+      .map ([key, obj], cb) ->
+        # This function is synchronous, but the only way that map exposes to return an error is via
+        # an asynchronous callback
+        return setImmediate cb, new Error "join key '#{field}' was not a primitive" if _(key).isObject()
+        hash = JSON.stringify key
+        setImmediate cb, null, hash + options.delim + obj + '\n'
       .writeFile file_name

     file_names.push file_name


unnecessary var

unnecessary var

--- lib/index.coffee
+++ lib/index.coffee
@@ -4,9 +4,9 @@
 async = require 'async'
 debug = require('debug') 'redis-reservation'

-create_redis_client = (host, port) ->
+create_redis_client = _.memoize (host, port) ->
   redis.createClient port, host, { retry_max_delay:100, connect_timeout: 500, max_attempts: 10 }
-memoized_redis_client = _.memoize create_redis_client, (host, port) -> "#{host}:#{port}"
+, (host, port) -> "#{host}:#{port}"

 module.exports = class ReserveResource
   constructor: (@by, @host, @port, @heartbeat_interval, @lock_ttl, @log=console.log) ->
@@ -94,7 +94,7 @@
     # by default client tries to connect forever, fail after half a sec so worker can continue
     # will try again on next job
     unless @_redis?
-      @_redis = memoized_redis_client @host, @port
+      @_redis = create_redis_client @host, @port
       @_redis.once 'error', (err) =>
         @log "RESERVE: Error connecting to REDIS: #{@host}:#{@port}.", err
         throw err


Use new 'while' construct

Use new 'while' construct

--- app/scripts/lazerscripts/stage1/camera_crew.coffee
+++ app/scripts/lazerscripts/stage1/camera_crew.coffee
@@ -40,11 +40,11 @@

   crash: ->
     @sequence(
-      @parallel(
+      @while(
         @movePath [
           [.6, .82]
         ], speed: 150
-        @repeat 12, @sequence(
+        @sequence(
           @explosion(@location(), radius: 10)
           @wait 200
         )


Add push tx call

Add push tx call

--- app/src/restclients/transactions_restclient.coffee
+++ app/src/restclients/transactions_restclient.coffee
@@ -27,8 +27,8 @@

   postTransaction: (transaction, callback) ->
     @http().post
-      url: "blockchain/transactions/send"
-      params: {signed_hex: transaction.getSignedTransaction()}
+      url: "blockchain/pushtx"
+      params: {tx: transaction.getSignedTransaction()}
       onSuccess: (response) ->
         transaction.setHash(response.transaction_hash)
         callback?(transaction)


Correct Mistake in file check

Correct Mistake in file check

--- app/templates/extras/mvc-coffee/model-index.coffee
+++ app/templates/extras/mvc-coffee/model-index.coffee
@@ -9,7 +9,7 @@

 fs.readdirSync(__dirname)
   .filter (file) ->
-    ~file.indexOf('.') and file != 'index.coffee'
+    file.indexOf('.') != 0 and file != 'index.coffee'
   .forEach (file) ->
     model = sequelize.import path.join(__dirname, file)
     db[model.name] = model


Reenabling on surface mouse moved.

Reenabling on surface mouse moved.

--- app/views/editor/level/thangs/ThangsTabView.coffee
+++ app/views/editor/level/thangs/ThangsTabView.coffee
@@ -384,7 +384,7 @@
     return unless @addThangSprite
     wop = @surface.camera.screenToWorld x: e.x, y: e.y
     wop.z = 0.5
-    #@adjustThangPos @addThangSprite, @addThangSprite.thang, wop  # TODO: this and onSpriteDragged both conflictin'
+    @adjustThangPos @addThangSprite, @addThangSprite.thang, wop  # TODO: this and onSpriteDragged both conflictin'
     null

   onSurfaceMouseOver: (e) ->


:art: Remove unnecessary brackets

:art: Remove unnecessary brackets

--- lib/latex.coffee
+++ lib/latex.coffee
@@ -1,7 +1,7 @@
 _ = require 'underscore-plus'
 fs = require 'fs-plus'
 path = require 'path'
-ConfigSchema = require('./config-schema')
+ConfigSchema = require './config-schema'
 LatexmkBuilder = require './builders/latexmk'
 MasterTexFinder = require './master-tex-finder'


KDNotificationView: minor perf fix

KDNotificationView: minor perf fix

--- components/notifications/KDNotificationView.coffee
+++ components/notifications/KDNotificationView.coffee
@@ -11,7 +11,7 @@
     @notificationSetFollowUps   options.followUps     if options.followUps?
     @notificationShowTimer()                          if options.showTimer?
     @notificationSetCloseHandle options.closeManually
-
+
     @once "viewAppended",       @bound "setLoader"    if options.loader

     @notificationDisplay()
@@ -137,7 +137,7 @@

     followUps = [followUps]  unless Array.isArray followUps
     chainDuration = 0
-
+
     followUps.forEach (followUp)=>

       chainDuration += followUp.duration ? 10000
@@ -178,12 +178,13 @@
     @setClass "w-loader"
     {loader} = @getOptions()

-    loader.diameter or= switch @notificationType
-      when "tray"   then 25
-      when "growl"  then 30
-      when "mini"   then 18
-      when "sticky" then 25
-      else               30
+    diameters =
+      tray    : 25
+      growl   : 30
+      mini    : 18
+      sticky  : 25
+
+    loader.diameter = diameters[@notificationType] or 30

     @loader = new KDLoaderView
       size          :
@@ -198,13 +199,14 @@
         FPS         : loader.FPS       ? 24

     @addSubView @loader, null, yes
-    @$().css
-      paddingLeft : loader.diameter*2
-    @loader.$().css
+
+    @setCss "paddingLeft", loader.diameter * 2
+    @loader.setStyle
       position    : "absolute"
       left        : loader.left or Math.floor loader.diameter / 2
       top         : loader.top  or "50%"
       marginTop   : -(loader.diameter/2)
+
     @loader.show()

   showLoader:->


Add default for `Chaplin.Application#initMediator`

--- src/chaplin/application.coffee
+++ src/chaplin/application.coffee
@@ -81,6 +81,15 @@
   initComposer: (options = {}) ->
     @composer = new Composer options

+  # **Chaplin.mediator** is a singleton that serves as the sole communication
+  # channel for all parts of the application. It should be sealed so that its
+  # misuse as a kitchen sink is prohibited. If you do want to give modules
+  # access to some shared resource, however, add it here before sealing the
+  # mediator.
+
+  initMediator: ->
+    Chaplin.mediator.seal()
+
   # **Chaplin.Router** is responsible for observing URL changes. The router
   # is a replacement for Backbone.Router and *does not inherit from it*
   # directly. It's a different implementation with several advantages over


ProjectGetter.findRootDoc moved to mongojs

--- services/web/app/coffee/Features/Project/ProjectLocator.coffee
+++ services/web/app/coffee/Features/Project/ProjectLocator.coffee
@@ -5,7 +5,7 @@
 logger = require('logger-sharelatex')
 async = require('async')

-module.exports =
+module.exports = ProjectLocator =
 	findElement: (options, _callback = (err, element, path, parentFolder)->)->
 		callback = (args...) ->
 			_callback(args...)
@@ -67,7 +67,7 @@
 		if project?
 			getRootDoc project
 		else
-			Project.findById project_id, (err, project)->
+			ProjectGetter.getProject project_id, (err, project)->
 				getRootDoc project

 	findElementByPath: (project_or_id, needlePath, callback = (err, foundEntity)->)->


don't support multiple concurrent activate requests, handle the first, drop until this one finished

--- core/app/backbone/views/auto_completes_view.coffee
+++ core/app/backbone/views/auto_completes_view.coffee
@@ -42,8 +42,11 @@
       @list.splice(i,1)

     view.on 'requestActivate', =>
-      i = @list.indexOf(view)
-      @setActiveAutoComplete(i)
+      unless @alreadyHandlingAnActivate
+        @alreadyHandlingAnActivate = true
+        i = @list.indexOf(view)
+        @setActiveAutoComplete(i)
+        @alreadyHandlingAnActivate = false

     view.on 'requestDeActivate', => @deActivateCurrent()


Solid multitouch support

Solid multitouch support


Fixed typo

Fixed typo

--- source/organism/article.app.coffee
+++ source/organism/article.app.coffee
@@ -31,7 +31,7 @@
   # -- Private Events ----------------------------------------------------------
   fetchVideos: (@page = 0, @filter = {}, @context = "index") ->
     @fetching = true
-gi    __.Entity.Video.destroyAll() if @page is 0
+    __.Entity.Video.destroyAll() if @page is 0
     parameters = page: @page
     parameters.tag = @filter.tag if @filter.tag
     parameters.author = @filter.author if @filter.author


fix chunking strategy tests

fix chunking strategy tests

--- js/test/chunking/DefaultChunkingStrategy-test.coffee
+++ js/test/chunking/DefaultChunkingStrategy-test.coffee
@@ -1,11 +1,11 @@
 # mock data
 # =========

-DATA_LONG = [0...8000].map((i) -> 'a').join('')
+DATA_LONG = [0...1000200].map((i) -> 'a').join('')

 DATA_LONG_SPLIT = [
-  [0...4096].map((i) -> 'a').join(''),
-  [4096...8000].map((i) -> 'a').join('')
+  [0...1000000].map((i) -> 'a').join(''),
+  [1000000...1000200].map((i) -> 'a').join('')
 ]

 # tests
@@ -25,7 +25,7 @@

     describe '#split', ->

-      it 'should split data over 4096 byte intervals', ->
+      it 'should split data over 1,000,000 byte intervals', ->
         chunkingStrategy = new DefaultChunkingStrategy()
         expect(chunkingStrategy.split(DATA_LONG)).toEqual(DATA_LONG_SPLIT)


When clicking the logout button, the user is now actually logged out

--- src/MunKirjat/MainBundle/Resources/coffee/router/Router.coffee
+++ src/MunKirjat/MainBundle/Resources/coffee/router/Router.coffee
@@ -5,6 +5,7 @@
         "frontpage":        "frontpage"
         "about":            "about"
         "login":            "login"
+        "logout":            "logout"
         "author":           "author"
         "author/:id":       "getAuthor"
         "authors":          "listAuthors"
@@ -52,6 +53,9 @@
         @preDispatch()
         @dispatcher.trigger "url:changed", 'primary-menu-login'
         @loginView.show()
+
+    logout: () ->
+        window.location.href = Routing.getBaseUrl() + "/logout"

     author: () ->
         @preDispatch()
@@ -102,6 +106,7 @@
         @preDispatch()
         @dispatcher.trigger "url:changed", 'primary-menu-list-books'
         @bookListView.reset().show(authorId)
+
     search: () ->
         @preDispatch()
         @dispatcher.trigger "url:changed", 'primary-menu-search'


cleanup console

cleanup console

--- src/components/vocabulary.cjsx
+++ src/components/vocabulary.cjsx
@@ -17,8 +17,6 @@
     location: React.PropTypes.object

   setTerm: (ev) ->
-    console.log @getVocabId(), ev.target.value
-
     VocabularyActions.change(@getVocabId(), term: ev.target.value)

   setDefinition: (ev) ->
@@ -27,7 +25,6 @@
   update: -> @forceUpdate()

   componentWillMount: ->
-    console.log 'mount'
     VocabularyStore.addChangeListener(@update)
     @loadIfNeeded( @getVocabId() )


Add back "is 'test'"

Add back "is 'test'"

--- lib/token.coffee
+++ lib/token.coffee
@@ -24,7 +24,7 @@

   @deployContract: ->
     output = run "node_modules/.bin/truffle migrate --network #{nodeEnv}
-      --reset --verbose-rpc", relaxed: true, quiet: nodeEnv
+      --reset --verbose-rpc", relaxed: true, quiet: nodeEnv is 'test'

     pattern = ///#{CONTRACT_NAME}:\s(0x[0-9a-f]{40})///
     contractAddress = pattern.exec(output)?[1]


Fix issue when deleting trend

Fix issue when deleting trend

--- src/components/common/trends-list/trends-list.component.coffee
+++ src/components/common/trends-list/trends-list.component.coffee
@@ -60,8 +60,7 @@
             _.property('trends'),
             _.partialRight(_.some, { id: this.entity.id })
           ))
-          trend = _.find(trendGroup.trends, 'id', this.entity.id)
-          trendGroup.trends.splice(_.findIndex(trendGroup.trends, {id: trendGroup.id}), 1)
+          trendGroup.trends.splice(_.findIndex(trendGroup.trends, {id: this.entity.id}), 1)
         ctrl.originalGroups = _.map(ctrl.groups, _.cloneDeep)
         this.cancel()


Left a comment for group changes

Left a comment for group changes

--- admin/static/coffee/servers/datacenter.coffee
+++ admin/static/coffee/servers/datacenter.coffee
@@ -395,7 +395,7 @@
         on_submit: =>
             super

-            # For when /ajax will handle post request
+            # That creates huge logs. Should post specific data multiple times instead?
             data = {}
             data['datacenters'] = {}
             for datacenter in datacenters.models


Confirm before remove a block

Confirm before remove a block

--- src/js/faber/controllers/BlockController.coffee
+++ src/js/faber/controllers/BlockController.coffee
@@ -68,7 +68,8 @@

   # Remove a child block
   $scope.remove = (block)->
-    $scope.block.blocks.splice($scope.block.blocks.indexOf(block), 1)
+    if confirm 'Are you sure you want to permanently remove this block?\n\nYou can’t undo this action.'
+      $scope.block.blocks.splice($scope.block.blocks.indexOf(block), 1)

   # Insert a child block to the given index
   $scope.insert = (index, block)->


Refactor to jquery

Refactor to jquery

--- lib/assets/javascripts/moe-legacy/history.coffee
+++ lib/assets/javascripts/moe-legacy/history.coffee
@@ -1,23 +1,29 @@
+$ = jQuery
+
 window.History =
   last_click: -1
   checked: []
   dragging: false
+
+
   init: ->
-    # Watch mousedown events on the table itself, so clicking between table rows and dragging
-    # doesn't misbehave.
-    $('history').observe 'mousedown', ((event) ->
+    # Watch mousedown events on the table itself, so clicking between table rows
+    # and dragging doesn't misbehave.
+    $('#history').on 'mousedown', (event) ->
       if !event.shiftKey
-        # Clear last_click, so dragging will extend from the next position crossed instead of
-        # the previous position clicked.
+        # Clear last_click, so dragging will extend from the next position
+        # crossed instead of the previous position clicked.
         History.last_click = -1
       History.mouse_is_down()
       event.stopPropagation()
       event.preventDefault()
-      return
-    ), true
+
     History.update()
-    return
+
+
   add_change: (change_id, group_by_type, group_by_id, ids, user_id) ->
+    row = $("#r#{change_id}")
+
     History.checked.push
       id: change_id
       ids: ids
@@ -25,160 +31,176 @@
       group_by_id: group_by_id
       user_id: user_id
       on: false
-      row: $('r' + change_id)
-    $('r' + change_id).observe 'mousedown', (e) ->
+      row: row
+
+    row.on 'mousedown', (e) ->
       History.mousedown(change_id, e)
-      true
-      return
-    $('r' + change_id).observe 'mouseover', (e) ->
+
+    row.on 'mouseover', (e) ->
       History.mouseover(change_id, e)
-      true
-      return
-    if $('r' + change_id).down('.id')
-      $('r' + change_id).down('.id').observe 'click', (event) ->
-        History.id_click change_id
-        return
-    $('r' + change_id).down('.author').observe 'click', (event) ->
+
+    row.find('.id').on 'click', (event) ->
+      History.id_click change_id
+
+    row.find('.author').on 'click', (event) ->
       History.author_click change_id
-      return
-    $('r' + change_id).down('.change').observe 'click', (event) ->
+
+    row.find('.change').on 'click', (event) ->
       History.change_click change_id
-      return
-    return
+
+
   update: ->
     # Set selected flags on selected rows, and remove them from unselected rows.
-    i = 0
-    while i < History.checked.length
-      row = History.checked[i].row
-      if History.checked[i].on
-        row.addClassName 'selected'
+    for entry in History.checked
+      row = entry.row
+      if entry.on
+        row.addClass 'selected'
       else
-        row.removeClassName 'selected'
-      ++i
+        row.removeClass 'selected'
+
     if History.count_selected() > 0
-      $('undo').removeClassName 'footer-disabled'
-      $('redo').removeClassName 'footer-disabled'
+      $('#undo').removeClass 'footer-disabled'
+      $('#redo').removeClass 'footer-disabled'
     else
-      $('undo').addClassName 'footer-disabled'
-      $('redo').addClassName 'footer-disabled'
-    return
-  id_click: (id, event) ->
+      $('#undo').addClass 'footer-disabled'
+      $('#redo').addClass 'footer-disabled'
+
+
+
+  id_click: (id) ->
     id = History.get_row_by_id(id)
-    $('search').value = History.checked[id].group_by_type.toLowerCase() + ':' + History.checked[id].group_by_id
-    return
-  author_click: (id, event) ->
+    entry = History.checked[id]
+    $('#search').val "#{entry.group_by_type.toLowerCase()}:#{entry.group_by_id}"
+
+
+  author_click: (id) ->
     id = History.get_row_by_id(id)
-    $('search').value = 'user:' + History.checked[id].user_id
-    return
-  change_click: (id, event) ->
+    $('#search').val "user:#{History.checked[id].user_id}"
+
+
+  change_click: (id) ->
     id = History.get_row_by_id(id)
-    $('search').value = 'change:' + History.checked[id].id
-    return
+    $('#search').val "change:#{History.checked[id].id}"
+
+
   count_selected: ->
     ret = 0
-    i = 0
-    while i < History.checked.length
-      if History.checked[i].on
-        ++ret
-      ++i
+    ret++ for entry in History.checked when entry.on
+
     ret
+
+
   get_first_selected_row: ->
-    i = 0
-    while i < History.checked.length
-      if History.checked[i].on
-        return i
-      ++i
+    return i for entry, i in History.checked when entry.on
+
+    # nothing found, return null
     null
+
+
   get_row_by_id: (id) ->
-    i = 0
-    while i < History.checked.length
-      if History.checked[i].id.toString() == id.toString()
-        return i
-      ++i
+    for entry, i in History.checked
+      return i if entry.id.toString() == id.toString()
+
+    # nothing found, return -1
     -1
+
+
   set: (first, last, isOn) ->
-    i = first
-    loop
-      History.checked[i].on = isOn
-      if i.toString() == last.toString()
-        break
-      i += if last > first then +1 else -1
-    return
+    first = parseInt(first, 10)
+    last = parseInt(last, 10)
+
+    [first, last] = [last, first] if last < first
+
+    for entry in History.checked[first..last]
+      entry.on = isOn
+
+
   doc_mouseup: (event) ->
     History.dragging = false
-    document.stopObserving 'mouseup', History.doc_mouseup
-    return
+    $(document).off 'mouseup', History.doc_mouseup
+
+
   mouse_is_down: ->
     History.dragging = true
-    document.observe 'mouseup', History.doc_mouseup
-    return
+    $(document).on 'mouseup', History.doc_mouseup
+
+
   mousedown: (id, event) ->
-    if !Event.isLeftClick(event)
-      return
+    # only for primary click
+    return if event.which != 1
+
     History.mouse_is_down()
     i = History.get_row_by_id(id)
-    if i == -1
-      return
+
+    # no row found?
+    return if i == -1
+
     first = null
     last = null
-    if History.last_click != -1 and event.shiftKey
+
+    if History.last_click != -1 && event.shiftKey
       first = History.last_click
       last = i
     else
       first = last = History.last_click = i
       History.checked[i].on = !History.checked[i].on
+
     isOn = History.checked[first].on
+
     if !event.ctrlKey
       History.set 0, History.checked.length - 1, false
     History.set first, last, isOn
     History.update()
+
     event.stopPropagation()
     event.preventDefault()
-    return
+
+
   mouseover: (id, event) ->
     i = History.get_row_by_id(id)
-    if i == -1
-      return
+
+    return if i == -1
+
     if History.last_click == -1
       History.last_click = i
-    if !History.dragging
-      return
+
+    return if !History.dragging
+
     History.set 0, History.checked.length - 1, false
     first = History.last_click
     last = i
     this_click = i
     History.set first, last, true
     History.update()
-    return
+
+
   undo: (redo) ->
-    if History.count_selected() == 0
-      return
+    return if History.count_selected() == 0
+
     list = []
-    i = 0
-    while i < History.checked.length
-      if !History.checked[i].on
-        ++i
-        continue
-      list = list.concat(History.checked[i].ids)
-      ++i
+
+    for entry in History.checked
+      list = list.concat(entry.ids) if entry.on
+
     if redo
       notice 'Reapplying...'
     else
       notice 'Undoing...'
-    new (Ajax.Request)('/history/undo.json',
-      requestHeaders: 'X-CSRF-Token': jQuery('meta[name=csrf-token]').attr('content')
-      parameters:
-        'id': list.join(',')
-        'redo': if redo then 1 else 0
-      onComplete: (resp) ->
-        resp = resp.responseJSON
-        if resp.success
-          text = resp.errors
-          if resp.successful > 0
-            text.unshift if redo then 'Changes reapplied.' else 'Changes undone.'
-          notice text.join('
')
-        else
-          notice 'Error: ' + resp.reason
-        return
-)
-    return
+
+    $.ajax '/history/undo.json',
+      method: 'POST'
+      dataType: 'json'
+      data:
+        id: list.join(',')
+        redo: if redo then 1 else 0
+    .done (resp) ->
+      text = resp.errors
+
+      if resp.successful > 0
+        mainMessage = "Changes #{if redo then 'reapplied' else 'undone'}."
+        text.unshift mainMessage
+
+      notice text.join('
')
+
+    .fail (resp) ->
+      notice "Error: #{resp.reason}"


Modified in browser at pixie.strd6.com

Modified in browser at pixie.strd6.com

--- test/movable.coffee
+++ test/movable.coffee
@@ -24,4 +24,15 @@

   ok particle.I.velocity.magnitude() <= particle.I.maxSpeed, "magnitude of the velocity should not exceed maxSpeed"

+test "should increase velocity according to acceleration", ->
+  particle = GameObject
+    velocity: Point(7, 4)
+    acceleration: Point(1, -0.3)
+
+  4.times ->
+    particle.update()
+
+  equals, particle.I.velocity.x, 11
+  equals, particle.I.velocity.y, 2.8
+
 module()


fix debug function

fix debug function

--- lib/utils.coffee
+++ lib/utils.coffee
@@ -42,7 +42,7 @@
     when 'file'
       filePath = fs.normalize settings.get('debugOutputFilePath')
       if fs.existsSync(filePath)
-        fs.appendFileSync filePath, messages
+        fs.appendFileSync filePath, messages + "\n"

 getView = (model) ->
   atom.views.getView(model)


tiny bugfix for last change

tiny bugfix for last change

--- lib/utils.coffee
+++ lib/utils.coffee
@@ -296,7 +296,7 @@
           # Let's strip the “}” character from our original line, for later use.
           line = line.replace blockStrip, '$1'
           # Also strip it from our `blockline`.
-          blockline = blockline[foldPrefix.length...]
+          blockline = blockline[ignorePrefix.length...]

       # This flag is triggered above.
       if inBlock


Docs: Define functions used in loop examples (#4653)

* Cherrypick changes from messy branch

* Reorder function defs

--- documentation/examples/array_comprehensions.coffee
+++ documentation/examples/array_comprehensions.coffee
@@ -1,8 +1,10 @@
 # Eat lunch.
+eat = (food) -> "#{food} eaten."
 eat food for food in ['toast', 'cheese', 'wine']

 # Fine five course dining.
 courses = ['greens', 'caviar', 'truffles', 'roast', 'cake']
+menu = (i, dish) -> "Menu Item #{i}: #{dish}"
 menu i + 1, dish for dish, i in courses

 # Health conscious meal.


part1

--- app/assets/javascripts/oxalis/view/gui.coffee
+++ app/assets/javascripts/oxalis/view/gui.coffee
@@ -58,12 +58,6 @@

     @folders = []

-    @folders.push( fControls = @gui.addFolder("Controls") )
-    @addCheckbox(fControls, @user.getSettings(), "inverseX", "Inverse X")
-    @addCheckbox(fControls, @user.getSettings(), "inverseY", "Inverse Y")
-    @addSlider(fControls, @user.getSettings(), "keyboardDelay",
-      0, 500, 10, "Keyboard delay (ms)" )
-
     @folders.push( @fViewportcontrols = @gui.addFolder("Viewportoptions") )
     @moveValueController = @addSlider(@fViewportcontrols, @user.getSettings(), "moveValue",
       constants.MIN_MOVE_VALUE, constants.MAX_MOVE_VALUE, 10, "Move Value (nm/s)")
@@ -72,6 +66,12 @@
     @scaleController = @addSlider(@fViewportcontrols, @user.getSettings(), "scale", constants.MIN_SCALE,
       constants.MAX_SCALE, 0.1, "Viewport Scale")
     @addCheckbox(@fViewportcontrols, @user.getSettings(), "dynamicSpaceDirection", "d/f-Switching")
+
+    @folders.push( fControls = @gui.addFolder("Controls") )
+    @addCheckbox(fControls, @user.getSettings(), "inverseX", "Inverse X")
+    @addCheckbox(fControls, @user.getSettings(), "inverseY", "Inverse Y")
+    @addSlider(fControls, @user.getSettings(), "keyboardDelay",
+      0, 500, 10, "Keyboard delay (ms)" )

     @folders.push( @fFlightcontrols = @gui.addFolder("Flightoptions") )
     @addSlider(@fFlightcontrols, @user.getSettings(), "mouseRotateValue",


Remove unused variables and classes

Remove unused variables and classes

--- resources/assets/coffee/react/contest/voting/art-entry.coffee
+++ resources/assets/coffee/react/contest/voting/art-entry.coffee
@@ -20,12 +20,6 @@
 el = React.createElement

 class Contest.Voting.ArtEntry extends React.Component
-  constructor: (props) ->
-    super props
-
-    @voter = React.createRef
-
-
   render: ->
     votingOver = moment(@props.contest.voting_ends_at).diff() <= 0
     isSelected = _.includes @props.selected, @props.entry.id
@@ -40,7 +34,6 @@
       top3 = place <= 3

     divClasses = [
-      'js-contest-vote-entry'
       'contest-art-entry',
       'contest-art-entry--result' if showVotes,
       "contest-art-entry--placed contest-art-entry--placed-#{place}" if showVotes && top3,


Reset fs port

Reset fs port

--- lib/integrated-learn-environment.coffee
+++ lib/integrated-learn-environment.coffee
@@ -38,7 +38,7 @@
       workspaceView = atom.views.getView(atom.workspace)
       atom.commands.dispatch(workspaceView, 'tree-view:toggle')

-    @fs = new SyncedFS("wss://ile.learn.co:3000?token=" + @oauthToken, isTerminalWindow)
+    @fs = new SyncedFS("wss://ile.learn.co:4464?token=" + @oauthToken, isTerminalWindow)
     @fsViewEmitter = new EventEmitter
     @fsView = new SyncedFSView(state, @fs, @fsViewEmitter, isTerminalWindow)


Grammary shortcut

Grammary shortcut

--- lib/videojs-HTML5-niconicoplayer.coffee
+++ lib/videojs-HTML5-niconicoplayer.coffee
@@ -204,7 +204,7 @@
           commentEl.style.left = commentOffset + 'px'

           for color in colors
-            if chat.styles.indexOf(color) isnt -1
+            if color in chat.styles
               commentEl.className += ' ' + color

           lineEndTimes[index] = chat.vpos / 100 + settings.commentPostTime


for simplicity keep the cutoff time the same while flushing the queue

--- services/document-updater/app/coffee/DeleteQueueManager.coffee
+++ services/document-updater/app/coffee/DeleteQueueManager.coffee
@@ -22,6 +22,7 @@
 module.exports = DeleteQueueManager =
     flushAndDeleteOldProjects: (options, callback) ->
         startTime = Date.now()
+        cutoffTime = startTime - options.min_delete_age
         count = 0

         flushProjectIfNotModified = (project_id, flushTimestamp, cb) ->
@@ -49,7 +50,6 @@
             if count > options.limit
                 logger.log "hit count limit on flushing old projects"
                 return callback()
-            cutoffTime = now - options.min_delete_age
             RedisManager.getNextProjectToFlushAndDelete cutoffTime, (err, project_id, flushTimestamp, queueLength) ->
                 return callback(err) if err?
                 return callback() if !project_id?


avoid exception on pdfPage destroy

avoid exception on pdfPage destroy

--- services/web/public/coffee/ide/pdfng/directives/pdfPage.coffee
+++ services/web/public/coffee/ide/pdfng/directives/pdfPage.coffee
@@ -108,7 +108,7 @@
 					, 1000

 				scope.$on "$destroy", () ->
-					if scope.timeoutHandler
+					if scope.timeoutHandler?
 						$timeout.cancel(scope.timeoutHandler)
 						highlightsLayer.clearHighlights()


FIX: Update add comment within Task

FIX: Update add comment within Task

--- src/app/common/services/project-service.coffee
+++ src/app/common/services/project-service.coffee
@@ -3,7 +3,7 @@
 #
 # Service for handling projects
 #
-.factory("projectService", ($filter, $http, taskService, Project, $rootScope, alertService, Task, Visualisation, gradeService, TeachingPeriod, DoubtfireConstants) ->
+.factory("projectService", ($filter, $http, taskService, Project, $rootScope, alertService, Task, Visualisation, gradeService, TeachingPeriod, DoubtfireConstants, TaskCommentService) ->
   projectService = {}

   injectFunctionalityInProject = (project) ->
@@ -191,7 +191,10 @@
     task.group = ->
       projectService.getGroupForTask(task.project(), task)
     task.addComment = (textString, success, failure) ->
-      taskService.addComment(task, textString, success, failure)
+      TaskCommentService.addComment(task, textString).subscribe(
+        (tc) -> success(tc)
+        (error) -> failure(error)
+      )
     task.scrollCommentsToBottom = ->
       taskService.scrollDown()
     task.applyForExtension = (reason, weeksRequested, onSuccess, onError) ->


fix team selection

fix team selection

--- src-public/settings/directives/select-people/controller.coffee
+++ src-public/settings/directives/select-people/controller.coffee
@@ -6,7 +6,7 @@
     team = []
     for key, checked of $scope.teamCheck
       if checked
-        team.push _.find $scope.members, (member) -> member.id
+        team.push _.find $scope.members, (member) -> member.id == key
     $scope.selectedMembers = team

   $scope.$watch 'selectedMembers', (newVal) ->


Fix for DOMAttrModified client side.

Fix for DOMAttrModified client side.

--- lib/client/socketio_client.coffee
+++ lib/client/socketio_client.coffee
@@ -127,7 +127,8 @@

     DOMAttrModified : (args) ->
         target = @nodes.get(args.target)
-        name = args.name
+        name = args.attrName
+        value = args.newValue
         if target.clientSpecific
             return if name == 'value'
         if args.attrChange == 'ADDITION'
@@ -135,11 +136,11 @@
             if /^selected$|^selectedIndex$|^value$|^checked$/.test(name)
                 # Calling setAttribute doesn't cause the displayed value to change,
                 # but setting it as a property does.
-                target[name] = args.value
+                target[name] = value
             else
-                target.setAttribute(args.name, args.value)
+                target.setAttribute(name, value)
         else if args.attrChange == 'REMOVAL'
-            target.removeAttribute(args.name)
+            target.removeAttribute(name)
         else
             throw new Error("Invalid attrChange: #{args.attrChange}")


fixes

fixes

--- apps/game/assets/js/keyboard_shortcuts.coffee
+++ apps/game/assets/js/keyboard_shortcuts.coffee
@@ -1,4 +1,4 @@
-$(document.body).keypress (event) ->
+$(document.body).bind 'keyup', (event) ->
   return unless event.srcElement.localName is 'body'
   return if event.altKey or event.ctrlKey or event.metaKey or event.shiftKey
   switch event.keyCode


Revert "ExperimentResults: super double quote keys"

This reverts commit 736238c89c6a386bfce3f9acc75d0eecb76745cc.

--- src/components/experiment_results/index.coffee
+++ src/components/experiment_results/index.coffee
@@ -29,7 +29,7 @@
               "\"#{experiment.key}\"='#{choice}'"
             else
               experimentFilter = _.map(experiment.apps, (app) ->
-                "\"\\\"#{app}_#{experiment.key}\\\"\"='#{choice}'"
+                "\"#{app}_#{experiment.key}\"='#{choice}'"
               ).join(' OR ')
               "(#{experimentFilter})"


Removed unused code.

Removed unused code.

--- lib/helpers/authentication.coffee
+++ lib/helpers/authentication.coffee
@@ -8,20 +8,10 @@
 log = require './log'
 User = require '../model/user'

-find = (token, cb)->
-  log.debug 'AUTH Got called'
-  User.findWithToken(token).then (user)->
-    cb(null, true, user: user, token: token)
-  .fail (err)->
-    cb(null, false)
-  .done()
-
 module.exports = (server)->
   deferred = Q.defer()
-  log.debug 'auth 1'
   server.register require('hapi-auth-bearer-token'), (err)->
     return deferred.reject(err) if err
-    log.debug 'auth 2'
     server.auth.strategy(
       'token',
       'bearer-access-token',


fixes

fixes

--- packages/rocketchat-ui/lib/chatMessages.coffee
+++ packages/rocketchat-ui/lib/chatMessages.coffee
@@ -25,7 +25,6 @@
 		return -1

 	recordInputAsDraft: () ->
-		console.log(this.editing)
 		id = this.editing.id
 		record = this.records[id] || {}
 		draft = this.input.value
@@ -41,8 +40,12 @@
 		record.original = message.msg
 		this.records[message._id] = record

-	getMessageDraft: (id) -> return this.records[id]
-	clearMessageDraft: (id) -> delete this.records[id]
+	getMessageDraft: (id) ->
+		return this.records[id]
+
+	clearMessageDraft: (id) ->
+		delete this.records[id]
+
 	clearCurrentDraft: () ->
 		this.clearMessageDraft this.editing.id


Support native keybndings in installed package view

--- lib/installed-package-view.coffee
+++ lib/installed-package-view.coffee
@@ -20,7 +20,7 @@
         @span outlet: 'updateLabel', class: 'icon icon-squirrel update-message'
         @span outlet: 'updateLink', class: 'alert-link update-link icon icon-cloud-download', 'Install'

-      @h3 =>
+      @h3 class: 'native-key-bindings', tabindex: -1, =>
         @span outlet: 'title', class: 'text'
         @span ' '
         @span outlet: 'version', class: 'label label-primary'
@@ -28,8 +28,8 @@
         @span outlet: 'disabledLabel', class: 'label label-warning', 'Disabled'

       @p outlet: 'packageRepo', class: 'link icon icon-repo repo-link'
-      @p outlet: 'description', class: 'text-subtle'
-      @p outlet: 'startupTime', class: 'text-subtle icon icon-dashboard'
+      @p outlet: 'description', class: 'text-subtle native-key-bindings', tabindex: -1
+      @p outlet: 'startupTime', class: 'text-subtle icon icon-dashboard native-key-bindings', tabindex: -1

       @div outlet: 'buttons', class: 'btn-group', =>
         @button outlet: 'disableButton', class: 'btn btn-default icon'


switching ResourceClient by argument

switching ResourceClient by argument

--- src/lib/base-repository.coffee
+++ src/lib/base-repository.coffee
@@ -60,10 +60,12 @@
     @method save
     @public
     @param {Entity} entity
+    @param {ResourceClientInterface} [client=@client]
     @return {Promise<Entity>} entity (different instance from input)
     ###
-    save: (entity) ->
-        @client.upsert(entity).then (obj) =>
+    save: (entity, client) ->
+        client ?= @client
+        client.upsert(entity).then (obj) =>
             return @factory.createFromObject(obj)

@@ -73,10 +75,12 @@
     @method get
     @public
     @param {any} id
+    @param {ResourceClientInterface} [client=@client]
     @return {Promise<Entity>} entity
     ###
-    get: (id) ->
-        @client.findById(id).then (obj) =>
+    get: (id, client) ->
+        client ?= @client
+        client.findById(id).then (obj) =>
             return @factory.createFromObject(obj)

@@ -87,10 +91,12 @@
     @method query
     @public
     @param {Object} [params] query parameters
+    @param {ResourceClientInterface} [client=@client]
     @return {Promise<Array>} array of entities
     ###
-    query: (params) ->
-        @client.find(params).then (objs) =>
+    query: (params, client) ->
+        client ?= @client
+        client.find(params).then (objs) =>
             return (@factory.createFromObject(obj) for obj in objs)

@@ -100,10 +106,12 @@
     @method singleQuery
     @public
     @param {Object} [params] query parameters
+    @param {ResourceClientInterface} [client=@client]
     @return {Promise<Entity>} entity
     ###
-    singleQuery: (params) ->
-        @client.findOne(params).then (obj) =>
+    singleQuery: (params, client) ->
+        client ?= @client
+        client.findOne(params).then (obj) =>
             return @factory.createFromObject(obj)

@@ -114,10 +122,12 @@
     @method delete
     @public
     @param {Entity} entity
+    @param {ResourceClientInterface} [client=@client]
     @return {Promise<Boolean>} isDeleted
     ###
-    delete: (entity) ->
-        @client.destroyById(entity.id).then =>
+    delete: (entity, client) ->
+        client ?= @client
+        client.destroyById(entity.id).then =>
             return true

@@ -128,10 +138,12 @@
     @public
     @param {any} id id of the entity to update
     @param {Object} data key-value pair to update
+    @param {ResourceClientInterface} [client=@client]
     @return {Promise<Entity>} updated entity
     ###
-    update: (id, data) ->
-        @client.updateAttributes(id, data).then (obj) =>
+    update: (id, data, client) ->
+        client ?= @client
+        client.updateAttributes(id, data).then (obj) =>
             return @factory.createFromObject(obj)


update fatal view after fetching issue

update fatal view after fetching issue

--- lib/notifications-log-item.coffee
+++ lib/notifications-log-item.coffee
@@ -10,7 +10,12 @@

   render: ->
     # TODO: should probably create new element instead of cloning
-    atomNotification = atom.views.getView(@notification).element.cloneNode(true)
+    notificationView = atom.views.getView(@notification)
+    notificationElement = @renderNotification(notificationView)
+
+    if @notification.getType() is 'fatal'
+      notificationView.getRenderPromise().then =>
+        @element.replaceChild(@renderNotification(notificationView), notificationElement)

     @timestamp = document.createElement('div')
     @timestamp.classList.add('timestamp')
@@ -19,9 +24,12 @@

     @element = document.createElement('li')
     @element.classList.add('notifications-log-item', @notification.getType())
-    @element.appendChild(atomNotification)
+    @element.appendChild(notificationElement)
     @element.appendChild(@timestamp)
     @element.addEventListener('click', => @emitter.emit 'click')
+
+  renderNotification: (view) ->
+    view.element.cloneNode(true)

   getElement: -> @element


Build command

Build command

--- src/js/app/compilers/teascript/compiler.coffee
+++ src/js/app/compilers/teascript/compiler.coffee
@@ -5697,6 +5697,9 @@
   # types: typeEnumaration ctx
   errors: errors

+compileModule = (moduleName = '@unnamed') ->
+  js: library + immutable + (listOfLines map lookupJs, (setToArray runtimeDependencies moduleName))
+
 compileExpression = (source, moduleName = '@unnamed') ->
   ast = (astFromSource "(#{source})", -1, -1)
   if _empty _validTerms ast
@@ -7510,6 +7513,7 @@

 exports.compileTopLevel = compileTopLevel
+exports.compileModule = compileModule
 exports.compileExpression = compileExpression
 exports.findAvailableTypes = findAvailableTypes
 exports.findMatchingDefinitions = findMatchingDefinitions
@@ -7523,13 +7527,6 @@
 exports.plainPrettyPrint = plainPrettyPrint
 exports.labelDocs = labelDocs
 exports.builtInLibraryNumLines = library.split('\n').length + immutable.split('\n').length
-
-# exports.compileModule = (source) ->
-#   """
-#   #{library}
-#   var exports = {};
-#   #{compileDefinitionsInModule source}
-#   exports"""

 exports.library = library