Add a test for sorting admin products by name

--- spec/javascripts/unit/admin/bulk_product_update_spec.js.coffee
+++ spec/javascripts/unit/admin/bulk_product_update_spec.js.coffee
@@ -357,6 +357,15 @@
     it "resets dirtyProducts", ->
       expect(DirtyProducts.clear).toHaveBeenCalled()

+  describe "sorting products", ->
+    it "sorts products", ->
+      spyOn $scope, "fetchProducts"
+
+      $scope.sortOptions.toggle('name')
+      $scope.$apply()
+
+      expect($scope.q.sorting).toEqual 'name asc'
+      expect($scope.fetchProducts).toHaveBeenCalled()

   describe "updating the product on hand count", ->
     it "updates when product is not available on demand", ->


Don't emit events when arrays are empty

Don't emit events when arrays are empty

--- lib/directory.coffee
+++ lib/directory.coffee
@@ -123,14 +123,16 @@

       newEntries.push(entry) if entry?

-    for name, entry of removedEntries
-      entry.destroy()
-      delete @entries[name]
-      delete @expandedEntries[name]
-    @emit 'entries-removed', removedEntries
+    if removedEntries.length > 0
+      for name, entry of removedEntries
+        entry.destroy()
+        delete @entries[name]
+        delete @expandedEntries[name]
+      @emit 'entries-removed', removedEntries

-    @entries[entry.name] = entry for entry in newEntries
-    @emit 'entries-added', newEntries
+    if newEntries.length > 0
+      @entries[entry.name] = entry for entry in newEntries
+      @emit 'entries-added', newEntries

   # Public: Collapse this directory and stop watching it.
   collapse: ->


:memo: Add missing it

:memo: Add missing it

--- lib/directory.coffee
+++ lib/directory.coffee
@@ -133,7 +133,7 @@
     @expandedEntries = @serializeExpansionStates()
     @unwatch()

-  # Public: Expand this directory, load its children, and start watching for
+  # Public: Expand this directory, load its children, and start watching it for
   # changes.
   expand: ->
     @isExpanded = true


Remove completed sdss_lost_set

Remove completed sdss_lost_set

--- app/models/subject.coffee
+++ app/models/subject.coffee
@@ -98,11 +98,7 @@
   # stop working until a user of the app informs the developer and the developer then has time to fix the error.
   # For iPhone apps there will also be a delay until the updated App is approved.
   @randomSurveyId: ->
-    n = Math.random()
-    if n <= (0.333)
-      @::surveys.sdss_lost_set.id
-    else
-      @::surveys.gama12.id
+    @::surveys.gama12.id

   @next: ->
     if @current


Add defensive checks

Add defensive checks

--- client/ide/lib/index.coffee
+++ client/ide/lib/index.coffee
@@ -792,7 +792,10 @@
   resizeAllSplitViews: ->

     parents = []
-    @ideViews.forEach (view) -> parents.push view.parent?.parent
+    @ideViews.forEach (view) ->
+      parent = view.parent?.parent
+      if parent and parent instanceof kd.SplitView
+        parents.push parent

     _.uniq(parents, 'id').forEach (p) -> p._windowDidResize()


Fix: latent type error in listSelection

Fix: latent type error in listSelection

--- lib/list-edit.coffee
+++ lib/list-edit.coffee
@@ -187,7 +187,7 @@
         atom.notifications.addWarning 'Selection is not in well-formed list.'
       else
         listSelection = TextManipulation.getSelectionForRange elementList.elts, selectionIxRange
-        if listSelection.end > elementList.elts.length
+        if listSelection[1] > elementList.elts.length
           atom.notifications.addError 'INTERNAL ERROR: list selection end outside list.'
           # Note: Will not occur, just for easily signaling bugs during development.
         else


use underscore string for allows

use underscore string for allows

--- models/block.coffee
+++ models/block.coffee
@@ -5,6 +5,7 @@
 Base = require "./base.coffee"
 sd = require("sharify").data
 _ = require 'underscore'
+_s = require 'underscore.string'

 module.exports = class Block extends Base

@@ -65,7 +66,7 @@
     @get('user').id is user.id

   allows: (permission, user) ->
-    _.include @getPermissions(user), permission
+    _s.include @getPermissions(user), permission

   connectedByCurrentUser: (user)->
     @get('connected_by_user_id') is user.id


Groups: searchMembers is called for searching members (disabled autocomplete feature)

--- client/Dashboard/views/groupsmemberpermissionsview.coffee
+++ client/Dashboard/views/groupsmemberpermissionsview.coffee
@@ -88,10 +88,11 @@
       skip  : @skip

     if @_searchValue
+      selector = @_searchValue
       {JAccount} = KD.remote.api
-      JAccount.byRelevance @_searchValue, options, (err, members)=> @populateMembers err, members
     else
-      @getData().fetchMembers {}, options, (err, members)=> @populateMembers err, members
+      selector = ""
+    @getData().searchMembers selector, options, (err, members)=> @populateMembers err, members

   populateMembers:(err, members)->
     instantiateItems = (err) =>


Rename JApp to JNewApp to be able to use same db for both resurrection and master when we need.

--- client/landing/Intro/_old_Home/Views/featuredviews.coffee
+++ client/landing/Intro/_old_Home/Views/featuredviews.coffee
@@ -77,7 +77,7 @@
           avatarWidth  :250
           avatarHeight :250

-    KD.remote.api.JApp.some {},{limit:4},(err,apps)=>
+    KD.remote.api.JNewApp.some {},{limit:4},(err,apps)=>
       if err then warn err
       else if apps
         appsController.instantiateListItems apps


Added overlay support for introduction tooltips.

--- client/landing/app/CommonViews/introductiontooltip.coffee
+++ client/landing/app/CommonViews/introductiontooltip.coffee
@@ -48,7 +48,7 @@
             item.expiryDate = snippet.expiryDate
             @createInstance null, item

-        # @addOverlay() if @shouldAddOverlay and @visibleTooltips.length > 0
+        @addOverlay() if @shouldAddOverlay and @visibleTooltips.length > 0

   createInstance: (parentView, data) ->
     assets = @getAssets parentView, data
@@ -115,3 +115,8 @@
     @overlay.hide()
     @overlay.appendTo "body"
     @overlay.fadeIn 200
+    @overlay.bind "click", =>
+      for tooltipInstance in @visibleTooltips
+        tooltipInstance.getOptions().parentView.tooltip?.destroy()
+      @overlay.remove()
+      @visibleTooltips.length = 0


Missed updating a method name

Missed updating a method name

--- lib/assets/javascripts/cable/connection.coffee
+++ lib/assets/javascripts/cable/connection.coffee
@@ -55,7 +55,7 @@
       {identifier, message, type} = JSON.parse(event.data)

       if type?
-        @handleTypeMessage(type)
+        @onTypeMessage(type)
       else
         @consumer.subscriptions.notify(identifier, "received", message)


fix setting author in create command

fix setting author in create command

--- lib/cli.coffee
+++ lib/cli.coffee
@@ -318,8 +318,7 @@
           config = CSON.parseFileSync config_path
           config.id = id
           config.version = version
-          config.author.name = user.name
-          config.author.email = user.email
+          config.author = {name: user.name, email: user.email}
           config.developers = {}
           config.developers[user.admin_uid] = 'admin'
           config = CSON.stringifySync(config).replace /\n\n/g, '\n'


fixed category in dataset list

fixed category in dataset list

--- app/assets/javascripts/admin/views/dataset/dataset_list_item_view.coffee
+++ app/assets/javascripts/admin/views/dataset/dataset_list_item_view.coffee
@@ -42,7 +42,7 @@

     <% _.map(dataSource.dataLayers, function(layer){ %>
-        <%= layer.typ %> - <%= layer.elementClass %>
+        <%= layer.category %> - <%= layer.elementClass %>
     <% }) %>

       <% if(dataSource.needsImport){ %>


Extends from @Table and notify user actions

--- app/assets/javascripts/georgia_mailer/components/message_table.js.coffee
+++ app/assets/javascripts/georgia_mailer/components/message_table.js.coffee
@@ -1,28 +1,25 @@
-class @MessagesTable
+class @MessagesTable extends @Table

-  constructor: (element) ->
-    @element          = $(element)
-    @checkboxes       = @element.find("input:checkbox")
-    @deleteBtn        = @element.find('.js-delete')
-    @spamBtn          = @element.find('.js-spam')
-    @hamBtn           = @element.find('.js-ham')
+  constructor: (element, checkboxable) ->
+    super(element, checkboxable)
+    @deleteBtn  = @element.find('.js-delete')
+    @spamBtn    = @element.find('.js-spam')
+    @hamBtn     = @element.find('.js-ham')
     @setBindings()

   setBindings: () =>
-    @checkboxes.on('change', @update)
     @deleteBtn.on('click', @delete)
     @spamBtn.on('click', @spam)
     @hamBtn.on('click', @ham)
-
-  update: () =>
-    if @getChecked().length then @enableActions() else @disableActions()

   delete: (event) =>
     @stopEvent(event)
     $.ajax(
       url: "/admin/messages/#{@getIds()}"
       type: 'DELETE'
-    )
+      dataType: "JSON"
+      success: @removeMessages
+    ).always(@notify)

   spam: (event) =>
     @stopEvent(event)
@@ -30,9 +27,8 @@
       type: "POST"
       dataType: "JSON"
       url: "/admin/messages/#{@getIds()}/spam"
-      success: (data) =>
-        $.each data, (i, message_id) => @removeMessage(message_id)
-    )
+      success: @removeMessages
+    ).always(@notify)

   ham: (event) =>
     @stopEvent(event)
@@ -40,9 +36,11 @@
       type: "POST"
       dataType: "JSON"
       url: "/admin/messages/#{@getIds()}/ham"
-      success: (data) =>
-        $.each data, (i, message_id) => @removeMessage(message_id)
-    )
+      success: @removeMessages
+    ).always(@notify)
+
+  removeMessages: () =>
+    $.each @getIds(), (i, message_id) => @removeMessage(message_id)

   removeMessage: (message_id) ->
     $("tr#message_#{message_id}").remove();
@@ -57,17 +55,10 @@
     @hamBtn.addClass('disabled').removeClass('btn-warning')
     @deleteBtn.addClass('disabled').removeClass('btn-danger')

-  stopEvent: (event) ->
-    event.stopPropagation()
-    event.preventDefault()
-
-  getChecked: () => @element.find("input:checkbox:checked[data-checkbox='child']")
-  getId:      (c) => $(c).data('id')
-  getIds:     () => $.map(@getChecked(), (c) => @getId(c))
-
 $.fn.actsAsMessagesTable = () ->
   @each ->
-    new MessagesTable($(this))
+    checkboxable = new Checkboxable($(this))
+    new MessagesTable($(this), checkboxable)

 jQuery ->
   $("table.messages.js-checkboxable").each ->


make multi serial search work with spaces

--- app/assets/javascripts/views/stolen/stolen_multi_serial_search.js.coffee
+++ app/assets/javascripts/views/stolen/stolen_multi_serial_search.js.coffee
@@ -16,6 +16,9 @@

   trim = (str) ->
     str.replace(/^\s\s*/, "").replace /\s\s*$/, ""
+
+  idify = (str) ->
+    str.replace(/[^a-z0-9]/g, "_")

   toggleMultiSearch: (e=null) ->
     e.preventDefault() if e?
@@ -78,8 +81,8 @@
     s_i.addClass('ms-match').removeClass('ms-nomatch')
     unless s_i.find('a').length > 0
       # make the li a link, add the returned bikes container
-      s_i.append("")
-      $('#bikes_returned').append("

")
+      s_i.append("")
+      $('#bikes_returned').append("

")
     s_i.find('a').addClass('blink-class')
     setTimeout (->
       s_i.find('a').removeClass('blink-class')
@@ -92,7 +95,7 @@
       html = "

"
     html += "#{serial} - #{results} results
"
     html += "
#{@bikeList(bikes)}

"
-    $("##{serial}").append(html)
+    $("##{idify(serial)}").append(html)

   searchSerialsFuzzy: (event) ->
     event.preventDefault()


git.coffee: Always call stdout, even if code != 0

--- lib/git.coffee
+++ lib/git.coffee
@@ -23,9 +23,8 @@
       @save ?= ''
       @save += data
     exit = (exit) ->
-      if exit is 0
-        c_stdout @save ?= ''
-        @save = null
+      c_stdout @save ?= ''
+      @save = null

   new BufferedProcess
     command: command


more refactoring

more refactoring

--- lib/job.coffee
+++ lib/job.coffee
@@ -3,7 +3,7 @@
 class Job extends Stream
   constructor: (@gearman, @name, @payload) ->
     @timeoutTimer = null
-    @gearman.sendCommand "SUBMIT_JOB", @name, false, @payload, @receiveHandle.bind(@)
+    @gearman.sendCommand "SUBMIT_JOB", @name, false, @payload, @receiveHandle.bind @

   setTimeout: (timeout, timeoutCallback) ->
     @timeoutValue = timeout
@@ -13,7 +13,7 @@
   updateTimeout: () ->
     return if not @timeoutValue
     clearTimeout @timeoutTimer
-    @timeoutTimer = setTimeout(@onTimeout.bind(@), @timeoutValue)
+    @timeoutTimer = setTimeout (@onTimeout.bind @), @timeoutValue

   onTimeout: () ->
     delete @gearman.currentJobs[@handle] if @handle
@@ -30,10 +30,10 @@
     @aborted = true

   receiveHandle: (handle) ->
-    if handle
-      @handle = handle
-      @gearman.currentJobs[handle] = @
-    else
+    if not handle
       @emit "error", new Error("Invalid response from server")
+      return
+    @handle = handle
+    @gearman.currentJobs[handle] = @

 module.exports = Job


add ts to filename

add ts to filename

--- lib/nap.coffee
+++ lib/nap.coffee
@@ -135,7 +135,7 @@
 # Runs through all of the asset packages. Concatenates, minifies, and gzips them. Then outputs
 # the final packages. (To be run once during the build step for production)

-module.exports.package = (callback = ->) =>
+module.exports.package = (ts, callback = ->) =>

   clearAssetsDir()

@@ -147,7 +147,7 @@
       contents = (contents for fn, contents of preprocessPkg pkg, 'js').join(';\n')
       contents = uglify contents if @mode is 'production' and @minify
       fingerprint = '-' + fingerprintForPkg('js', pkg)
-      filename = "#{pkg}.js"
+      filename = "#{pkg}-#{ts}.js"
       writeFile filename, contents, (err) =>
         if @gzip then gzipPkg(contents, filename, callback) else callback()
         total++
@@ -159,7 +159,7 @@
       ).join('')
       contents = sqwish.minify contents if @mode is 'production'
       fingerprint = '-' + fingerprintForPkg('css', pkg)
-      filename = "#{pkg}.css"
+      filename = "#{pkg}-#{ts}.css"
       writeFile filename, contents, (err) =>
         if @gzip then gzipPkg(contents, filename, callback) else callback()
         total++
@@ -170,7 +170,7 @@
       contents = @_tmplPrefix + contents
       contents = uglify contents if @mode is 'production' and @minify
       fingerprint = '-' + fingerprintForPkg('jst', pkg)
-      filename = "#{pkg}.jst.js"
+      filename = "#{pkg}-#{ts}.jst.js"
       writeFile filename , contents, (err) =>
         if @gzip then gzipPkg(contents, filename, callback) else callback()
         total++


fixed appDir assignment after use

fixed appDir assignment after use

--- lib/nap.coffee
+++ lib/nap.coffee
@@ -28,10 +28,10 @@
     throw new Error "You must specify an 'assets' obj with keys 'js', 'css', or 'jst'"
   @assets = _.clone options.assets
   @originalAssets = _.clone options.assets
+  @appDir = (if options.appDir? then options.appDir else process.cwd())
   expandAssetGlobs()

   # Config defaults
-  @appDir = (if options.appDir? then options.appDir else process.cwd())
   @publicDir = path.resolve(@appDir, options.publicDir || 'public')
   @mode = options.mode ? switch process.env.NODE_ENV
     when 'staging' then 'production'


Fixed when request to not declared endpoint

--- lib/zen.coffee
+++ lib/zen.coffee
@@ -108,7 +108,7 @@
             break

         for use in @middleware when not response.headersSent
-          if endpoint.handler or use.system
+          if endpoint?.handler or use.system
             use.callback.apply @, [request, response, next]

         if match


Fix node 10 build
It is introducing an inconsistent using fs.writeFile

Based in the documentation, the callback of the method just return an error,
but right now it is returning a second argument, always a

--- lib/Bumped.util.coffee
+++ lib/Bumped.util.coffee
@@ -54,7 +54,7 @@

   saveConfig: (opts, cb) ->
     data = serializer opts.data
-    fs.writeFile opts.path, data, encoding: 'utf8', cb
+    fs.writeFile opts.path, data, encoding: 'utf8', (err) -> cb(err)

   isBoolean: (n) ->
     typeof n is 'boolean'


Remove from core presumptuous Underscore templateSettings configuration.

--- src/js/jquery.extension.hlf.core.coffee
+++ src/js/jquery.extension.hlf.core.coffee
@@ -14,8 +14,6 @@
     ], extension
   else extension jQuery, _
 )(($, _) ->
-
-  _.templateSettings = interpolate: /\{\{(.+?)\}\}/g

   hlf =
     debug: on # Turn this off when going to production.


CoreFunctions: Refactor fromEach and select to be transform stream functions

--- src/main/functions/CoreFunctions.coffee
+++ src/main/functions/CoreFunctions.coffee
@@ -2,15 +2,17 @@
 _ = require 'lodash'
 ReactiveRunner = require '../runtime/ReactiveRunner'

-transform = (fn) -> fn.kind = 'transform'; fn
+#transform = (fn) -> fn.kind = 'transform'; fn
 transformStream = (fn) -> fn.kind = ReactiveRunner.TRANSFORM_STREAM; fn
 aggregate = (fn) -> fn.returnKind = ReactiveRunner.AGGREGATE_RETURN; fn
 sequence = (fn) -> fn.returnKind = ReactiveRunner.SEQUENCE_RETURN; fn
 streamReturn = (fn) -> fn.returnKind = ReactiveRunner.STREAM_RETURN; fn
+apply = (funcOrValue, x) -> if typeof funcOrValue == 'function' then funcOrValue(x) else funcOrValue

 module.exports = {
-  fromEach: transform (seq, func) -> (func(x) for x in seq)
-  select: transform (seq, func) -> (x for x in seq when func(x))
+  fromEach: transformStream (s, func) -> s.map (x) -> apply(func, x)
+  select: transformStream (s, func) -> s.filter (x) -> apply(func, x)
+
   shuffle: (seq) -> _.shuffle seq

   count: aggregate (seq) -> seq.scan 0, (acc, x) -> acc + 1


Rename.

Rename.

--- migrations/007-add-reminders-reminder_time-index.coffee
+++ migrations/007-add-reminders-reminder_time-index.coffee
@@ -1,9 +0,0 @@
-db = require '../lib/db'
-
-exports.up = (next) ->
-	query = "CREATE INDEX reminders_reminder_time ON reminders (reminder_time)"
-	db.query query, next
-
-exports.down = (next) ->
-	query = "DROP INDEX reminders_reminder_time"
-	db.query query, next


Improve fix for issue #136 incorrect indent of non-JSX rows following JSX.

--- lib/auto-indent.coffee
+++ lib/auto-indent.coffee
@@ -249,9 +249,7 @@
             if parentTagIdx >= 0 then tagStack[parentTagIdx].termsThisTagsAttributesIdx = idxOfTags
             idxOfTags++

-      scopes = @editor.scopeDescriptorForBufferPosition([row, 0]).getScopesArray()
-
-      if idxOfTags > 0 and not tagOnThisLine and 'meta.tag.jsx' in scopes
+      if idxOfTags > 0 and not tagOnThisLine and  row isnt range.end.row
         if tagStack[idxOfTags-1].type is JSXTAG_CLOSE_ATTRS or
           tagStack[idxOfTags-1].type is JSXTAG_CLOSE or
           tagStack[idxOfTags-1].type is JSXTAG_SELFCLOSE_END


Drop automatic feature require

Drop automatic feature require

This forced projects to store their features in the root of
their code. Which was not great for all project structures.
fixes #22

--- src/dill.coffee
+++ src/dill.coffee
@@ -3,9 +3,6 @@
   timeStart = new Date().getTime()
   process.argv.push "--require"
   process.argv.push "#{lib}/support"
-
-  process.argv.push "--require"
-  process.argv.push "features"

   require('./environment')()
   require(require.resolve('cucumber').replace /lib\/cucumber\.js$/, 'bin/cucumber.js')


Relation user into campaign creation

Relation user into campaign creation

--- lib/collections.coffee
+++ lib/collections.coffee
@@ -36,6 +36,11 @@
 	user:
 		type: Object
 		label: 'Criado por'
+		autoValue: ->
+			return {
+				_id: @userId
+				name: Users.findOne(@userId).profile.name
+			}
 	'user._id':
 		type: String
 	'user.name':


fixed coffeelint errors on workers/social/lib/social/models/computeproviders/koding.coffee

--- workers/social/lib/social/models/computeproviders/koding.coffee
+++ workers/social/lib/social/models/computeproviders/koding.coffee
@@ -5,7 +5,7 @@
 KodingError       = require '../../error'

 Regions           = require 'koding-regions'
-{argv}            = require 'optimist'
+{ argv }          = require 'optimist'
 KONFIG            = require('koding-config-manager').load("main.#{argv.c}")

 SUPPORTED_REGIONS = ['us-east-1', 'eu-west-1', 'ap-southeast-1', 'us-west-2']
@@ -14,9 +14,9 @@

   @providerSlug = 'koding'

-  @ping = (client, options, callback)->
-
-    {nickname} = client.r.account.profile
+  @ping = (client, options, callback) ->
+
+    { nickname } = client.r.account.profile
     callback null, "#{ @providerSlug } is the best #{ nickname }!"

@@ -25,7 +25,7 @@
    * @param {String=} options.snapshotId - The unique snapshotId to create
    *   this machine from, if any.
   ###
-  @create = (client, options, callback)->
+  @create = (client, options, callback) ->

     { instanceType, label, storage, region, snapshotId } = options
     { r: { group, user, account }, clientIP } = client
@@ -49,7 +49,7 @@
       fetchUserPlan client, (err, userPlan) ->
         return callback err  if err

-        fetchUsage client, {provider}, (err, usage) ->
+        fetchUsage client, { provider }, (err, usage) ->
           return callback err  if err

           if err = checkUsage usage, userPlan, storage
@@ -82,7 +82,7 @@
             callback null, { meta, label, credential: client.r.user.username }

-  @postCreate = (client, options, callback)->
+  @postCreate = (client, options, callback) ->

     { r: { account } } = client
     { machine } = options
@@ -95,14 +95,14 @@
       JWorkspace.createDefault client, machine.uid, callback

-  @update = (client, options, callback)->
+  @update = (client, options, callback) ->

     { machineId, alwaysOn, resize } = options
     { r: { group, user, account } } = client

     unless machineId? or alwaysOn?
       return callback new KodingError \
-        "A valid machineId and an update option required.", "WrongParameter"
+        'A valid machineId and an update option required.', 'WrongParameter'

     provider = @providerSlug

@@ -110,18 +110,18 @@

     { fetchUserPlan, fetchUsage } = require './computeutils'

-    fetchUserPlan client, (err, userPlan)=>
+    fetchUserPlan client, (err, userPlan) ->

       return callback err  if err?

-      fetchUsage client, {provider}, (err, usage)->
+      fetchUsage client, { provider }, (err, usage) ->

         return callback err  if err?

         if alwaysOn and usage.alwaysOn >= userPlan.alwaysOn
           return callback new KodingError \
             """Total limit of #{userPlan.alwaysOn}
-               always on vm limit has been reached.""", "UsageLimitReached"
+               always on vm limit has been reached.""", 'UsageLimitReached'

         if resize?
           resize = +resize
@@ -132,10 +132,10 @@
           else if resize > userPlan.storage
             return callback new KodingError \
             """Requested new size exceeds allowed
-               limit of #{userPlan.storage}GB.""", "UsageLimitReached"
+               limit of #{userPlan.storage}GB.""", 'UsageLimitReached'
           else if resize < 3
             return callback new KodingError \
-            """New size can't be less than 3GB.""", "WrongParameter"
+            """New size can't be less than 3GB.""", 'WrongParameter'

         { ObjectId } = require 'bongo'

@@ -144,13 +144,19 @@
             { _id : ObjectId machineId }
             { uid : machineId }
           ]
-          users   : $elemMatch: id: user.getId(), sudo: yes, owner: yes
-          groups  : $elemMatch: id: group.getId()
-
-        JMachine.one selector, (err, machine)->
+          users        :
+            $elemMatch :
+              id       : user.getId()
+              sudo     : yes
+              owner    : yes
+          groups       :
+            $elemMatch :
+              id       : group.getId()
+
+        JMachine.one selector, (err, machine) ->

           if err? or not machine?
-            err ?= new KodingError "Machine object not found."
+            err ?= new KodingError 'Machine object not found.'
             return callback err

           fieldsToUpdate = {}
@@ -165,11 +171,11 @@
             if (resize - storageSize) + usage.storage > userPlan.storage
               return callback new KodingError \
               """Requested new size exceeds allowed
-                 limit of #{userPlan.storage}GB.""", "UsageLimitReached"
-            else if resize == machine.getAt 'meta.storage_size'
+                 limit of #{userPlan.storage}GB.""", 'UsageLimitReached'
+            else if resize is machine.getAt 'meta.storage_size'
               return callback new KodingError \
               """Requested new size is same with current
-                 storage size (#{resize}GB).""", "SameValueForResize"
+                 storage size (#{resize}GB).""", 'SameValueForResize'

             fieldsToUpdate['meta.storage_size'] = resize

@@ -177,10 +183,10 @@

             $set: fieldsToUpdate

-          , (err)-> callback err
-
-
-  @fetchAvailable = (client, options, callback)->
+          , (err) -> callback err
+
+
+  @fetchAvailable = (client, options, callback) ->

     callback null, [
       {
@@ -192,3 +198,5 @@
         price : 'free'
       }
     ]
+
+


:lipstick: fix styles for review.

:lipstick: fix styles for review.

--- src/file.coffee
+++ src/file.coffee
@@ -135,6 +135,7 @@
   # Sets the path for the file.
   setPath: (@path) ->
     @realPath = null
+
   # Public: Sets the file encoding name.
   setEncoding: (@encoding) ->

@@ -171,8 +172,8 @@
     if not @exists()
       @cachedContents = null
     else if not @cachedContents? or flushCache
-      content = fs.readFileSync @getPath()
-      @cachedContents = iconv.decode content, @getEncoding()
+      contents = fs.readFileSync @getPath()
+      @cachedContents = iconv.decode contents, @getEncoding()

     @setDigest(@cachedContents)
     @cachedContents
@@ -230,8 +231,8 @@
   # permission to the path.
   writeFileWithPrivilegeEscalationSync: (filePath, text) ->
     try
-      content = iconv.encode text, @getEncoding()
-      fs.writeFileSync(filePath, content, encoding: null)
+      contents = iconv.encode text, @getEncoding()
+      fs.writeFileSync filePath, contents
     catch error
       if error.code is 'EACCES' and process.platform is 'darwin'
         runas ?= require 'runas'


Don't track any impressions or experiments for homepage entry hub if user is logged in (mobile web)

--- src/mobile/apps/home/client/view.coffee
+++ src/mobile/apps/home/client/view.coffee
@@ -21,13 +21,15 @@

   initialize: ->
     @collection = new ShowsFeed
-    if sd.HOMEPAGE_COLLECTION_HUB_ENTRYPOINTS_TEST == "experiment"
-      analytics.track("Impression", {
-        context_page: "Home",
-        context_module: "HubEntrypoint",
-        subject: "Featured Categories",
-      })
-    splitTest("homepage_collection_hub_entrypoints_test").view()
+
+    if !sd.CURRENT_USER
+      if sd.HOMEPAGE_COLLECTION_HUB_ENTRYPOINTS_TEST == "experiment"
+        analytics.track("Impression", {
+          context_page: "Home",
+          context_module: "HubEntrypoint",
+          subject: "Featured Categories",
+        })
+      splitTest("homepage_collection_hub_entrypoints_test").view()

     @slideshow = new Flickity '#carousel-track',
       cellAlign: 'left'


More improvements to #entries tag

More improvements to #entries tag

Filter by slug, add simple sorting

--- server/lib/renderer.coffee
+++ server/lib/renderer.coffee
@@ -16,33 +16,36 @@

     # Add the entries helper
     hbs.registerAsyncHelper 'entries', (options, cb) ->
-      _.defaults options.hash,
+      settings = _.defaults options.hash,
         bucket: ''
         until: Date.now()
         since: ''
         limit: 10
         skip: 0
-        sort: ''
-        sort_by: 'date_posted'
-        sort_dir: 'desc'
+        sort: '-publishDate'
         status: 'live'
         find: ''
+        slug: null

       searchQuery = {}
       bucketPath = path: 'bucket'

-      if options.hash.bucket
-        bucket = _.findWhere(buckets, slug: options.hash.bucket)
+      if settings.bucket
+        bucket = _.findWhere(buckets, slug: settings.bucket)
         searchQuery['bucket'] = bucket._id if bucket

-      if options.hash.where
-        searchQuery.$where = options.hash.where
+      if settings.slug
+        searchQuery.slug = settings.slug
+
+      if settings.where
+        searchQuery.$where = settings.where

       Entry.find(searchQuery)
         .populate('bucket')
         .populate('author')
-        .limit(options.hash.limit)
-        .skip(options.hash.skip)
+        .sort(settings.sort)
+        .limit(settings.limit)
+        .skip(settings.skip)
         .exec (err, pages) ->
           console.log err if err


Schedule syncedcron to run every one hour at the startup minute

--- server/startup/cron.coffee
+++ server/startup/cron.coffee
@@ -25,7 +25,7 @@
 		SyncedCron.add
 			name: 'Generate and save statistics',
 			schedule: (parser) -># parser is a later.parse object
-				return parser.text 'every 1 hour'
+				return parser.cron new Date().getMinutes() + ' * * * *'
 			job: generateStatistics

 		SyncedCron.start()


disable snapshots

disable snapshots

--- src/smc-util/syncstring_schema.coffee
+++ src/smc-util/syncstring_schema.coffee
@@ -67,7 +67,7 @@
                 string_id         : (obj, db) -> db.sha1(obj.project_id, obj.path)
                 users             : null
                 last_snapshot     : null
-                snapshot_interval : 150      # unclear how good of a choice 150 is...
+                snapshot_interval : 100000 # temporary disable
                 project_id        : null
                 path              : null
                 deleted           : null


jupyter: add some padding top and bottom

--- src/smc-webapp/jupyter/cell-list.cjsx
+++ src/smc-webapp/jupyter/cell-list.cjsx
@@ -11,6 +11,8 @@
 {Cell} = require('./cell')

 keyboard       = require('./keyboard')
+
+PADDING = 100

 exports.CellList = rclass
     propTypes:
@@ -92,9 +94,9 @@
                 cur = elt.find("##{@props.cur_id}")
                 if cur.length > 0
                     top = cur.position().top - elt.position().top
-                    if top < 0
+                    if top < PADDING
                         scroll = 'cell top'
-                    else if top > elt.height()
+                    else if top > elt.height() - PADDING
                         scroll = 'cell bottom'
                     else
                         return
@@ -108,7 +110,7 @@
                 when 'cell top'
                     cur = elt.find("##{@props.cur_id}")
                     if cur.length > 0
-                        elt.scrollTop(elt.scrollTop() +  (cur.position().top - elt.position().top))
+                        elt.scrollTop(elt.scrollTop() +  (cur.position().top - elt.position().top) - PADDING)
                 when 'cell center'
                     cur = elt.find("##{@props.cur_id}")
                     if cur.length > 0
@@ -116,7 +118,7 @@
                 when 'cell bottom'
                     cur = elt.find("##{@props.cur_id}")
                     if cur.length > 0
-                        elt.scrollTop(elt.scrollTop() +  (cur.position().top - elt.position().top) - elt.height()*.9)
+                        elt.scrollTop(elt.scrollTop() +  (cur.position().top - elt.position().top) - elt.height()*.9 + PADDING)

     render_loading: ->
@@ -174,4 +176,6 @@

                 {v}

+

+


Fix tiny bug in ignores

Fix tiny bug in ignores

--- lib/path_finder.coffee
+++ lib/path_finder.coffee
@@ -5,7 +5,7 @@
 module.exports =
 class PathFinder
   railsRootPathChildren: ['app', 'config', 'lib']
-  ignores: /(?:\/.git\/|\.keep$|\.DS_Store$|\.eot$|\.otf$|\.ttf$|\.woff$|\.png$|\.svg$|\.jpg$|\.gif$|\.mp4$|\.eps$|\.psd$)/
+  ignores: /(?:\/.git\/|\.(?:git)?keep$|\.DS_Store$|\.eot$|\.otf$|\.ttf$|\.woff$|\.png$|\.svg$|\.jpg$|\.gif$|\.mp4$|\.eps$|\.psd$)/

   constructor: (currentPath) ->
     @railsRootPath = @getRailsRootPath(currentPath)


shuffling code

shuffling code

--- lib/phabricator.coffee
+++ lib/phabricator.coffee
@@ -694,19 +694,20 @@

   doActions: (user, id, commandString, comment) ->
     @getBotPHID()
-    .bind({ botphid: null })
+    .bind({ bot_phid: null })
     .then (bot_phid) =>
-      @botphid = botphid
+      @bot_phid = bot_phid
       @getUser(user, user)
     .then (userPhid) =>
-      query = { 'task_id': id }
-      @request(query, 'maniphest.info')
+      @taskInfo id
     .then (body) =>
       commands = @parseAction body.result, commandString
+      if commands.data.length() > 0
+
       console.log commands
-      { id: id, messages: [ 'ok' ] }
-
-  parseAction: (item, str, res = []) ->
+      { id: id, messages: [ 'ok' ], data: [ 'open' ] }
+
+  parseAction: (item, str, res = [], msg = []) ->
     p = new RegExp("^(in|not in|on|is|to) ([^ ]*)")
     r = str.trim().match p
     switch r[1]
@@ -725,8 +726,8 @@
           res.push({ type: 'priority', value: r[2] })
     next = str.trim().replace(p, '')
     if next.trim() isnt ''
-      res = @parseAction(item, next, res)
-    res
+      res = @parseAction(item, next, res, msg)
+    { data: res, messages: msg }

   listTasks: (projphid) ->
     query = {


add ability to plumb helpers through to handlebars template rendering

--- src/guts.coffee
+++ src/guts.coffee
@@ -45,7 +45,8 @@
         model: @model.toJSON()
         cid: @model.cid
         url: @model.url
-    template_result = Guts.render @get_template(), context
+    helpers = (_.result @options, 'helpers') or (_.result @, 'helpers')
+    template_result = Guts.render @get_template(), context, helpers
     @$el.html(template_result)
     @

@@ -128,7 +129,8 @@
         url: @model.url

     @_rendered = true
-    template_result = Guts.render do @get_template, context
+    helpers = (_.result @options, 'helpers') or (_.result @, 'helpers')
+    template_result = Guts.render @get_template(), context, helpers
     orphans = @$el.children().detach()
     @$el.html(template_result)

@@ -206,10 +208,22 @@
       window.clearTimeout(@timer)
     @timer = window.setTimeout @save, 2000

+  change_select: =>
+    data = Backbone.Syphon.serialize(@)
+    @model.set data
+
+    @rerender()
+
+    if @timer
+      window.clearTimeout(@timer)
+    @timer = window.setTimeout @save, 2000
+
   events: =>
     'submit form': 'submitted'
     'keyup input': 'keyup'
+    'change input': 'keyup'
     'keyup textarea': 'keyup'
+    'change select': 'change_select'
     'change input[type=file]': 'file_chosen'

@@ -218,7 +232,8 @@
     value = @options.model.get(@options.property)
     context = {}
     context[@options.property] = value
-    template_result = Guts.render @get_template(), context
+    helpers = (_.result @options, 'helpers') or (_.result @, 'helpers')
+    template_result = Guts.render @get_template(), context, helpers
     @$el.html(template_result)
     @

@@ -300,12 +315,13 @@
   @CompositeModelForm: CompositeModelForm
   @BaseCollectionView: BaseCollectionView
   @ModelFieldView:     ModelFieldView
-  @render: (template_name, context) ->
+  @render: (template_name, context, helpers) ->
     template = App.Handlebars[template_name]
     if template
       if verbose
         console.log "Rendering template '#{template_name}'"
-      output = template context
+      output = template context,
+        helpers: _.defaults {}, helpers, Handlebars.helpers
       return output
     else
       throw "handlebars_render : error : couldn't find template '#{template_name}'"


fix: referenceerror err

fix: referenceerror err

--- src/processors/job/job.processor.coffee
+++ src/processors/job/job.processor.coffee
@@ -32,7 +32,7 @@
       }

       @_notificationsApi(message).fail errorMessage
-        .throw new NonRetryable "Max retry exceeded", err
+        .throw new NonRetryable "Max retry exceeded", error

     _notificationsApi: ({ HeadersForRequest, JobId }) =>
       new NotificationsApi {


doc php 5.5.7

doc php 5.5.7


fix dayum

fix dayum

--- scripts/memes.coffee
+++ scripts/memes.coffee
@@ -27,7 +27,7 @@
       msg.send url

   robot.hear /da+yum/i, (msg) ->
-    msg.send 'http://fc09.deviantart.net/fs71/f/2012/258/8/2/dayum_dayum_dayum___by_mystic_dranomimon-d5erzlw.gif'
+    msg.send 'http://i.imgur.com/vu0AC4m.gif'

   robot.hear /\benhance\b/i, (msg) ->
     msg.send 'http://stream1.gifsoup.com/view1/2373799/enhance-o.gif'


setHeader() bug

setHeader() bug


move files before their containing dir

move files before their containing dir

--- lib/tree-view.coffee
+++ lib/tree-view.coffee
@@ -1058,7 +1058,8 @@

       if initialPaths
         # Drop event from Atom
-        for initialPath in initialPaths.split(',')
+        # iterate backwards so files in a dir are moved before the dir itself
+        for initialPath in initialPaths.split(',') by -1
           @moveEntry(initialPath, newDirectoryPath)
       else
         # Drop event from OS


Disable landing page on pro for now

Disable landing page on pro for now

--- app/utils/location.coffee
+++ app/utils/location.coffee
@@ -1,4 +1,5 @@
 `import Ember from 'ember'`
+`import config from 'travis/config/environment'`

 Location = Ember.HistoryLocation.extend
   init: ->
@@ -12,11 +13,12 @@

   getURL: ->
     url = this._super.apply(this, arguments)
-    if location.pathname == '/'
-      if @get('auth.signedIn')
-        return '/repositories'
-      else
-        return '/home'
+    unless config.pro
+      if location.pathname == '/'
+        if @get('auth.signedIn')
+          return '/repositories'
+        else
+          return '/home'

     url


Add express-validator middleware

Add express-validator middleware

--- config/express.coffee
+++ config/express.coffee
@@ -1,16 +1,17 @@
-express = require('express')
-session = require('express-session')
-compression = require('compression')
-morgan = require('morgan')
-cookieParser = require('cookie-parser')
-cookieSession = require('cookie-session')
-bodyParser = require('body-parser')
-methodOverride = require('method-override')
-csrf = require('csurf')
-multer = require('multer')
+express = require 'express'
+session = require 'express-session'
+compression = require 'compression'
+morgan = require 'morgan'
+cookieParser = require 'cookie-parser'
+cookieSession = require 'cookie-session'
+bodyParser = require 'body-parser'
+methodOverride = require 'method-override'
+csrf = require 'csurf'
+multer = require 'multer'
 mongoStore = require('connect-mongo')(session)
-flash = require('express-flash')
-config = require('./config')
+flash = require 'express-flash'
+expressValidator = require 'express-validator'
+config = require './config'

 module.exports = (app, passport) ->
   app.use(compression())
@@ -20,6 +21,7 @@
   app.set('views', config.views)
   app.use(bodyParser.json())
   app.use(bodyParser.urlencoded(extended: true))
+  app.use(expressValidator())
   app.use(multer())
   app.use(methodOverride((req, res) ->
     if req.body && typeof req.body == 'object' && '_method' in req.body


:bug: critical but was not apparent

:bug: critical but was not apparent

I noticed this when working for AnyPair expandable. nice catch me!

--- lib/text-object.coffee
+++ lib/text-object.coffee
@@ -119,7 +119,7 @@
     if start? and (end = @findPair(point, start, pair)?.traverse([0, -1]))
       range = new Range(start, end)
       range = range.translate([0, -1], [0, 1]) if @inclusive
-    unless range and originallyEmpty
+    if not range and originallyEmpty
       selection.selectLeft()
     range


:art: cleanup

:art: cleanup

--- lib/text-object.coffee
+++ lib/text-object.coffee
@@ -84,7 +84,6 @@
   pair: null

   # Return 'open' or 'close'
-  {inspect} = require 'util'
   getPairState: (pair, matchText, range) ->
     [openChar, closeChar] = pair
     if openChar is closeChar
@@ -194,10 +193,7 @@
     @new(klass, {@inner}).getRange(selection, {@enclosed})

   getRanges: (selection) ->
-    ranges = []
-    for klass in @member when (range = @getRangeBy(klass, selection))
-      ranges.push range
-    ranges
+    (range for klass in @member when (range = @getRangeBy(klass, selection)))

   getNearestRange: (selection) ->
     ranges = @getRanges(selection)


pipeline_of_streams: avoid recursing on stream itself if returned by _pipeline

--- lib/understream.coffee
+++ lib/understream.coffee
@@ -65,7 +65,9 @@
 pipeline_of_streams = (streams) ->
   _.flatten _(streams).map (stream) ->
     if stream._pipeline?
-      pipeline_of_streams(stream._pipeline()).concat [stream]
+      # In old versions of Understream, _pipeline returned the stream. We defensively avoid
+      # recursing on the stream itself to prevent infinite loops.
+      pipeline_of_streams(_.without stream._pipeline(), stream).concat [stream]
     else
       [stream]


Change listeners to use once to avoid eventemitter leak warnings

--- lib/understream.coffee
+++ lib/understream.coffee
@@ -15,12 +15,12 @@
     dmn = domain.create()
     stream._transform = dmn.bind stream._transform.bind stream
     stream._flush = dmn.bind stream._flush.bind stream if stream._flush?
-    dmn.on 'error', (err) ->
+    dmn.once 'error', (err) ->
       dmn.exit()
       stream.emit 'error', err
     # Use .exit() instead of .dispose() because .dispose() was breaking the
     # tests. Something to look into at some point maybe... (-Jonah)
-    stream.on 'end', -> dmn.exit()
+    stream.once 'end', -> dmn.exit()

 state_to_string = (state) ->
   if state?


lulz, that should do it

lulz, that should do it

--- server/config.coffee
+++ server/config.coffee
@@ -16,8 +16,8 @@
     smtp:
       service: 'Mandrill'
       auth:
-        user: process.env.MANDRILL_APIKEY
-        pass: process.env.MANDRILL_USERNAME
+        user: process.env.MANDRILL_USERNAME
+        pass: process.env.MANDRILL_APIKEY
     db: process.env.MONGOHQ_URL
   development:
     smtp:


fix for tandem-core bug

fix for tandem-core bug

tandem-core does not compact adjacent ops where attributes both
are {} (since it probably just ==)

--- src/line.coffee
+++ src/line.coffee
@@ -45,7 +45,8 @@
       nodeFormats = _.clone(formats)
       # TODO: optimize
       _.each(@doc.formats, (format, name) ->
-        nodeFormats[name] = format.value(node)
+        # format.value() also checks match() but existing bug in tandem-core requires check anyways
+        nodeFormats[name] = format.value(node) if format.match(node)
       )
       if Leaf.isLeafNode(node)
         @leaves.append(new Leaf(node, nodeFormats))


fix a bug

fix a bug

--- src/main.coffee
+++ src/main.coffee
@@ -50,7 +50,7 @@
                     })
                 catch
                     null
-            if newFilePath.search(/^[a-z][a-z0-9\-]*$/) != -1
+            if newFilePath? and newFilePath.search(/^[a-z][a-z0-9\-]*$/) != -1
                 newFilePath = null
             if newFilePath?
                 if not filePathIndexesInMods[newFilePath]?


--- src/main.coffee
+++ src/main.coffee
@@ -24,7 +24,9 @@
     stdout: ['logging.stdout', [off, "Log to stdout"]]

 config.load (args, opts) ->
-    config.merge(require(opts.config))
+    # dont load default config over opts and args
+    unless opts.config is defaultConfigPath
+        config.merge(require(opts.config))

     # Kludge:
     if opts.stdout


include codepoint (CID) in pathdataplus

include codepoint (CID) in pathdataplus

--- src/main.coffee
+++ src/main.coffee
@@ -93,7 +93,8 @@
     path            = glyph.getPath x, y, size
     pathdata        = path.toPathData path_precision
     glyphname       = glyph.name
-  return { pathdata, glyphname, }
+    return { pathdata, glyphname, chr: ( String.fromCodePoint cid ), } if ( cid = glyph.unicode )?
+  return { pathdata, glyphname, chr: '', }

 #-----------------------------------------------------------------------------------------------------------
 @_pathelement_from_pathdata = ( me, pathdata, transform = null ) ->


added 'diskOutdated' and 'renderOutdated' booleans

--- src/main.coffee
+++ src/main.coffee
@@ -1,9 +1,10 @@
-dirty = false
+diskOutdated = false
+renderOutdated = true

 converter = new Markdown.Converter()
 markdown = (s) -> converter.makeHtml(s)

-code = ''
+code = '# Headline\n\nThis is some plain text.\n\n    print("Hello World");'
 textarea = undefined
 outputarea = undefined
 showHideCodeButton = undefined
@@ -13,15 +14,14 @@
 showCodeText = 'Show code'

 window.addEventListener('beforeunload', (e) ->
-  if dirty
+  if diskOutdated
     e.returnValue = 'Are you sure you want to leave this page?'
 )

 window.App =
   init: ->
     textarea = CodeMirror $('#source .panel-body').get(0),
-      value: '# Headline\n\nThis is some plain
-      text.\n\n    print("Hello World");'
+      value: code
       mode: 'markdown'
       indentUnit: 4

@@ -44,10 +44,12 @@
       textarea.setOption 'vimMode', $("#vimmode").is(":checked")

 possiblyUpdate = ->
-  return if code == textarea.getValue()
+  if code != textarea.getValue()
+    diskOutdated = true
+    renderOutdated = true
+  code = textarea.getValue()

-  code = textarea.getValue()
-  dirty = true
+  return if !renderOutdated

   md = markdown(code)
   outputarea.find('.output').html(md)
@@ -86,7 +88,7 @@
 ))()

 load = ->
-  if dirty
+  if diskOutdated
     if !window.confirm('Are you sure you want to load a new file without' +
                        'saving this one first?')
       return
@@ -102,7 +104,13 @@
     if reader.result == undefined
       console.log('file contents are undefined')
       return
+
+    # Populate the text field with the new source code
+    code = reader.result
     textarea.setValue(reader.result)
+    diskOutdated = false
+    renderOutdated = true
+
   reader.readAsText(file)

 save = ->


add afterRender handler for logging each route

--- server/router.coffee
+++ server/router.coffee
@@ -4,6 +4,10 @@
 routes = require(paths.entryPath + '/routes')

 config = null;
+
+stashPerf = (req, name, value) ->
+  if (config && config.stashPerf)
+    config.stashPerf(req, name, value)

 # given a name, eg "listings#show"
 # return function that matches that controller's action (eg the show method of the listings controller)
@@ -26,14 +30,13 @@

     start = new Date;
     action.call context, params, (err, template, data) ->
-      if (config && config.stashPerf)
-        config.stashPerf(req, "data", new Date - start)
+      stashPerf(req, "data", new Date - start)
       return handleErr(err, req, res) if err
+
       start = new Date;
       res.render(template, locals: data, app: req.appContext, req: req)
-      if (config && config.stashPerf)
-        config.stashPerf(req, "render", new Date - start)
-        config.stashPerf(req, "afterRenderTotalTime")
+      stashPerf(req, "render", new Date - start)
+      next()

 handleErr = (err, req, res) ->
   if (config && config.stashError)
@@ -46,6 +49,7 @@
       throw err
     else
       res.render('error_view', app: req.appContext, req: req);
+      next()

 getAuthenticate = (routeInfo) ->
   (req, res, next) ->
@@ -53,8 +57,14 @@
     if routeInfo.authenticated && !req.appContext.loggedIn()
       res.redirect('/login')
     else
-      config.stashPerf(req, "authenticate", new Date - start)
+      stashPerf(req, "authenticate", new Date - start)
       next()
+
+afterRender = () ->
+  (req, res, next) ->
+    if (config && config.afterRender)
+      config.afterRender(req, res)
+    # DO NOT CALL NEXT!  END FILTER CHAIN HERE

 # config
 # - stashError(req, err)
@@ -70,6 +80,6 @@
     action = getAction(routeInfo)
     handler = getHandler(action)
     authenticate = getAuthenticate(routeInfo)
-    routeSpecs.push(['get', "/#{path}", authenticate, handler])
+    routeSpecs.push(['get', "/#{path}", authenticate, handler, afterRender()])

   routeSpecs


#715 - minor typos in code cleanup

#715 - minor typos in code cleanup

--- dkobo/koboform/static/js/xlform/XLF.view.surveyApp.coffee
+++ dkobo/koboform/static/js/xlform/XLF.view.surveyApp.coffee
@@ -13,7 +13,7 @@
   @create: (params = {}) ->
     if _.isString params.el
       params.el = $(params.el).get 0
-    returns new @SurveryApp(params)
+    return new SurveyApp(params)

   initialize: (options)->
     if options.survey and (options.survey instanceof XLF.Survey)


Fixing bugs

Fixing bugs

--- steam.coffee
+++ steam.coffee
@@ -135,8 +135,6 @@
             msg.send "Match ID #{match.match_id} is a #{lobbies[match.lobby_type].toLowerCase()} game that took place #{start}. The #{victor} won the game in #{duration} minutes. First blood was drawn #{firstBlood} into the game."
             msg.send "Radiant towers remaining: #{radiantTowers} | Dire towers remaining: #{direTowers}"

-            communityID = if msg.match[2]? then getCommunityID(msg.match[2]) else false
-
             playerInfo = (communityID) ->
                 for player in match.players
                     if player.account_id is communityID
@@ -180,7 +178,7 @@
         if steamData()[steamID]?
             steamData()[steamID].communityID = communityID
         else
-            steamData()[object.response.steamid] = communityID: communityID
+            steamData()[steamID] = communityID: communityID

         communityID


better layer api reflected

better layer api reflected

--- templates/default/app/controllers/applicationController.coffee
+++ templates/default/app/controllers/applicationController.coffee
@@ -6,18 +6,18 @@

     # Create a new layer that ...

-    # TODO: FIXME get rid off localhost setting
-    layer = new Steroids.Layer { location: "http://localhost:13101" + @getAttribute("data-location") }
+    layer = new Steroids.Layer { location: @getAttribute("data-location") }

     # ... Open on top of this document and pushes to the navigation stack
     Steroids.layers.push layer: layer

+
   $(".opensModal").on "tap", () ->

-    # TODO: FIXME get rid off localhost setting
-    layer = new Steroids.Layer { location: "http://localhost:13101" + @getAttribute("data-location") }
+    layer = new Steroids.Layer { location: @getAttribute("data-location") }

-    Steroids.modal.show layer:layer
+    Steroids.modal.show { layer: layer }
+

   $(".closesModal").on "tap", () ->


BG/Sprite rendering optimizations.

BG/Sprite rendering optimizations.

--- emulator/core/units/ppu.coffee
+++ emulator/core/units/ppu.coffee
@@ -171,7 +171,6 @@
         @supressNMI = false     # Whether to supress NMI generation
         @nmiDelay = 0           # Number of cycles after which NMI is generated
         @oddFrame = false       # Whether odd frame is being rendered
-        @renderedSprite = null  # Currently rendered sprite
         @spriteCount = 0        # Total number of sprites on current scanline
         @spriteNumber = 0       # Number of currently fetched sprite
         @spriteCache = (0 for [0..261])         # Preprocesed sprite data for current scanline (cycle -> sprite rendered on that cycle)
@@ -304,12 +303,12 @@
     readData: ->
         address = @$incrementAddress()
         oldBufferContent = @vramReadBuffer
-        @vramReadBuffer = @$read address                                         # Always increments the address
+        @vramReadBuffer = @ppuMemory.read address                                # Always increments the address
         if @$isPaletteAddress address then @vramReadBuffer else oldBufferContent # Delayed read outside the palette memory area

     writeData: (value) ->
         address = @$incrementAddress()                      # Always increments the address
-        @$write address, value unless @$isRenderingActive() # Only during VBlank or disabled rendering
+        @ppuMemory.write address, value unless @$isRenderingActive() # Only during VBlank or disabled rendering
         value

     incrementAddress: ->
@@ -320,32 +319,8 @@
     getAddressIncrement: ->
         if @bigAddressIncrement then 0x20 else 0x01 # Vertical/horizontal move in pattern table.

-
-    ###########################################################
-    # Internal VROM/VRAM access
-    ###########################################################
-
-    read: (address) ->
-        if @$isPaletteAddress address
-            @readPalette address
-        else
-            @ppuMemory.read address
-
-    readPalette: (address) ->
-        value = @ppuMemory.readPalette @$fixPaletteAddress address
-        if @monochromeMode then value & 0x30 else value
-
     isPaletteAddress: (address) ->
-        (address & 0x3F00) == 0x3F00
-
-    fixPaletteAddress: (address) ->
-        if @$shouldUseBackdropColor address then 0x3F00 else address
-
-    shouldUseBackdropColor: (address) ->
-        (address & 0x0003) is 0 and not @vblankActive
-
-    write: (address, value) ->
-        @ppuMemory.write address, value
+        (address & 0x3F00) is 0x3F00

     ###########################################################
     # Scrolling and scrolling register ($2005)
@@ -515,19 +490,27 @@
         if @ntscMode and @cycleFlags & F_CLIP_NTSC # Clip top/bottom 8 scanlines in NTSC
             @$clearFramePixel()
         else
-            colorAddress = 0x3F00 | @renderFramePixel()
-            @$setFramePixel @$readPalette colorAddress
+            address = @renderFramePixel()
+            color = @ppuMemory.readPalette address
+            @$setFramePixel color

     renderFramePixel: ->
         backgroundColor = @renderBackgroundPixel()
-        spriteColor = @renderSpritePixel()
-        if (spriteColor & 0x03) and (backgroundColor & 0x03)
-            @spriteZeroHit ||= @renderedSprite.zeroSprite                    # Both bagckground and sprite pixels are visible
-            if @renderedSprite.inFront then spriteColor else backgroundColor # Choose target by rendering priority
+        spriteColor = @$renderSpritePixel()
+        if backgroundColor & 0x03
+            if spriteColor & 0x03
+                sprite = @$getRenderedSprite()
+                @spriteZeroHit ||= sprite.zeroSprite
+                if sprite.inFront
+                    spriteColor     # Sprite has priority over background
+                else
+                    backgroundColor # Background has priority over sprite
+            else
+                backgroundColor     # Only background is visible
         else if spriteColor & 0x03
-            spriteColor      # Sprite pixel is visible
+            spriteColor             # Only sprite is visible
         else
-            backgroundColor  # Otherwise render backround
+            0                       # Use backdrop color

     ###########################################################
     # Background rendering
@@ -706,14 +689,15 @@

     renderSpritePixel: ->
         if @$isSpritePixelVisible()
-            @renderedSprite = @spriteCache[@cycle]
             @spritePixelCache[@cycle]
         else
-            @renderedSprite = null
             0

     isSpritePixelVisible: ->
         @spritesVisible and not (@spriteClipping and (@cycleFlags & F_CLIP_LEFT))
+
+    getRenderedSprite: ->
+        @spriteCache[@cycle]

     ###########################################################
     # Debug rendering
@@ -742,7 +726,7 @@
                 bitPosition = columnNumber ^ 0x07
                 colorSelect1 =  (patternBuffer0 >> bitPosition) & 0x01
                 colorSelect2 = ((patternBuffer1 >> bitPosition) & 0x01) << 1
-                color = @$readPalette 0x3F00 | colorSelect2 | colorSelect1
+                color = @ppuMemory.readPalette colorSelect2 | colorSelect1
                 @setFramePixelOnPosition x, y, color
         undefined

@@ -751,7 +735,7 @@
             baseY = 128 + tileY * 28
             for tileX in [0...8]
                 baseX = tileX << 5
-                color = @$readPalette 0x3F00 | (tileY << 3) | tileX
+                color = @ppuMemory.readPalette (tileY << 3) | tileX
                 @renderPaletteTile baseX, baseY, color
         undefined


Remove "View (Un)staged Changes" entries from FilePatchItem context menu

--- menus/git.cson
+++ menus/git.cson
@@ -114,7 +114,7 @@
       'command': 'github:toggle-expanded-commit-message-editor'
     }
   ]
-  'atom-text-editor': [
+  '.item-views > atom-text-editor': [
     {
       'label': 'View Unstaged Changes',
       'command': 'github:view-unstaged-changes-for-current-file'


broker client: roll back previous commit

--- node_modules_koding/koding-broker-client/src/broker-client/broker.coffee
+++ node_modules_koding/koding-broker-client/src/broker-client/broker.coffee
@@ -57,7 +57,7 @@
       # replay any existing subscriptions after reconnecting.
       for own name, args of @subscriptions
         delete @subscriptions[name]
-        delete @channels[name]
+        # delete @channels[name]
         @subscribe args...

     @readyState = READY


fix generateandstore

fix generateandstore

--- app/config.coffee
+++ app/config.coffee
@@ -26,7 +26,7 @@
       type: 'octoblu:user'

     getDeviceToken = (uuid) =>
-      @meshbludb.generateAndStoreToken uuid: uuid, (error, device) =>
+      @meshbludb.generateAndStoreToken uuid, (error, device) =>
         device.id = profileId
         done null, device


fixed detect cloud host

fixed detect cloud host

--- app/config.coffee
+++ app/config.coffee
@@ -3,10 +3,12 @@
 cloudhosts = ["rhcloud.com"]
 host = window.location.hostname

-cloudDeploy = _.find(cloudhosts, (n) -> host.indexOf(n) > 1 )
+cloudDeploy = _.find(cloudhosts, (n) -> host.indexOf(n) > 0 )
+
+console.log "Cloud Deployed? #{cloudDeploy}"

 config.api.root = if cloudDeploy
-  "http://${host}"
+  "http://#{host}"
 else
   'http://dev.wokwin.com:9080'


More sensible access control

More sensible access control

--- packages/shrub-user/client/index.coffee
+++ packages/shrub-user/client/index.coffee
@@ -158,10 +158,8 @@
 				@lastAccessed = (new Date()).toISOString()
 				this

-			# Temporary... secure by default.
 			# `TODO`: Access control structure.
 			hasPermission: (perm) -> false
-			isAccessibleBy: (user) -> false

 exports.collectionsAlter = (collections) ->

@@ -193,6 +191,9 @@
 				error.code = 403
 				throw error

+			# Secure by default.
+			collection.attributes.isAccessibleBy ?= (user) -> false
+
 			collection.authenticatedAll = (user, params) ->

 				validateUser(user).then(->


adds static helper Space.Object::isSubclassOf

--- source/object.coffee
+++ source/object.coffee
@@ -190,3 +190,8 @@
         _.deepExtend @prototype[key], value
       else
         @prototype[key] ?= value
+
+  @isSubclassOf = (sup) ->
+    isSubclass = this.prototype instanceof sup
+    isSameClass = this is sup
+    return isSubclass || isSameClass


compute: make it so can ensure project is opened or running when get it.

--- salvus/compute.coffee
+++ salvus/compute.coffee
@@ -346,13 +346,17 @@
     project: (opts) =>
         opts = defaults opts,
             project_id : required
-            open       : false    # if true, only returns after ensuring project is opened on some host (which may take minutes)
+            opened     : false    # if true, only returns after ensuring project is opened on some host (which may take minutes)
+            running    : false    # if true, ensures project is started before returning
             cb         : required
         if not @_project_cache?
             @_project_cache = {}
         p = @_project_cache[opts.project_id]
+        state = undefined
+        dbg = @dbg("project(#{opts.project_id}, open=#{opts.opened}, start=#{opts.running})")
         async.series([
             (cb) =>
+                dbg("get project")
                 if p?
                     cb()
                 else
@@ -367,14 +371,25 @@
                                 @_project_cache[opts.project_id] = project
                                 cb()
             (cb) =>
-                if not opts.open
+                if not (opts.opened or opts.running)
                     cb()
                 else
+                    dbg("ensure at least opened")
                     p.state
-                        cb : (err, state) =>
-                            if err or state.state != 'closed' and state.state != 'closing'
+                        cb : (err, s) =>
+                            if err
                                 cb(err)
                                 return
+                            state = s.state
+                            if state == 'opening'
+                                p.once 'opened', () =>
+                                    state = 'opened'
+                                    cb()
+                                return
+                            if state != 'closed' and state != 'closing'
+                                cb(err)
+                                return
+                            # Finally deal with case of closed or closing.
                             # This is tricky: in close state, we request open and wait
                             # for project to open; in closing state, we wait until closed
                             # then request open and wait until open.
@@ -387,11 +402,47 @@
                                             p.once 'opened', () =>
                                                 # TODO: some danger that this will never happen, e.g., in case
                                                 # of socket disconnect while waiting.
+                                                state = 'opened'
                                                 cb()
-                            if state.state == 'closed'
+                            if state == 'closed'
                                 f()
-                            else if state.state == 'closing'
+                            else
                                 p.once 'closed', () =>
+                                    f()
+            (cb) =>
+                if not opts.running
+                    cb()
+                else
+                    p.state
+                        cb : (err, s) =>
+                            if err
+                                cb(err)
+                                return
+                            state = s.state
+                            if state == 'starting'
+                                p.once 'running', () =>
+                                    cb()
+                                return
+                            if state != 'opened' and state != 'stopping'
+                                cb(err)
+                                return
+                            # This is tricky: in close state, we request open and wait
+                            # for project to open; in closing state, we wait until closed
+                            # then request open and wait until open.
+                            f = () =>
+                                p.start
+                                    cb : (err) =>
+                                        if err
+                                            cb(err)
+                                        else
+                                            p.once 'running', () =>
+                                                # TODO: some danger that this will never happen, e.g., in case
+                                                # of socket disconnect while waiting.
+                                                cb()
+                            if state == 'opened'
+                                f()
+                            else
+                                p.once 'opened', () =>
                                     f()
         ], (err) =>
             if err
@@ -592,7 +643,7 @@
                     dbg("getting other project and ensuring that it is already opened")
                     @compute_server.project
                         project_id : opts.target_project_id
-                        open       : true
+                        opened     : true
                         cb         : (err, target_project) =>
                             if err
                                 dbg("error ")


update error message for new rethinkdb node.js driver

--- salvus/rethink.coffee
+++ salvus/rethink.coffee
@@ -1670,7 +1670,7 @@
         if not @_validate_opts(opts) then return
         @table('projects').get(opts.project_id)('users')(opts.account_id)('group').run (err, group) =>
             if err?
-                if err.name == "RqlRuntimeError"
+                if err.name == "ReqlNonExistenceError"
                     # indicates that there's no opts.account_id key in the table (or users key) -- error is different
                     # (i.e., RqlDriverError) when caused by connection being down.
                     # one more chance -- admin?
@@ -2258,8 +2258,8 @@
             cb         : required  # cb(err, ttl actually used in seconds); ttl=0 for infinite ttl
         @table('blobs').get(opts.uuid).pluck('expire').run (err, x) =>
             if err
-                if err.name == 'RqlRuntimeError'
-                    # Get RqlRuntimeError if the blob not already saved, due to trying to pluck from nothing.
+                if err.name == 'ReqlNonExistenceError'
+                    # Get ReqlNonExistenceError if the blob not already saved, due to trying to pluck from nothing.
                     # We now insert a new blob.
                     x =
                         id         : opts.uuid


Added better tag form handling

Added better tag form handling

The tag form now collapses if the tag button is pressed again.

--- src/Pascal/FeedDisplayerBundle/Resources/public/js/feedEntryTools.coffee
+++ src/Pascal/FeedDisplayerBundle/Resources/public/js/feedEntryTools.coffee
@@ -46,6 +46,10 @@

 	tagEntry: (event) =>
 		tool = $(event.currentTarget)
+
+		existingTagForm = tool.parent().find('div.tagForm')
+		if existingTagForm.length isnt 0
+			return existingTagForm.remove()

 		# Find the currently attached tags
 		tags = this.findCurrentTags tool


Electric punctuation is by default turned off. Related to #584 and #647

--- admin/static/coffee/dataexplorer.coffee
+++ admin/static/coffee/dataexplorer.coffee
@@ -213,7 +213,7 @@
             else
                 @options =
                     suggestions: true
-                    electric_punctuation: true
+                    electric_punctuation: false # False by default

             # We do not load the rest of data from localStorage.
             if not DataExplorerView.Container.prototype.saved_data?


Enable "Add table" button when re-initializing table index from an existing model.

--- admin/static/coffee/tables/index.coffee
+++ admin/static/coffee/tables/index.coffee
@@ -150,6 +150,8 @@
             else if @collection.length is 0
                 @$el.html @template.no_databases()
                 @container.display_add_table_button false
+            else
+                @container.display_add_table_button true

             @listenTo @collection, 'add', (database) =>
                 new_view = new TablesView.DatabaseView


add Sarasa* fontfiles

add Sarasa* fontfiles

--- options.coffee
+++ options.coffee
@@ -336,6 +336,13 @@

       { texname: 'mktsFontfileSushikii',                      subfolder: 'sushiki_ub',  filename: 'sushikii.ttf', }

+      ### TAINT TTC fonts from the Sarasa series have several regional / usage variants, as seen in BabelMap, these should
+                be selected and made available here ###
+      { texname: 'mktsFontfileSarasabold',                    subfolder: 'sarasa-gothic-0.6.0', filename: 'sarasa-bold.ttc',        }
+      { texname: 'mktsFontfileSarasabolditalic',              subfolder: 'sarasa-gothic-0.6.0', filename: 'sarasa-bolditalic.ttc',  }
+      { texname: 'mktsFontfileSarasaitalic',                  subfolder: 'sarasa-gothic-0.6.0', filename: 'sarasa-italic.ttc',      }
+      { texname: 'mktsFontfileSarasaregular',                 subfolder: 'sarasa-gothic-0.6.0', filename: 'sarasa-regular.ttc',     }
+

       ]


enable textarea line numbers in modal dialog

--- app/assets/javascripts/states/runbooks/views/_command_log_modal.js.coffee
+++ app/assets/javascripts/states/runbooks/views/_command_log_modal.js.coffee
@@ -8,6 +8,7 @@

     show: ->
       @$el.modal("show")
+      @$("textarea").linedtextarea();

     after_render: ->
       @$el.modal({ show: false })


More better mention filtering

More better mention filtering

--- lineman/app/js/controllers/comment_form_controller.coffee
+++ lineman/app/js/controllers/comment_form_controller.coffee
@@ -6,8 +6,8 @@
   $scope.getMentionables = (fragment) ->
     MembershipService.fetchByNameFragment fragment, group.id, ->
       $scope.mentionables = _.filter(group.members(), (member) ->
-        ~member.name.toLowerCase().indexOf(fragment.toLowerCase()) or \
-        ~member.label.toLowerCase().indexOf(fragment.toLowerCase()))
+        ~member.name.search(new RegExp(fragment, 'i')) or \
+        ~member.label.search(new RegExp(fragment, 'i')))

   saveSuccess = ->
     $scope.comment = new CommentModel(discussion_id: discussion.id)


Starts QueuedApp.Router

Starts QueuedApp.Router

--- app/assets/javascripts/backbone/apps/queued/queued_app.js.coffee
+++ app/assets/javascripts/backbone/apps/queued/queued_app.js.coffee
@@ -10,6 +10,6 @@
       QueuedApp.List.Controller.getQueuedList()

-  # App.addInitializer ->
-  #   new QueuedApp.Router
-  #     controller: API+  App.addInitializer ->
+    new QueuedApp.Router
+      controller: API


clean up code

clean up code

--- app/assets/javascripts/components/image-subject-viewer-mark.cjsx
+++ app/assets/javascripts/components/image-subject-viewer-mark.cjsx
@@ -11,9 +11,8 @@
 TextRowTool                   = require './mark/text-row-tool'
 TranscribeTool                = require './transcribe/transcribe-tool'
 Classification                = require '../models/classification'
-getUrlParamByName             = require '../lib/getUrlParamByName'
-
-WORKFLOW_ID = '533cd4dd4954738018030000'
+
+WORKFLOW_ID = '54b82b4745626f20c9020000' # marking workflow

 ImageSubjectViewer_mark = React.createClass # rename to Classifier
   displayName: 'ImageSubjectViewer_mark'
@@ -26,38 +25,24 @@

 SubjectViewer = React.createClass
   displayName: 'SubjectViewer'
-
   resizing: false
-
-  usingFakeSubject: ->
-    if getUrlParamByName('use_fake_subject') is "true"
-      console.log 'DEBUG NOTE: USING FAKE SUBJECTS'
-      return true
-    else
-      return false

   getInitialState: ->
     subjects: null
     subject: null
     subjectEndpoint: @props.endpoint
-
     marks: []
     tools: []
     loading: false
-
     frame: 0
     imageWidth: 0
     imageHeight: 0
-
     viewX: 0
     viewY: 0
     viewWidth: 0
     viewHeight: 0
-
     classification: null
-
     selectedMark: null # TODO: currently not in use
-
     showTranscribeTool: false

   getFakeSubject: (group) ->
@@ -71,19 +56,7 @@
   componentDidMount: ->
     console.log 'TASK = ', @props.task
     @setView 0, 0, @state.imageWidth, @state.imageHeight
-
-    if @usingFakeSubject()
-      if @props.task is 'mark'
-        console.log 'using MARKING subjects'
-        subjectEndpoint = "./offline/example_subjects/marking_subjects.json"
-      else
-        console.log 'using TRANSCRIPTION subjects'
-        subjectEndpoint = "./offline/example_subjects/transcription_subjects.json"
-      @setState subjectEndpoint: subjectEndpoint, =>
-        @fetchSubjects(@state.subjectEndpoint)
-    else
-      @fetchSubjects(@state.subjectEndpoint)
-
+    @fetchSubjects(@state.subjectEndpoint)
     window.addEventListener "resize", this.updateDimensions

   componentWillMount: ->
@@ -147,7 +120,7 @@
         y: mark.y

     # DEBUG CODE
-    console.log @state.classification.annotations
+    # console.log @state.classification.annotations

   submitMark: (key) ->
     # prepare classification
@@ -162,10 +135,6 @@
       y_lower: mark.yLower
       x: mark.x
       y: mark.y
-
-    console.log 'SUBJECT: ', @state.subject
-
-    console.log 'CLASSIFICATION: ', classification

     # send classification
     $.post('/classifications', {
@@ -184,13 +153,12 @@
       #   return

   nextSubject: () ->
-    console.log 'MARKS: ', @state.marks

     @prepareClassification()
     @sendMarkClassification()

     # # DEBUG CODE
-    console.log 'CLASSIFICATION: ', @state.classification
+    # console.log 'CLASSIFICATION: ', @state.classification

     # console.log JSON.stringify @state.classification # DEBUG CODE
     @state.classification.send()
@@ -204,7 +172,6 @@
     else
       @setState subject: @state.subjects[0], =>
         @loadImage ((if @usingFakeSubject() then @state.subject.classification.subject.location else @state.subject.location))
-

     @state.classification = new Classification @state.subject

@@ -274,7 +241,6 @@
     currentMark.yUpper = Math.round currentMark.y - markHeight/2
     currentMark.yLower = Math.round currentMark.y + markHeight/2

-
     # prevent dragging mark beyond image bounds
     offset = @state.markOffset.y
     return if ( y + offset - markHeight/2 ) < 0
@@ -322,7 +288,6 @@
     y = Math.round y

     currentMark = @state.selectedMark
-

     # enforce bounds
     if y > @state.imageHeight


'android' fake global: support for new 'native' module

--- process.coffee
+++ process.coffee
@@ -164,9 +164,9 @@
 				http:
 					request: -> 0
 					onResponse: ->
-				renderer:
+				native:
 					transferData: ->
-					onUpdateView: ->
+					onData: ->

 		ios: ->
 			browserEnv()
@@ -252,7 +252,7 @@

 		modulePath = pathUtils.relative base, filename
 		parentPath = pathUtils.relative base, parent.id
-		unless parentPath then return r
+		unless parentPath then return r

 		if onlyLocal
 			if ///^\.\.(?:\/|\\)|^node_modules(?:\/|\\)///.test(modulePath) or not ///\.[a-zA-Z0-9]+$///.test(modulePath)


Changed Model/Base to not index attributes for new models until after all attributes have been pre-set. This is to prevent functions bound to those indexes from getting access to an incomplete model.

--- lib/ST/Model/Base.coffee
+++ lib/ST/Model/Base.coffee
@@ -103,6 +103,13 @@
             @[attribute] data[attribute]
           else if !details.virtual
             @[attribute] details.default
+
+      # Add class to indexes
+      if @_class._indexes
+        for attribute of @_class._attributes
+          if @_class._attributes.hasOwnProperty(attribute)
+            if index = @_class._indexes[attribute]
+              index.add @_attributes[attribute], this

       if @_class._manyBinds
         for binding in @_class._manyBinds
@@ -271,14 +278,14 @@
         # Set new value
         @_attributes[name] = newValue

-        # Update index
-        if @_class._indexes
-          if index = @_class._indexes[name]
-            index.remove  oldValue, this
-            index.add     newValue, this
-
-        # Trigger changed event
         unless @_creating
+          # Update index
+          if @_class._indexes
+            if index = @_class._indexes[name]
+              index.remove  oldValue, this
+              index.add     newValue, this
+
+          # Trigger changed event
           @_changed name, oldValue, newValue if @_changed
           @trigger 'changed', name, oldValue, newValue


Don't display "Uuid" in form labels.

Don't display "Uuid" in form labels.

--- lib/ST/Model/Base.coffee
+++ lib/ST/Model/Base.coffee
@@ -422,6 +422,6 @@
         @_dependent.push name

     @classMethod 'labelForAttribute', (attribute) ->
-      ST.ucFirst(attribute.replace /([A-Z])/g, " $1")
+      ST.ucFirst(attribute.replace(/([A-Z])/g, " $1").replace(/\sUuid$/, ''))

     @include ST.Model.Searchable


удалил лишний файл

удалил лишний файл

--- app/server.coffee
+++ app/server.coffee
@@ -1,40 +0,0 @@
-
-express = 		require('express')
-http = 			require('http')
-path = 			require('path')
-# routes = 		require './public/routes'
-
-mongoClient = 	require('mongodb').MongoClient
-
-app = express()
-
-app.configure ->
-	app.set 'port', process.env.PORT || 2527
-	app.use express.logger 'dev'
-	app.use express.bodyParser()
-	app.use express.methodOverride()
-	app.use app.router
-	app.use express.static __dirname
-	app.set app.method, 'PUT'
-
-app.configure 'development', () ->
-	app.use express.errorHandler()
-
-app.all '*', (req,res,next) ->
-	req.method = req.query._method if req.query._method?
-	next()
-
-app.put '/registration', (req, res) ->
-	mongoClient.connect 'mongodb://127.0.0.1:27017/mydb', (err, db) ->
-		throw err if err
-		db.collection('testData').find().toArray (err, doc) ->
-			throw err if err
-			console.log doc
-			res.jsonp {a:1}
-			db.close()
-			console.log 'end'
-
-
-http.createServer(app).listen app.get('port'), () ->
-	console.log "server work at http://localhost:" + app.get('port')
-


Tests: Fix for coverage.

Tests: Fix for coverage.

It must be 100%.

--- src/tests/core/test_store.coffee
+++ src/tests/core/test_store.coffee
@@ -260,6 +260,9 @@
       store2.set 'isOnline', no
       expect(passed).toBe 2

+      message = store2.get('fetch')()
+      expect(message).toBe 'fetched user data...'
+
       store2.set 'fetch', 'it must be a function to pass'
       expect(failed).toBe 3


Update index.coffee

Update index.coffee

--- client/activity/lib/components/channelinfocontainer/index.coffee
+++ client/activity/lib/components/channelinfocontainer/index.coffee
@@ -115,7 +115,7 @@

         {@renderChannelIntro()}

-          You can start a collaboration session, or drag and drop  VMs and
+          You can start a collaboration session, or drag and drop VMs and
           workspaces here from the sidebar to let anyone in this channel access
           them.
           (<Link onClick ={@bound 'onCollaborationHelp'}>Show me how?</Link>)


fix for the custom css

fix for the custom css

--- packages/rocketchat-theme/server/server.coffee
+++ packages/rocketchat-theme/server/server.coffee
@@ -69,7 +69,7 @@

 				RocketChat.settings.get '*', Meteor.bindEnvironment (key, value, initialLoad) =>
 					if key is 'theme-custom-css'
-						if value?.trim() isnt ''
+						if value?
 							@customCSS = value
 					else if /^theme-.+/.test(key) is true
 						name = key.replace /^theme-[a-z]+-/, ''


add client-side compiling

add client-side compiling

--- lib/adapters/toffee.coffee
+++ lib/adapters/toffee.coffee
@@ -1,5 +1,4 @@
 Adapter = require '../adapter_base'
-_ = require 'lodash'
 W = require 'when'
 fs = require 'fs'

@@ -11,17 +10,16 @@
     @output = 'html'

   _render: (str, options) ->
-    compiler = _.clone(@compiler)
-    compile =>
-      compiler.str_render(str, options, (err, res) -> return res)
+    compile => @compiler.str_render(str, options, (err, res) -> res)

   _compile: (str, options) ->
-    compiler = _.clone(@compiler)
-    compile =>
-      return compiler.compileStr(str).toString()
+    compile => @compiler.compileStr(str).toString()
+
+  _compileClient: (str, options) ->
+    compile => @compiler.configurable_compile(str, options)

   # private
-
+
   compile = (fn) ->
     try res = fn()
     catch err then return W.reject(err)


:lipstick:

:lipstick:

--- src/test.coffee
+++ src/test.coffee
@@ -49,6 +49,7 @@
         env: env
         windowsVerbatimArguments: true
       cmd = process.env.comspec or 'cmd.exe'
+
       @spawn cmd, cmdArgs, cmdOptions, (code) ->
         try
           loggedOutput = fs.readFileSync(logFilePath, 'utf8')


minor changes

minor changes

--- app/vis.coffee
+++ app/vis.coffee
@@ -76,6 +76,24 @@
         string_mesh = @getTextMesh string_geom
         string_mesh.scale.multiplyScalar(-1)
         string_mesh
+
+    getLineObject: (line) =>
+        line_geometry = @getTextGeometry line
+        line_layout = line_geometry.layout
+        glyph_positions = line_layout.glyphs.map (g) -> g.position
+
+        letterObjects = line.split("").map (letter, index) =>
+            letter_mesh = @getMeshFromString letter
+            letter_mesh.position.x = - glyph_positions[index][0]
+            letter_mesh
+
+        # TODO: Pack up words...
+
+        lineObject = new THREE.Object3D()
+        lineObject.add.apply lineObject, letterObjects
+        lineObject._line = line
+        lineObject._layout = line_layout
+        lineObject

     processChain = (chain) ->
         chain.map (obj, i, array) ->
@@ -89,24 +107,6 @@
                 obj.my_prev_connector_index = my_prev_idx
                 obj.prev_connector_index = prev_idx
             obj
-
-    getLineObject: (_line, index) =>
-        line_geometry = @getTextGeometry _line
-        line_layout = line_geometry.layout
-        glyph_positions = line_layout.glyphs.map (g) -> g.position
-
-        letterObjects = _line.split("").map (letter, index) =>
-            letter_mesh = @getMeshFromString letter
-            letter_mesh.position.x = - glyph_positions[index][0]
-            letter_mesh
-
-        # TODO: Pack up words...
-
-        lineObject = new THREE.Object3D()
-        lineObject.add.apply(lineObject, letterObjects)
-        lineObject._line = _line
-        lineObject._layout = line_layout
-        lineObject

     positionLines = (line, index, array) =>
         return line if index is 0
@@ -450,15 +450,15 @@

         traverse root

-        # addBBox = (node) =>
-        #     bbox = new THREE.BoundingBoxHelper( node._text_object, 0xff0000 )
-        #     do bbox.update
-        #     @scene.add bbox
-        #     if node.children
-        #         node.children.forEach addBBox
-        # addBBox root
-
         @animateLines root
+
+# addBBox = (node) =>
+#     bbox = new THREE.BoundingBoxHelper( node._text_object, 0xff0000 )
+#     do bbox.update
+#     @scene.add bbox
+#     if node.children
+#         node.children.forEach addBBox
+# addBBox root

 # module.exports = Main


rename getTransitionPromise to getFadePromise

--- app/vis.coffee
+++ app/vis.coffee
@@ -252,7 +252,7 @@
                         @camera.position.y = y(t)
                 .each "end", resolve

-    getTransitionPromise = (interpolator, duration) ->
+    getFadePromise = (interpolator, duration) ->
         (text_object) ->
             new Promise (resolve) ->
                 d3.select(text_object).transition()
@@ -267,7 +267,7 @@
     fade = (from, to, duration) ->
         (text_object) ->
             i = d3.interpolate from, to
-            getTransitionPromise(i, duration)(text_object)
+            getFadePromise(i, duration)(text_object)

     fadeTo = (to, duration) ->
         (text_object) ->
@@ -275,15 +275,15 @@
                 text_object.children[0].material.uniforms.opacity.value
             else 0
             i = d3.interpolate current, to
-            getTransitionPromise(i, duration) text_object
+            getFadePromise(i, duration) text_object

     fadeOut = (text_object) ->
         i = d3.interpolate(0.5, 0)
-        getTransitionPromise(i)(text_object)
+        getFadePromise(i)(text_object)

     fadeIn = (text_object) ->
         i = d3.interpolate(0, 0.5)
-        getTransitionPromise(i)(text_object)
+        getFadePromise(i)(text_object)

     setTextObject: (node) =>
         text_object = @getLineObject(node.val)
@@ -420,13 +420,14 @@
             Promise.resolve()
                 .then =>
                     # Fade out siblings
-                    if node._parent?
-                        siblings = node._parent.children
-                            .filter (child) -> child isnt node
-                        parent = node._parent
-                        promises = siblings.concat(parent).map (child) ->
-                                fadeTo(0, 1000) child._text_object
-                        Promise.all promises
+                    # if node._parent?
+                    #     siblings = node._parent.children
+                    #         .filter (child) -> child isnt node
+                    #     parent = node._parent
+                    #     promises = siblings.concat(parent).map (child) ->
+                    #             fadeTo(0, 1000) child._text_object
+                    #     Promise.all promises
+                    return true
                 .then =>
                     # Fade in children
                     if node.children?


TEST: superfish

TEST: superfish

--- app/assets/javascripts/custom.js.coffee
+++ app/assets/javascripts/custom.js.coffee
@@ -1,2 +1,2 @@
 jQuery ->
-  $('ul.nav').superfish()+  $('ul.sf-menu').superfish()


Add help link in editor.

Add help link in editor.

--- app/assets/javascripts/editor.js.coffee
+++ app/assets/javascripts/editor.js.coffee
@@ -12,6 +12,9 @@

+

+

+


open screenshots with fancy JS magic

open screenshots with fancy JS magic

--- app/assets/javascripts/static.js.coffee
+++ app/assets/javascripts/static.js.coffee
@@ -1,3 +1,11 @@
 # Place all the behaviors and hooks related to the matching controller here.
 # All this logic will automatically be available in application.js.
 # You can use CoffeeScript in this file: http://coffeescript.org/
+
+$ ->
+  $('ul.gallery a').click (e) ->
+    e.preventDefault()
+    e.stopPropagation()
+    shade = $('<div>').css position: 'fixed', top: 0, bottom: 0, left: 0, right: 0, backgroundColor: 'rgba(0,0,0,0.5)'
+    img = $('<img>').attr('src', $(this).attr('href')).css position: 'fixed', top: '50%', maxHeight: '100%', transform: 'translateY(-50%)', right: 0, left: 0, margin: '0 auto'
+    $(document.body).append(shade, img).click -> shade.remove() && img.remove()


Fix broken survey task editor (#6221)

Fix broken survey task editor (#6221)

Replace `workflow.update('tasks').save()` with `@props.onChange(@props.task)` throughout.

--- app/classifier/tasks/survey/editor.cjsx
+++ app/classifier/tasks/survey/editor.cjsx
@@ -310,7 +310,7 @@
     @props.task.questionsMap = newTask.questionsMap
     @props.task.questionsOrder = newTask.questionsOrder

-    @props.workflow.update('tasks').save()
+    @props.onChange @props.task
       .then =>
         @clearState()

@@ -544,14 +544,14 @@
   handleImageAdd: (media) ->
     @setState resettingFiles: true
     @props.task.images[media.metadata.filename] = media.src
-    @props.workflow.update('tasks').save()
+    @props.onChange @props.task
       .then =>
         @setState resettingFiles: false

   handleImageDelete: (media) ->
     @setState resettingFiles: true
     delete @props.task.images[media.metadata.filename]
-    @props.workflow.update('tasks').save()
+    @props.onChange @props.task
       .then =>
         @setState resettingFiles: false

@@ -595,7 +595,7 @@
         questionsOrder: []
         questions: {}
         questionsMap: {}
-      @props.workflow.update 'tasks'
+      @props.onChange @props.task
       @clearState()

   resetMedia: (e) ->


Fix indentation error

Fix indentation error

--- scripts/bungie.coffee
+++ scripts/bungie.coffee
@@ -98,7 +98,7 @@
         getVendorDetails(res, vendorHash).then (vendorDetails) ->

           category for category in vendorDetails.saleItemCategories when category.categoryTitle is 'Material Exchange'
-            console.log "#{vendorDetails.vendorName}: #{category}"
+          console.log "#{vendorDetails.vendorName}: #{category}"

     else
       # command not recognized. Lists all available commands


Try Promise

Try Promise

--- scripts/bungie.coffee
+++ scripts/bungie.coffee
@@ -67,10 +67,10 @@
               return deferred.resolve(category.salesItems)
         , (err) ->
           return deferred.reject(err)
-
+        deferred.promise()
         itemCategoriesDefers.push deferred

-      $.when itemCategoriesDefers .done (bountyItems) ->
+      Promice.all(itemCategoriesDefers).done (bountyItems) ->
         console.log 'bountyItems = '
         console.log bountyItems


Load MathJax like any other requirejs dependency

--- scripts/config.coffee
+++ scripts/config.coffee
@@ -3,6 +3,9 @@
 require.config
   # # Configure Library Locations
   paths:
+
+    mathjax: 'http://cdn.mathjax.org/mathjax/2.0-latest/MathJax.js?config=TeX-MML-AM_HTMLorMML-full&delayStartupUntil=configured'
+
     # ## Template and Style paths
     templates: '../templates'
     styles: '../styles'
@@ -95,18 +98,21 @@
       exports: 'Select2'

     aloha:
-      deps: ['jquery', 'bootstrapModal', 'bootstrapPopover', 'cs!configs/aloha', 'cs!configs/mathjax']
+      deps: ['jquery', 'mathjax', 'cs!configs/aloha', 'bootstrapModal', 'bootstrapPopover']
       exports: 'Aloha'
-      init: ($, alohaConfig, mathjaxConfig) ->
-        script = document.createElement("script")
-        script.src = "http://cdn.mathjax.org/mathjax/2.0-latest/MathJax.js?config=TeX-MML-AM_HTMLorMML-full&delayStartupUntil=configured"
-        script.text = 'MathJax.Hub.Config(' + JSON.stringify(mathjaxConfig) + ');' + 'MathJax.Hub.Startup.onload();'
-
-        document.getElementsByTagName("head")[0].appendChild(script);
-
+      init: ($, mathjaxConfig) ->
         jQuery.browser.version = 10000 # Hack to fix aloha-editor's version checking

         return Aloha
+
+    mathjax:
+      deps: ['cs!configs/mathjax']
+      exports: 'MathJax'
+      init: (mathjaxConfig) ->
+        MathJax.Hub.Config(mathjaxConfig)
+        MathJax.Hub.Startup.onload()
+        return MathJax
+

   # Handlebars Requirejs Plugin Configuration
   # This configures `requirejs` plugins (used when loading templates `'hbs!...'`).


Fix background on mod creation

Fix background on mod creation

--- scripts/create.coffee
+++ scripts/create.coffee
@@ -132,7 +132,6 @@
         if path == null
             p.textContent = 'Please upload images only.'
         else
-            document.querySelector('html').style.backgroundImage = "url('#{path.url}')"
             document.getElementById('backgroundMedia').value = path.file
             setTimeout(() ->
                 box.removeChild(p)


Do not send a parameter with the current time when requesting folders via Ajax.

This kept the client from leveraging HTTP caching.

--- app/assets/javascripts/ng-services/ng-FeedsFoldersSvc.js.coffee
+++ app/assets/javascripts/ng-services/ng-FeedsFoldersSvc.js.coffee
@@ -99,8 +99,7 @@
   # PRIVATE FUNCTION: Load folders.
   #--------------------------------------------
   load_folders = ->
-    now = new Date()
-    $http.get("/api/folders.json?time=#{now.getTime()}")
+    $http.get("/api/folders.json")
     .success (data)->
       reset_timer()


fix event triguer

fix event triguer

--- BackofficeBundle/Resources/public/coffee/ribbonButton/RibbonFormButtonView.coffee
+++ BackofficeBundle/Resources/public/coffee/ribbonButton/RibbonFormButtonView.coffee
@@ -17,11 +17,11 @@
   setFocusedView: (view, container) ->
     @container = if typeof container == 'undefined' then $('.ribbon-form-button') else container
     @container.html('')
-    view.setElement(@container)
     viewContext = this
     $('.btn-in-ribbon', view.$el).each ->
       viewContext.cloneButton $(this)
       return
+    this.setElement @container
     return

   ###*$
@@ -33,7 +33,9 @@
     @container.append(clonedButton)

   clickClone: (event) ->
-    console.log("omar")
+    event.preventDefault
+    console.log("test event")
+    console.debug(event)

 jQuery ->
   appConfigurationView.setConfiguration('ribbon-form-button', 'createRibbonFormButton', OpenOrchestra.RibbonButton.RibbonFormButtonView)


Controls binding code refactoring.

Controls binding code refactoring.

--- src/NESCoffee.coffee
+++ src/NESCoffee.coffee
@@ -103,35 +103,37 @@
     ###########################################################

     bindControl: (port, device, button, srcDevice, srcButton, unbindCallback) ->
-        binder = @binder
-        @replaceUnbindCallback port, device, button, srcDevice, srcButton, ->
-            binder.unbindControl srcDevice, srcButton
+        @unbindControl   port, device, button, srcDevice, srcButton
+        @bindInputDevice port, device, button, srcDevice, srcButton, unbindCallback
+
+    unbindControl: (port, device, button, srcDevice, srcButton) ->
+        @unbindCallbacks1[port]?[device]?[button]?() if port and device and button
+        @unbindCallbacks2[srcDevice]?[srcButton]?()  if srcDevice and srcButton
+
+    bindInputDevice: (port, device, button, srcDevice, srcButton, unbindCallback) ->
+        unbindInputDevice = @getUnbindInputDeviceCallback port, device, button, srcDevice, srcButton, unbindCallback
+        useInputDevice = @getUseInputDeviceCallback port, device, button
+        @unbindCallbacks1[port]?[device]?[button] = unbindInputDevice
+        @unbindCallbacks2[srcDevice]?[srcButton] = unbindInputDevice
+        @binder.bindControl srcDevice, srcButton, useInputDevice
+
+    unbindInputDevice: (port, device, button, srcDevice, srcButton) ->
+        @binder.unbindControl srcDevice, srcButton
+        @unbindCallbacks1[port]?[device]?[button] = null
+        @unbindCallbacks2[srcDevice]?[srcButton] = null
+
+    getUnbindInputDeviceCallback: (port, device, button, srcDevice, srcButton, unbindCallback) ->
+        self = @
+        ->
+            self.unbindInputDevice port, device, button, srcDevice, srcButton
             unbindCallback()
-        callback = @getInputDeviceCallback port, device, button
-        @binder.bindControl srcDevice, srcButton, callback
-
-    replaceUnbindCallback: (port, device, button, srcDevice, srcButton, callback) ->
-        unbindCallbacks1 = @unbindCallbacks1
-        unbindCallbacks2 = @unbindCallbacks2
-        unbindCallbacks1[port]?[device]?[button]?()
-        unbindCallbacks1[port]?[device]?[button] = ->
-            unbindCallbacks2[srcDevice]?[srcButton] = null
-            callback()
-        unbindCallbacks2[srcDevice]?[srcButton]?()
-        unbindCallbacks2[srcDevice]?[srcButton] = ->
-            unbindCallbacks1[port]?[device]?[button] = null
-            callback()
-
-    getInputDeviceCallback: (port, device, button) ->
+
+    getUseInputDeviceCallback: (port, device, button) ->
         if device is "joypad"
             button = joypadButtonToId[button.toLowerCase()] or 0
             @inputDevices[port]?.joypad.setButtonPressed.bind this, button
         else if device is "zapper"
             @inputDevices[port]?.zapper.setTriggerPressed.bind this
-
-    unbindControl: (port, device, button) ->
-        @unbindCallbacks1[port]?[device]?[button]?()
-        @unbindCallbacks1[port]?[device]?[button] = null

     ###########################################################
     # Input recording


Just try cutting out his points instead.

--- scripts/points.coffee
+++ scripts/points.coffee
@@ -103,9 +103,9 @@
             chat = JSON.parse(body)
             people = flatten([chat.chatters.moderators, chat.chatters.staff, chat.chatters.admins, chat.chatters.global_mods, chat.chatters.viewers])

-            for username in people not 'awebot'
+            for username in people
                 points[username] ?= 0
-                points[username] += 5
+                points[username not 'awebot'] += 5
                 save(robot)

             # Winners (and then recall) is equal to all users


Show colon in message

Show colon in message

--- lib/go-to-line-view.coffee
+++ lib/go-to-line-view.coffee
@@ -87,5 +87,5 @@
     if editor = atom.workspace.getActiveEditor()
       @storeFocusedElement()
       atom.workspaceView.append(this)
-      @message.text("Enter a line number 1-#{editor.getLineCount()} and column number")
+      @message.text("Enter a row:column to go to")
       @miniEditor.focus()


Call methods on TextEditor model

Call methods on TextEditor model

--- lib/go-to-line-view.coffee
+++ lib/go-to-line-view.coffee
@@ -43,13 +43,13 @@

   confirm: ->
     lineNumber = @miniEditor.getText()
-    editorView = atom.workspaceView.getActiveView()
+    editor = atom.workspace.getActiveTextEditor()

     @detach()

-    return unless editorView? and lineNumber.length
+    return unless editor? and lineNumber.length

-    currentRow = editorView.getModel().getCursorBufferPosition().row
+    currentRow = editor.getCursorBufferPosition().row
     [row, column] = lineNumber.split(/:+/)
     if row?.length > 0
       # Line number was specified
@@ -69,10 +69,10 @@
       column = -1

     position = new Point(row, column)
-    editorView.scrollToBufferPosition(position, center: true)
-    editorView.editor.setCursorBufferPosition(position)
+    editor.scrollToBufferPosition(position, center: true)
+    editor.setCursorBufferPosition(position)
     if column < 0
-      editorView.editor.moveCursorToFirstCharacterOfLine()
+      editor.moveCursorToFirstCharacterOfLine()

   storeFocusedElement: ->
     @previouslyFocusedElement = $(':focus')


Unneeded db reads

Unneeded db reads

--- index.coffee
+++ index.coffee
@@ -42,14 +42,7 @@
     method: 'GET',
     path: '/families',
     handler: (request, reply) ->
-      addresses = []
-      config.addressesDB.createReadStream()
-        .on('data', (data) ->
-          addresses.push data.value
-        )
-        .on('end', ->
-          reply(addresses)
-        )
+      reply(families.addresses)
 })
 server.route({
     method: 'GET',


Handle break event from voxel-mine

Handle break event from voxel-mine

--- index.coffee
+++ index.coffee
@@ -133,6 +133,9 @@
   game.on 'place', (adjacent) ->
     game.createBlock adjacent, game.currentMaterial

+  game.on 'break', (goner) ->
+    game.setBlock goner, 0
+
   game.on 'tick', () ->
     walk.render target.playerSkin
     vx = Math.abs target.velocity.x


Remove unused params

Remove unused params

--- index.coffee
+++ index.coffee
@@ -49,7 +49,7 @@
       nugetOutput
     ]

-    spawn {cmd, args}, (error, result, code) ->
+    spawn {cmd, args}, (error) ->
       return done(error) if error?

       nupkgPath = path.join(nugetOutput, "#{metadata.name}.#{metadata.version}.nupkg")
@@ -64,4 +64,4 @@
         loadingGif
       ]

-      spawn {cmd, args}, (error, result, code) -> done(error)
+      spawn {cmd, args}, (error) -> done(error)


remove the basement

remove the basement

--- index.coffee
+++ index.coffee
@@ -51,5 +51,4 @@
 assert nucleus = module.exports.nucleus
 assert membrane = module.exports.membrane
 assert exposure = module.exports.exposure
-assert basement = module.exports.basement
 module.exports.cakefile = nucleus.cakefile


Disable default Google Maps controls

Disable default Google Maps controls

--- prototypes/load_maps/coffeescripts/main.coffee
+++ prototypes/load_maps/coffeescripts/main.coffee
@@ -1,6 +1,7 @@
-jQuery ->
+$ ->
 	myOptions =
 		center: new google.maps.LatLng(-34.397, 150.644)
 		zoom: 8
+		disableDefaultUI: true
 		mapTypeId: google.maps.MapTypeId.ROADMAP
 	map = new google.maps.Map(document.getElementById("centermap"), myOptions)