Initial problem list functionality

Initial problem list functionality

--- lms/static/coffee/src/staff_grading/staff_grading.coffee
+++ lms/static/coffee/src/staff_grading/staff_grading.coffee
@@ -36,19 +36,20 @@
     else if cmd == 'save_grade'
       console.log("eval: #{data.score} pts,  Feedback: #{data.feedback}")
       response =
-        @mock('get_next', {})
-    # get_probblem_list
+        @mock('get_next', {location})
+    # get_problem_list
     # sends in a course_id and a grader_id
     # should get back a list of problem_ids, problem_names, num_left, num_total
     else if cmd == 'get_problem_list'
-        response =
-            success: true
-            problem_list: [
-                {location: 'i4x://MITx/3.091x/problem/open_ended_demo', \
-                    problem_name: "Problem 1", num_left: 3, num_total: 5},
-                {location: 'i4x://MITx/3.091x/problem/open_ended_demo', \
-                    problem_name: "Problem 2", num_left: 1, num_total: 5}
-            ]
+      @mock_cnt++
+      response =
+        success: true
+        problem_list: [
+          {location: 'i4x://MITx/3.091x/problem/open_ended_demo', \
+            problem_name: "Problem 1", num_left: 3, num_total: 5},
+          {location: 'i4x://MITx/3.091x/problem/open_ended_demo', \
+            problem_name: "Problem 2", num_left: 1, num_total: 5}
+        ]
     else
       response =
         success: false
@@ -79,8 +80,13 @@
 class StaffGrading
   constructor: (backend) ->
     @backend = backend
+    @list_view = true

     # all the jquery selectors
+
+    @problem_list_container = $('.problem-list-container')
+    @problem_list = $('.problem-list')
+
     @error_container = $('.error-container')
     @message_container = $('.message-container')

@@ -108,17 +114,19 @@
     @message = ''
     @max_score = 0
     @ml_error_info= ''
+    @location = ''

     @score = null
+    @problems = null

     # action handlers
     @submit_button.click @submit

     # render intial state
-    @render_view()
+    #@render_view()

     # send initial request automatically
-    @get_next_submission()
+    @get_problem_list()

   setup_score_selection: =>
@@ -153,7 +161,9 @@
     @message = ''

     if response.success
-      if response.submission
+      if response.problem_list
+        @problems = response.problem_list
+      else if response.submission
         @data_loaded(response.prompt, response.submission, response.rubric, response.submission_id, response.max_score, response.ml_error_info)
       else
         @no_more(response.message)
@@ -162,8 +172,13 @@

     @render_view()

-  get_next_submission: () ->
-    @backend.post('get_next', {}, @ajax_callback)
+  get_next_submission: (location) ->
+    @location = location
+    @list_view = false
+    @backend.post('get_next', {location}, @ajax_callback)
+
+  get_problem_list: () ->
+    @backend.post('get_problem_list', {}, @ajax_callback)

   submit_and_get_next: () ->
     data =
@@ -202,14 +217,41 @@
     @state = state_no_data

   render_view: () ->
-    # make the view elements match the state.  Idempotent.
-    show_grading_elements = false
-    show_submit_button = true
-
+    # clear the problem list
+    @problem_list.html('')
     @message_container.html(@message)
+    # only show the grading elements when we are not in list view or the state
+    # is invalid
+    show_grading_elements = !(@list_view || @state == state_error ||
+      @state == state_no_data)
+    @prompt_wrapper.toggle(show_grading_elements)
+    @submission_wrapper.toggle(show_grading_elements)
+    @rubric_wrapper.toggle(show_grading_elements)
+    @ml_error_info_container.toggle(show_grading_elements)
+    @submit_button.hide()
+
     if @backend.mock_backend
       @message_container.append("
NOTE: Mocking backend.
")
-
+    if @list_view
+      @render_list()
+    else
+      @render_problem()
+
+  problem_link:(problem) ->
+    link = $('').attr('href', "javascript:void(0)").append(
+      "#{problem.problem_name} (#{problem.num_left} / #{problem.num_total})")
+        .click =>
+          @get_next_submission problem.location
+
+
+  render_list: () ->
+    for problem in @problems
+      @problem_list.append($('
').append(@problem_link(problem)))
+
+  render_problem: () ->
+    # make the view elements match the state.  Idempotent.
+    show_submit_button = true
+
     @error_container.html(@error_msg)

     if @state == state_error
@@ -220,7 +262,6 @@
       @prompt_container.html(@prompt)
       @submission_container.html(@submission)
       @rubric_container.html(@rubric)
-      show_grading_elements = true

       # no submit button until user picks grade.
       show_submit_button = false
@@ -228,7 +269,6 @@
       @setup_score_selection()

     else if @state == state_graded
-      show_grading_elements = true
       @set_button_text('Submit')

     else if @state == state_no_data
@@ -239,21 +279,16 @@
       @error('System got into invalid state ' + @state)

     @submit_button.toggle(show_submit_button)
-    @prompt_wrapper.toggle(show_grading_elements)
-    @submission_wrapper.toggle(show_grading_elements)
-    @rubric_wrapper.toggle(show_grading_elements)
-    @ml_error_info_container.toggle(show_grading_elements)
-

   submit: (event) =>
     event.preventDefault()

     if @state == state_error
-      @get_next_submission()
+      @get_next_submission(@location)
     else if @state == state_graded
       @submit_and_get_next()
     else if @state == state_no_data
-      @get_next_submission()
+      @get_next_submission(@location)
     else
       @error('System got into invalid state for submission: ' + @state)


Actually remove element when animation is completed.

--- app/scripts/views/tile_view.coffee
+++ app/scripts/views/tile_view.coffee
@@ -38,7 +38,8 @@
       translate3d: "#{@left}px, #{@top + 150}px, 0"
       opacity: 0
     ,
-      complete: -> @remove()
+      complete: =>
+        @$el.remove()

   play: ->
     return if not @tilesToPlay = @getTilesToPlay() if not @tilesToPlay


fix to get past messages again.

fix to get past messages again.

--- chat/grails-app/assets/javascripts/chat.coffee
+++ chat/grails-app/assets/javascripts/chat.coffee
@@ -61,12 +61,12 @@
 # DateTimePicker changed eventhandler
 $('#datetimepickerInline').on 'dp.change', (event) ->
     updateMessageNumberBadges()
-    selectedDate = moment(event.date).format('YYYY/MM/DD')
-
-    if selectedDate >= moment().format('YYYY/MM/DD') then return
+    selectedDate = moment(event.date).format('YYYY-MM-DD')
+
+    if selectedDate >= moment().format('YYYY-MM-DD') then return

     crs = $('#chatRoomSelected').val()
-    count = sessionStorage.getItem(crs + '_' + selectedDate)
+    count = sessionStorage.getItem(crs + '_' + selectedDate.replace('-', '/'))
     if '' + count is '0' then return

     $('#area_log').append """


fix mistake

fix mistake

--- index.cjsx
+++ index.cjsx
@@ -75,12 +75,15 @@
       sortieTot += (sortieHp[i] + sortieHp[i + 12])
       enemyDmg += sortieHp[i + 12]
       if sortieHp[i] <= 0
+        enemyDmg += (sortieHp[i] - 0)
         sortieDrop += 1
+        sortieHp[i] = 0
     if combinedHp[i] + combinedHp[i + 12] > 0
       sortieCnt += 1
       sortieTot += (combinedHp[i] + combinedHp[i + 12])
-      enemyDmg += ombinedHp[i + 12]
+      enemyDmg += combinedHp[i + 12]
       if combinedHp[i] <= 0
+        enemyDmg += (combinedHp[i] - 0)
         sortieDrop += 1
         combinedHp[i] = 0
     if enemyHp[i] + enemyHp[i + 12] > 0
@@ -88,6 +91,7 @@
       enemyTot += (enemyHp[i] + enemyHp[i + 12])
       sortieDmg += enemyHp[i + 12]
       if enemyHp[i] <= leastHp
+        sortieDmg += (enemyHp[i] - leastHp)
         enemyDrop += 1
         enemyHp[i] = leastHp
     if enemyDrop == enemyCnt


remove nav bar code from overrides

remove nav bar code from overrides

--- readymade/overrides.coffee
+++ readymade/overrides.coffee
@@ -10,16 +10,6 @@
 classify_page.el.on 'activate-in-stack', ->
   if classify_page.tutorial.el.getAttribute('aria-hidden') is 'false'
     setTimeout => classify_page.tutorial.active_button?.focus()
-
-console.log header
-# build tabbed main nav
-header.buildNav()
-
-# add external links
-externalLinks =
-  Blog: 'http://blog.zooniverse.org'
-  Twitter: 'http://twitter.com/the_zooniverse'
-header.addNavLink href, title for title, href of externalLinks

 # focus management for the decision tree.
 decisionTree.autofocus = false


FIX: Add optional data in error callbacks

--- src/app/common/services/group-service.coffee
+++ src/app/common/services/group-service.coffee
@@ -51,7 +51,7 @@
         )
         onSuccess?(groupSet.groups)
       (failure) ->
-        alertService.add("danger", failure.data.error, 6000)
+        alertService.add("danger", failure.data?.error || "Unknown Error", 6000)
         onFailure?(failure)
     )

@@ -74,7 +74,7 @@
         alertService.add("success", "#{newGroup.name} was created!", 3000)
         onSuccess?(newGroup)
       (failure) ->
-        alertService.add("danger", failure.data.error, 6000)
+        alertService.add("danger", failure.data?.error || "Unknown Error", 6000)
         onFailure?(failure)
     )

@@ -89,7 +89,7 @@
         alertService.add("info", "#{group.name} was updated", 3000)
         onSuccess?(success)
       (failure) ->
-        alertService.add("danger", failure.data.error, 6000)
+        alertService.add("danger", failure.data?.error || "Unknown Error", 6000)
         onFailure?(failure)
     )

@@ -103,7 +103,7 @@
         alertService.add("info", "#{group.name} was deleted", 3000)
         onSuccess?(unit.groups)
       (failure) ->
-        alertService.add("danger", failure.data.error, 3000)
+        alertService.add("danger", failure.data?.error || "Unknown Error", 3000)
         onFailure?(failure)
     )

@@ -140,7 +140,7 @@
         else
           group.getMembers(onSuccess, onFailure)
       (failure) ->
-        alertService.add("danger", failure.data.error, 6000)
+        alertService.add("danger", failure.data?.error || "Unknown Error", 6000)
         onFailure?(failure)
     )

@@ -161,7 +161,7 @@
         else
           group.getMembers(onSuccess, onFailure)
       (failure) ->
-        alertService.add("danger", failure.data.error, 6000)
+        alertService.add("danger", failure.data?.error || "Unknown Error", 6000)
         onFailure?(failure)
     )


0;95;cRemove unnecessary boolean conversion.

--- common/lib/xmodule/xmodule/js/src/video/display.coffee
+++ common/lib/xmodule/xmodule/js/src/video/display.coffee
@@ -5,7 +5,7 @@
     @start = @el.data('start')
     @end = @el.data('end')
     @caption_asset_path = @el.data('caption-asset-path')
-    @show_captions = !!@el.data('show-captions')
+    @show_captions = @el.data('show-captions')
     window.player = null
     @el = $("#video_#{@id}")
     @parseVideos @el.data('streams')


MachineStateModal: much cleaner

MachineStateModal: much cleaner

--- client/Main/providers/machinestatemodal.coffee
+++ client/Main/providers/machinestatemodal.coffee
@@ -73,10 +73,10 @@
       @state    = status
       @hasError = error?.length > 0

-      unless percentage?
-        return @switchToIDEIfNeeded()
-
-      if percentage is 100
+      if not percentage?
+        @switchToIDEIfNeeded()
+
+      else if percentage is 100
         @completeCurrentProcess status

       else if task is 'reinit'


Add ChangeLog and default files (it requires some changes on server-side)

--- client/app/MainApp/kodingappscontroller.coffee
+++ client/app/MainApp/kodingappscontroller.coffee
@@ -525,11 +525,13 @@
     appPath     = getAppPath manifest
     log manifestStr

-
     FSItem.create appPath, "folder", (err, fsFolder)=>
       if err then warn err
       else
         stack = []
+        today = new Date().format('yyyy-mm-dd')
+        {profile} = KD.whoami()
+        fullName = Encoder.htmlDecode "#{profile.firstName} #{profile.lastName}"

         stack.push (cb)=>
           @kiteController.run
@@ -546,6 +548,33 @@
               path      : escapeFilePath "#{fsFolder.path}/index.coffee"
               contents  : "do ->"
           , cb
+
+        stack.push (cb)=>
+          @kiteController.run
+            toDo        : "uploadFile"
+            withArgs    :
+              path      : escapeFilePath "#{fsFolder.path}/ChangeLog"
+              contents  : """
+                              #{today} #{fullName} <@#{profile.nickname}>
+
+                                  * #{name} (index.coffee): Initial commit
+                          """
+          , cb
+
+        # Uncomment followings when we have reachable files for skel of Apps
+        #
+        # stack.push (cb)=>
+        #   @kiteController.run
+        #     withArgs  :
+        #       command : "cp -f /opt/Apps/.default/README #{escapeFilePath fsFolder.path}"
+        #   , cb
+
+        # if not isBlank
+        #   stack.push (cb)=>
+        #     @kiteController.run
+        #       withArgs  :
+        #         command : "cp -rf /opt/Apps/.default/resources #{escapeFilePath fsFolder.path}"
+        #     , cb

         async.parallel stack, (error, result) =>
           if err then warn err


ComputeHelpers: fix softlayer vm create logic for admins

--- client/app/lib/providers/computehelpers.coffee
+++ client/app/lib/providers/computehelpers.coffee
@@ -156,13 +156,14 @@

         machines ?= []

-        if err? or machines.length > 0
+        if err? or machines.length > 0 and provider isnt 'softlayer'
+
           new ComputePlansModalFree options
           cc._inprogress = no

           callback()

-        else if machines.length is 0
+        else

           stack   = cc.stacks.first._id
           storage = plans[plan]?.storage or 3


fix a bug in KDRouter, ass :name?/Dashboard route

--- client/landing/app/MainApp/kodingrouter.coffee
+++ client/landing/app/MainApp/kodingrouter.coffee
@@ -14,8 +14,10 @@
     @on 'AlreadyHere', ->
       new KDNotificationView title: "You're already here!"

+  listen:->
+    super
     unless @userRoute
-      @handleRoute defaultRoute,
+      @handleRoute @defaultRoute,
         shouldPushState: yes
         replaceState: yes

@@ -156,9 +158,6 @@

     clear = @bound 'clear'

-    openGroupAdminDashboard = =>
-      @getSingleton('groupsController').openAdminDashboard arguments...
-
     requireLogin =(fn)->
       mainController.accountReady ->
         # console.log 'faafafaf'
@@ -197,7 +196,11 @@
       '/:name?/Account'                 : section.Account

       # group dashboard
-      '/:name?/Dashboard'               : content.Groups
+      '/:name?/Dashboard'               : (routeInfo, state, route)->
+        {name} = routeInfo.params
+        KD.remote.cacheable name, (err, group, nameObj)=>
+          @openContent name, 'Groups', group, route
+

       # content
       '/:name?/Topics/:topicSlug'       : content.Topics
@@ -214,7 +217,8 @@
           mainController.loginScreen.hidden = no

           recoveryToken = decodeURIComponent recoveryToken
-          KD.remote.api.JPasswordRecovery.validate recoveryToken, (err, isValid)=>
+          {JPasswordRecovery} = KD.remote.api
+          JPasswordRecovery.validate recoveryToken, (err, isValid)=>
             if err or !isValid
               new KDNotificationView
                 title   : 'Something went wrong.'


Support i18n: zh-TW

Support i18n: zh-TW

--- index.cjsx
+++ index.cjsx
@@ -5,11 +5,12 @@

 # i18n
 window.i18n.secretary = new(require 'i18n-2')
-  locales: ['en-US', 'ja-JP', 'zh-CN', 'zh-TW'],
-  defaultLocale: 'zh-CN',
-  directory: join(__dirname, 'i18n'),
-  updateFiles: false,
+  locales: ['en-US', 'ja-JP', 'zh-CN', 'zh-TW']
+  defaultLocale: 'zh-CN'
+  directory: path.join(__dirname, "i18n")
   extension: '.json'
+  updateFiles: false
+  devMode: false
 window.i18n.secretary.setLocale(window.language)
 __ = window.i18n.secretary.__.bind(window.i18n.secretary)
 __r = window.i18n.resources.__.bind(window.i18n.resources)


Remove commented out code.

Remove commented out code.

--- cms/static/coffee/src/views/module_edit.coffee
+++ cms/static/coffee/src/views/module_edit.coffee
@@ -92,7 +92,6 @@
         title: gettext('Saving…')
       saving.show()
       @model.save(data).done( =>
-      #   # showToastMessage("Your changes have been saved.", null, 3)
         @module = null
         @render()
         @$el.removeClass('editing')


Update test data of checking year

Update test data of checking year

--- src/test/testData.coffee
+++ src/test/testData.coffee
@@ -48,14 +48,14 @@
   # fail test: date and future date
   {id: '110101188606258888', cardType: 'cnid', expect: true}
   {id: '110101188606248882', cardType: 'cnid', expect: false}
-  {id: '110101201701018886', cardType: 'cnid', expect: true} #todo to be dynamic
-  {id: '110101201712128888', cardType: 'cnid', expect: false} #todo to be dynamic
-  {id: '000101-3234560', cardType: 'krid', expect: true} # age 17 in 2017
-  {id: '001231-3234565', cardType: 'krid', expect: false} # age 16 in 2017
+  {id: '110101201901018880', cardType: 'cnid', expect: true} #todo update every year
+  {id: '110101201912128882', cardType: 'cnid', expect: false} #todo update every year
+  {id: '020101-3234564', cardType: 'krid', expect: true} #todo age 17 in 2019 (update every year)
+  {id: '021231-3234560', cardType: 'krid', expect: false} #todo age 16 in 2019 (update every year)
   {id: '991128-9123457', cardType: 'krid', expect: false} # date before 18991129
   {id: '991129-9123451', cardType: 'krid', expect: true} # date before 18991129
-  {id: '170101-3234569', cardType: 'krid', expect: false} # false year, 2017
-  {id: '171231-3234564', cardType: 'krid', expect: false} # false year, future date
+  {id: '190101-3234563', cardType: 'krid', expect: false} # false year, 2017
+  {id: '191231-3234569', cardType: 'krid', expect: false} # false year, future date
   {id: '990001-1234568', cardType: 'krid', expect: false} # false month
   {id: '991301-1234561', cardType: 'krid', expect: false} # false month
   {id: '990100-1234560', cardType: 'krid', expect: false} # false day


truerrrrrrr on line 295

truerrrrrrr on line 295

Probably a typo, there was a "truerrrrr" instead of a "true"

--- lib/split-diff.coffee
+++ lib/split-diff.coffee
@@ -292,7 +292,7 @@

     # turn off soft wrap setting for these editors so diffs properly align
     if editor1.isSoftWrapped()
-      @wasEditor1SoftWrapped = truerrrrrrrrrr
+      @wasEditor1SoftWrapped = true
     if editor2.isSoftWrapped()
       @wasEditor2SoftWrapped = true
       editor2.setSoftWrapped(false)


修改目录类型的标识,'+'改为'.'

修改目录类型的标识,'+'改为'.'

--- lib/subcmd/dir.coffee
+++ lib/subcmd/dir.coffee
@@ -29,7 +29,7 @@
       if stats.isDirectory()
         node.push obj =
           text: dir
-          type: '+'
+          type: '.'
           children: []
         if deep - 2 < maxDeep
           for file in fse.readdirSync(filePath)


get the options from the ipkg file

get the options from the ipkg file

--- lib/utils/ipkg.coffee
+++ lib/utils/ipkg.coffee
@@ -2,6 +2,10 @@
 fs = require 'fs'
 Rx = require 'rx-lite'

+optionsRegexp = /opts\s*=\s*\"([^\"]*)\"/
+
+# Find all ipkg-files in a directory and returns
+# an observable of an array of files
 findIpkgFile = (project) ->
   directory = project.getDirectories()[0].path
   readDir = Rx.Observable.fromNodeCallback fs.readdir
@@ -18,7 +22,11 @@
           file.ext == '.ipkg'

 parseIpkgFile = (ipkgFile) ->
-  []
+  matches = ipkgFile.match optionsRegexp
+  if matches
+    [matches[1]]
+  else
+    []

 readIpkgFile = (ipkgFile) ->
   readFile = Rx.Observable.fromNodeCallback fs.readFile


修改应用标识校验规则

修改应用标识校验规则

--- lib/utils/util.coffee
+++ lib/utils/util.coffee
@@ -55,7 +55,7 @@

   # 将传递过来的 str 进行判断是否符合文件命名，如果不符合，将不符合的字符改为"-", 并进行去重
   checkProjectName: (str)->
-    regEx5 = /^([A-Za-z]+\w*\.){2,}[A-Za-z]+\w*$/
+    regEx5 = /^([A-Za-z]+\.){2,}[A-Za-z]+\w*$/
     regEx6 = /^.{10,64}$/
     flag5 = regEx5.test str
     flag6 = regEx6.test str


Give a flakey spec more time to execute

Give a flakey spec more time to execute

--- spec_app/spec/javascripts/up/proxy_spec.js.coffee
+++ spec_app/spec/javascripts/up/proxy_spec.js.coffee
@@ -868,7 +868,7 @@
       it 'preloads the link destination on mouseover, after a delay'

       it 'triggers a separate AJAX request when hovered multiple times and the cache expires between hovers', asyncSpec (next)  ->
-        up.proxy.config.cacheExpiry = 20
+        up.proxy.config.cacheExpiry = 50
         up.proxy.config.preloadDelay = 0
         $element = affix('a[href="/foo"][up-preload]')
         Trigger.mouseover($element)
@@ -882,7 +882,7 @@
         next.after 1, =>
           expect(jasmine.Ajax.requests.count()).toEqual(1)

-        next.after 20, =>
+        next.after 60, =>
           Trigger.mouseover($element)

         next.after 1, =>


Added a check in the WMS request, new version of EOxServer can return list of timespans instead of list of single times. This is a quick fix, the issue has to be reviewed

--- src/d3.timeslider.coffee
+++ src/d3.timeslider.coffee
@@ -193,7 +193,13 @@
                             else
                                 ranges.push(element)
                         else
-                            points.push(element)
+                            # TODO: This if statement is a quick solution for when the
+                            # server returns a timespan this has to be redesigned
+                            # It assumes start and end time of timespan is equal
+                            if (element.split("/").length>1)
+                                points.push(element.split("/")[0])
+                            else
+                                points.push(element)

                     @data[id].ranges = ranges
                     @data[id].points = points


Refacator restore/save code.

Refacator restore/save code.

Some the long-reach code here is ugly.  Things are too spread around.

This refactors the code called on "save" to a callback.  Thus, the code
related to backup and restore is localised.

--- pages/options.coffee
+++ pages/options.coffee
@@ -1,7 +1,6 @@

 $ = (id) -> document.getElementById id
 bgExclusions = chrome.extension.getBackgroundPage().Exclusions
-restoreSettingsVersion = null

 # We have to use Settings from the background page here (not Settings, directly) to avoid a race condition for
 # the page popup.  Specifically, we must ensure that the settings have been updated on the background page
@@ -40,17 +39,14 @@
     bgSettings.clear @field
     @fetch()

+  @onSaveCallbacks: []
+  @onSave: (callback) ->
+    @onSaveCallbacks.push callback
+
   # Static method.
   @saveOptions: ->
     Option.all.map (option) -> option.save()
-    # If we're restoring a backup, then restore the backed up settingsVersion.
-    if restoreSettingsVersion?
-      bgSettings.set "settingsVersion", restoreSettingsVersion
-      restoreSettingsVersion = null
-    # Reset the restore-backup input.
-    $("chooseFile").value = ""
-    # We need to apply migrations in case we are restoring an old backup.
-    bgSettings.applyMigrations()
+    callback() for callback in @onSaveCallbacks

   # Abstract method; only implemented in sub-classes.
   # Populate the option's DOM element (@element) with the setting's current value.
@@ -337,6 +333,8 @@
 #
 # Backup and restore. "?" is for the tests."
 DomUtils?.documentReady ->
+  restoreSettingsVersion = null
+
   populateBackupLinkUrl = ->
     backup = settingsVersion: bgSettings.get "settingsVersion"
     for option in Option.all
@@ -368,6 +366,16 @@
             option.populateElement backup[option.field]
             option.onUpdated()

+  Option.onSave ->
+    # If we're restoring a backup, then restore the backed up settingsVersion.
+    if restoreSettingsVersion?
+      bgSettings.set "settingsVersion", restoreSettingsVersion
+      restoreSettingsVersion = null
+    # Reset the restore-backup input.
+    $("chooseFile").value = ""
+    # We need to apply migrations in case we are restoring an old backup.
+    bgSettings.applyMigrations()
+
 # Exported for tests.
 root = exports ? window
 extend root, {Options, isVimiumOptionsPage: true}


Use reset for better performance

Use reset for better performance

--- core/app/backbone/collections/search_collection.coffee
+++ core/app/backbone/collections/search_collection.coffee
@@ -19,7 +19,7 @@
       @trigger 'sync'
     else
       @reset []
-      @jqxhr = @fetch()
+      @jqxhr = @fetch(reset: true) # because the CollectionUtils do a full reset on add/remove

   encodedQuery: -> encodeURIComponent @query


Found edge case around standard deviation being 0.

--- pca-visualize.coffee
+++ pca-visualize.coffee
@@ -71,6 +71,13 @@

 					# Normalize the attribute, shoving the new value into doc["normalized_"+attr]
 					for doc in docs
+
+						# Edge case that the standard div is 0. As in, all the values
+						# are the same. We don't want to return NaN.
+						if standard_deviations[attr] is 0
+							doc["normalized_" + attr] = 0
+							continue
+
 						doc["normalized_" + attr] = doc[attr] - means[attr]
 						doc["normalized_" + attr] = doc["normalized_" + attr] / standard_deviations[attr]

@@ -81,7 +88,7 @@
 					for attr in req.query.attributes
 						_i.push doc["normalized_" + attr]
 					matrix.push _i
-
+
 				# Project into 2 dimensions..
 				svd	= sylvester.Matrix.create matrix
 				k	= svd.pcaProject 2


Style and comments

Style and comments

--- app/views/play/CampaignView.coffee
+++ app/views/play/CampaignView.coffee
@@ -384,24 +384,34 @@
       if level.unlocksHero
         level.purchasedHero = level.unlocksHero in (me.get('purchased')?.heroes or [])

+      # This function gets called 5+ times when visiting campaign screens
+      # Manually cache calls to minimize the amount of requests
       if not @itemCache[level.original]
-        @itemCache[level.original] = "pre-cache"
         if level.unlocksItem = _.find(level.rewards, 'item')?.item
+          @itemCache[level.original] = 'pre-cache'
+          # Gotta closure to preserve variable across for-loop
           do (level) =>
             request = @supermodel.addRequestResource 'load_full_thang', {
               url: "/db/thang.type/#{level.unlocksItem}/version",
               success: (data) =>
+                # Find the thang's Item component
                 itemComponent = data.components[_.findIndex(data.components, (elem) -> return elem.config?.slots?)]
-                @itemCache?[level.original] = "cached"
-                if itemComponent?.config? and itemComponent.config.slots.indexOf("pet") >= 0
+                # If the item is a pet
+                if itemComponent?.config? and itemComponent.config.slots.indexOf('pet') >= 0
+                  # Set the level to be the url of the pet image
                   level.unlocksPet = data.dollImages.pet
                   @itemCache?[level.original] = data.dollImages.pet
                   @renderSelectors("div[data-level-original=#{level.original}]")
+                else
+                  @itemCache?[level.original] = 'cached'
             }
             request.load()
+        else
+          @itemCache[level.original] = 'no-cache'
       else
         level.unlocksItem = _.find(level.rewards, 'item')?.item
-        if ["pre-cache", "cached"].indexOf(@itemCache[level.original]) is -1
+        if ['no-cache', 'pre-cache', 'cached'].indexOf(@itemCache[level.original]) is -1
+          # If there is a url in the cache, that is a pet unlock
           level.unlocksPet = @itemCache[level.original]

       if window.serverConfig.picoCTF


Null out task when deactivated

Null out task when deactivated

--- src/packages/fuzzy-finder/lib/fuzzy-finder.coffee
+++ src/packages/fuzzy-finder/lib/fuzzy-finder.coffee
@@ -3,6 +3,7 @@
 module.exports =
   projectPaths: null
   fuzzyFinderView: null
+  loadPathsTask: null

   activate: (state) ->
     rootView.command 'fuzzy-finder:toggle-file-finder', =>
@@ -24,6 +25,7 @@

   deactivate: ->
     @loadPathsTask?.terminate()
+    @loadPathsTask = null
     @fuzzyFinderView?.cancel()
     @fuzzyFinderView = null
     @projectPaths = null


Typo fix

Typo fix

--- files.coffee
+++ files.coffee
@@ -477,7 +477,7 @@
     @chunkSize  = Math.floor(@chunkSize / 8) * 8

     if @public and not @downloadRoute
-      throw new Meteor.Error 500, "[FilesCollection.#{@collectionName}]: \"downloadRoute\" must be precisely provided on \"public\" collections! Note: \"downloadRoute\" must be equal on be inside of your web/proxy-server (relative) root."
+      throw new Meteor.Error 500, "[FilesCollection.#{@collectionName}]: \"downloadRoute\" must be precisely provided on \"public\" collections! Note: \"downloadRoute\" must be equal or be inside of your web/proxy-server (relative) root."

     @collection        ?= new Mongo.Collection @collectionName
     @collectionName    ?= @collection._name


make sure to add the default module to the new book's opf file

--- scripts/gh-book/opf-file.coffee
+++ scripts/gh-book/opf-file.coffee
@@ -166,7 +166,8 @@
         #create empty module for the book
         module = new XhtmlFile {title: 'module1'}
         allContent.add(module)
-        @addChild(module)
+        @addChild(module) # for the nav file
+        @_addItem(module) # for this opf file

       clearTimeout(@_savingTimeout)
       @_savingTimeout = setTimeout (() =>


Inserted trailing newline into ‘prepFile’ method in ‘git-commit.coffee’ to fix syntax highlighting not appearing when local branch is ahead of remote branch.

--- lib/models/git-commit.coffee
+++ lib/models/git-commit.coffee
@@ -62,7 +62,7 @@
   # status - The current status as {String}.
   prepFile: (status) ->
     # format the status to be ignored in the commit message
-    status = status.replace(/\s*\(.*\)\n/g, '')
+    status = status.replace(/\s*\(.*\)\n/g, "\n")
     status = status.trim().replace(/\n/g, "\n#{@commentchar} ")
     fs.writeFileSync @filePath(),
       """#{@amend}


Always enable uninstall button after update

--- lib/package-update-view.coffee
+++ lib/package-update-view.coffee
@@ -33,8 +33,8 @@

   handlePackageEvents: ->
     @subscribeToPackageEvent 'package-updated theme-updated package-update-failed theme-update-failed', (pack, error) =>
+      @uninstallButton.prop('disabled', false)
       if error?
-        @uninstallButton.prop('disabled', false)
         @setStatusIcon('alert')
       else
         @setStatusIcon('check')


Refactor build plugin. Fix a rare bug causing the proj base lang not to load

--- lib/plugin/compile-i18n.coffee
+++ lib/plugin/compile-i18n.coffee
@@ -210,58 +210,19 @@

   return map

-buildUnifiedLangFiles = (compileStep=null, lang_files_path=default_build_files_path, supported_languages=null, project_translations_dir=null) ->
-  # Build the unified languages files on lang_files_path
-  #
-  # Returns an object whose keys are all the supported languages (if
-  # lang_files_path is null all the languages we find translation files to
-  # either in the project or in the packages are considered supported). The
-  # value for each key is *true* if we generated a language file for that
-  # language *false* otherwise. (language file is not generated if the language
-  # is supported but there are no files for it).
+getUnifiedLangFiles = (supported_languages=null, project_translations_dir=null) ->
+  # Generate the unified languages files
+  #
+  # Returns an object whose keys are all the supported languages and their
+  # translations.
   #
   # Attributes:
-  # lang_files_path (string): the path we build the unified languages files to
   # supported_languages (array or null): Array of languages tags to which
-  # unified files will be built. If null, a language file will be built for any
-  # language the project or one of its packages was translated to.
-
-  log "Building unified files directory: #{lang_files_path}"
-
-  lang_files_path = removeFileTrailingSeparator lang_files_path
-  lang_files_backup_path = "#{lang_files_path}~"
-
-  getLangFilePath = (lang) ->
-    lang_files_path + path.sep + lang + ".json"
-
-  # Remove old backup
-  try
-    wrench.rmdirSyncRecursive lang_files_backup_path
-    log "Old languages files backup #{lang_files_backup_path} removed"
-  catch error
-
-  # Create a backup for current lang_files_path
-  try
-    fs.renameSync lang_files_path, lang_files_backup_path
-    log "[IMPORTANT] unified languages files folder #{lang_files_path} already exists. Backing it up"
-    log "[IMPORTANT] to #{lang_files_backup_path}. If you need to, save the backup before building your"
-    log "[IMPORTANT] project again - otherwise you'll lose it."
-  catch error
-
-  # Create the new languages files dir
-  try
-    wrench.mkdirSyncRecursive lang_files_path, 0o744 # 0744 - owner: rwx, rest: r
-  catch error
-    throw new Meteor.Error 500, "Can't create folder `#{lang_files_path}'",
-      {error: error}
-
-  # A rollback procedure to use on failure
-  rollback = ->
-    log "Build failed, rolling back `#{lang_files_path}'"
-    wrench.rmdirSyncRecursive lang_files_path
-    try
-      fs.renameSync lang_files_backup_path, lang_files_path
-    catch error
+  # unified files will be generated. If null, a language file will be generated
+  # for any language the project or one of its packages was translated to.
+  # project_translations_dir: The project_translations_dir.
+
+  log "Generating unified languages files"

   packageTapI18nMaps =
     (wrench.readdirSyncRecursive project_root, (x) -> /package-tap.i18n$/.test(x)).map (x) -> loadPackageTapMap(x)
@@ -276,34 +237,6 @@
           lang_files_paths: project_lang_files_dir_map
       }

-      # If compileStep is defined and the base language was translated in the
-      # project level, add it to the bundle
-      if compileStep? and fallback_language of project_lang_files_dir_map
-        fallback_language_file = project_lang_files_dir_map[fallback_language]
-
-        try
-          lang_json = JSON.parse(fs.readFileSync(fallback_language_file))
-        catch error
-          throw new Meteor.Error 500, "Project fallback language file (#{fallback_language}) has an invalid JSON: `#{fallback_language_file}'",
-            {file_path: fallback_language_file, error: error}
-
-        if not _.isObject lang_json
-          throw new Meteor.Error 500, "Project fallback language file (#{fallback_language}) should contain a JSON object: `#{fallback_language_file}'",
-            {file_path: fallback_language_file}
-
-        project_fallback_lang_translation_js_file =
-          """
-          // add the project translations for the fallback language
-          TAPi18next.addResourceBundle('#{fallback_language}', '#{globals.project_translations_domain}', #{JSON.stringify lang_json});
-
-          """
-
-        compileStep.addJavaScript
-          path: "project-fallback-lang-translations.js",
-          sourcePath: compileStep.inputPath,
-          data: project_fallback_lang_translation_js_file,
-          bare: false
-
   unified_languages_files = {}

   _.each packageTapI18nMaps, (package_map) ->
@@ -311,7 +244,6 @@

     # Make sure package has a translation file for the fallback language
     if not (fallback_language of languages_files)
-      rollback()
       throw new Meteor.Error 500, "Package #{package_map.name} has no language file for the fallback language (#{fallback_language})"

     # Make sure we have the base language translations file for every dialect
@@ -320,7 +252,6 @@
     _.each dialects, (dialect) ->
       base_language = (dialect.split "-")[0]
       if not (base_language of languages_files)
-        rollback()
         throw new Meteor.Error 500, "Package #{package_map.name} has no language file for the base language (#{base_language}) of the dialect (#{dialect})"

     if supported_languages
@@ -338,14 +269,10 @@
       try
         lang_json = JSON.parse(fs.readFileSync(file_path))
       catch error
-        rollback()
-
         throw new Meteor.Error 500, "Failed to build unified languages files. Invalid JSON in language file: `#{file_path}' of package #{package_map.name}",
           {file_path: file_path, error: error}

       if not _.isObject lang_json
-        rollback()
-
         throw new Meteor.Error 500, "Failed to build unified languages files. The JSON in language file: `#{file_path}' of package #{package_map.name} is not an object.",
           {file_path: file_path}

@@ -359,9 +286,62 @@
       unified_languages_files[lang] += JSON.stringify lang_json

   for lang of unified_languages_files
+    unified_languages_files[lang] += "}"
+
+  # Add empty JSONs for supported languages we find no translation files for
+  unified_languages_files = _.extend(
+    _.object(_.map(supported_languages, (lang) -> [lang, "{}"])),
+    unified_languages_files
+  )
+
+  log "Done generating unified languages files"
+  return unified_languages_files
+
+addUnifiedFilesAsFsFiles = (unified_languages_files, lang_files_path=default_build_files_path) ->
+  log "Writing unified files directory to FS: #{lang_files_path}"
+
+  lang_files_path = removeFileTrailingSeparator lang_files_path
+  lang_files_backup_path = "#{lang_files_path}~"
+
+  getLangFilePath = (lang) ->
+    lang_files_path + path.sep + lang + ".json"
+
+  # A rollback procedure to use on failure
+  rollback = ->
+    log "Build failed, rolling back `#{lang_files_path}'"
+    wrench.rmdirSyncRecursive lang_files_path
+    try
+      fs.renameSync lang_files_backup_path, lang_files_path
+    catch error
+
+  # Remove old backup
+  try
+    wrench.rmdirSyncRecursive lang_files_backup_path
+    log "Old languages files backup #{lang_files_backup_path} removed"
+  catch error
+
+  # Create a backup for current lang_files_path
+  try
+    fs.renameSync lang_files_path, lang_files_backup_path
+    log "[IMPORTANT] unified languages files folder #{lang_files_path} already exists. Backing it up"
+    log "[IMPORTANT] to #{lang_files_backup_path}. If you need to, save the backup before building your"
+    log "[IMPORTANT] project again - otherwise you'll lose it."
+  catch error
+
+  # Create the new languages files dir
+  try
+    wrench.mkdirSyncRecursive lang_files_path, 0o744 # 0744 - owner: rwx, rest: r
+  catch error
+    rollback()
+
+    throw new Meteor.Error 500, "Can't create folder `#{lang_files_path}'",
+      {error: error}
+
+  for lang of unified_languages_files
+    if unified_languages_files[lang] == "{}"
+      continue
+
     lang_file_path = getLangFilePath lang
-
-    unified_languages_files[lang] += "}"

     try
       fs.writeFileSync lang_file_path, unified_languages_files[lang], {mode: 0o644}
@@ -371,52 +351,32 @@
       throw new Meteor.Error 500, "Failed to build unified languages files. Failed to create a file: #{lang_file_path}",
         {lang_file_path: lang_file_path, error: error}

-  # Map the unified languages files
-  has_unified_languages_files = _.extend(
-    _.object(_.map(supported_languages, (lang) -> [lang, false])),
-    _.object(_.map(unified_languages_files, (content, lang) -> [lang, true]))
-  )
-
-  log "Done building unified languages files"
-
-  return has_unified_languages_files
-
 build_files_once_log = {}
 build_files_once_arch_log = {}
 projectTapI18n = null
+unified_languages_files = {}
 buildFilesOnce = (compileStep) ->
-  # Builds the unified languages files and the project configuration (for each
-  # arch) once per build cycle
-
-  # To tell whether or not we are in a new build cycle we assume that if the
-  # same file triggered a call to that function for the same architecture we
-  # are in a new cycle
-  current_step_file = "#{compileStep._fullInputPath}::#{compileStep.arch}"
-
-  # Once per build cycle - regardless of arch
-  #
-  # If the build_files_once_log is empty or if the current_step_file is already
-  # in the log - we are in a new build cycle
-  if _.isEmpty(build_files_once_log) or (current_step_file of build_files_once_log)
-    # Init logs
-    build_files_once_log = {}
-    build_files_once_arch_log = {}
-
+  # Builds the unified languages files and the project configuration once
+  # per build cycle
+
+  oncePerCycle = () ->
     # Reload the project configuration
     projectTapI18n = loadProjectConf()

-    # Build the unified languages files only if tap-i18n is enabled in the
-    # project level
+    # Generate and build the unified languages files only
+    # if tap-i18n is enabled in the project level
     if projectTapI18n?
-      langs_with_unified_lang_files =
-        buildUnifiedLangFiles compileStep, projectTapI18n.build_files_path, projectTapI18n.supported_languages, projectTapI18n.languages_files_dir
+      unified_languages_files =
+        getUnifiedLangFiles projectTapI18n.supported_languages, projectTapI18n.languages_files_dir
+
+      addUnifiedFilesAsFsFiles unified_languages_files, projectTapI18n.build_files_path

       # If the supported languages for that project haven't been specified - all
       # the languages we have a unified language file for (and the fallback
       # language) are supported
-      projectTapI18n.supported_languages ?= _.union([fallback_language], _.keys langs_with_unified_lang_files)
-
-      projectTapI18n.unified_lang_files_map = langs_with_unified_lang_files
+      projectTapI18n.supported_languages ?= _.union([fallback_language], _.keys unified_languages_files)
+
+      projectTapI18n.unified_lang_files_map = _.object _.map(unified_languages_files, (content, lang) -> [lang, if content != "{}" then true else false])

       # Map supported language tags with respective titles in english and native
       projectTapI18n.language_names = {}
@@ -432,12 +392,10 @@
           lang_obj.name = language_names[tag_name][1]

         projectTapI18n.language_names[tag_name] = lang_obj
-
     else
       log "tap-i18n is not enabled in the project level, don't build unified languages files"

-  # Once per ARCH per build cycle
-  if not (compileStep.arch of build_files_once_arch_log)
+  oncePerCyclePerArch = (arch) ->
     if projectTapI18n?
       # If tap-i18n is enabled, add the project configurations to the TAPi18n
       # object if we haven't done that for the current arch already. (remember:
@@ -454,7 +412,66 @@
         data: project_i18n_js_file,
         bare: false

+      # For the browser arch add the base language file translation of the project
+      # to the bundle (if tap-i18n is enabled in the project level and the file exists)
+      if arch == "browser"
+        project_translations_dir = projectTapI18n.languages_files_dir
+
+        if project_translations_dir?
+          if not fs.existsSync project_translations_dir
+            log "Couldn't find project translations directory - no project level translations"
+          else
+            project_lang_files_dir_map = mapLangFilesDir project_translations_dir
+            if project_translations_dir?
+              if fs.existsSync project_translations_dir
+                # If the base language was translated in the project level, add it to the bundle
+                if fallback_language of project_lang_files_dir_map
+                  fallback_language_file = project_lang_files_dir_map[fallback_language]
+
+                  try
+                    lang_json = JSON.parse(fs.readFileSync(fallback_language_file))
+                  catch error
+                    throw new Meteor.Error 500, "Project fallback language file (#{fallback_language}) has an invalid JSON: `#{fallback_language_file}'",
+                      {file_path: fallback_language_file, error: error}
+
+                  if not _.isObject lang_json
+                    throw new Meteor.Error 500, "Project fallback language file (#{fallback_language}) should contain a JSON object: `#{fallback_language_file}'",
+                      {file_path: fallback_language_file}
+
+                  project_fallback_lang_translation_js_file =
+                    """
+                    // add the project translations for the fallback language
+                    TAPi18next.addResourceBundle('#{fallback_language}', '#{globals.project_translations_domain}', #{JSON.stringify lang_json});
+
+                    """
+
+                  compileStep.addJavaScript
+                    path: "project-fallback-lang-translations.js",
+                    sourcePath: compileStep.inputPath,
+                    data: project_fallback_lang_translation_js_file,
+                    bare: false
+
+  # To tell whether or not we are in a new build cycle we assume that if the
+  # same file triggered a call to that function for the same architecture we
+  # are in a new cycle
+  current_step_file = "#{compileStep._fullInputPath}::#{compileStep.arch}"
+
+  # Once per build cycle - regardless of arch
+  #
+  # If the build_files_once_log is empty or if the current_step_file is already
+  # in the log - we are in a new build cycle
+  if _.isEmpty(build_files_once_log) or (current_step_file of build_files_once_log)
+    # Init logs
+    build_files_once_log = {}
+    build_files_once_arch_log = {}
+
+    oncePerCycle()
+
+  # Once per ARCH per build cycle
+  if not (compileStep.arch of build_files_once_arch_log)
     build_files_once_arch_log[compileStep.arch] = true
+
+    oncePerCyclePerArch(compileStep.arch)

   # Same build cycle - log file
   build_files_once_log[current_step_file] = true


map chooser - interrupt previous request if one is still present

--- app/assets/javascripts/_open_street_map.coffee
+++ app/assets/javascripts/_open_street_map.coffee
@@ -66,7 +66,10 @@

   fetch_data: (query, handler) ->
-    $.ajax(
+    if @fetch_request
+      @fetch_request.cancel()
+
+    @fetch_request = $.ajax(
       url: "/api/circles.json",
       data: { location: query }
     ).done(handler)


Fixed adding/changing notes.

Fixed adding/changing notes.

--- app/assets/javascripts/app/models/macro.coffee
+++ app/assets/javascripts/app/models/macro.coffee
@@ -1,5 +1,5 @@
 class App.Macro extends App.Model
-  @configure 'Macro', 'name', 'perform', 'active'
+  @configure 'Macro', 'name', 'perform', 'note', 'active'
   @extend Spine.Model.Ajax
   @url: @apiPath + '/macros'
   @configure_attributes = [


[ui] ignore meta key in form inputs

[ui] ignore meta key in form inputs

--- app/assets/javascripts/helpers/forms.js.coffee
+++ app/assets/javascripts/helpers/forms.js.coffee
@@ -8,8 +8,6 @@
   el = $(el)
   if el.length
     el = $(el[0])
-  else
-    el = $(el)

   type = el.prop("type")
   if type == "checkbox" || type == "radio"
@@ -83,7 +81,7 @@
 # @param [Event] e             keypress event
 _.wait_valid = (e) ->
   # skip if not a printable char, allowing backspace and delete (8 and 46)
-  return if (e.which != 8 && e.which != 46) && (e.which < 32 || e.key.length > 1)
+  return if (e.which != 8 && e.which != 46) && (e.which < 32 || e.key.length > 1 || e.metaKey)

   el = $(e.target)
   [feedback, valid_div, icon_span] = _.valid_els(el)


Not use pop on routes page-title view

Not use pop on routes page-title view

--- app/assets/javascripts/views/page-title.coffee
+++ app/assets/javascripts/views/page-title.coffee
@@ -19,7 +19,7 @@
       appTitle = @appTitle(routes)
       content.pushObject(appTitle) if appTitle

-      currentRoute = routes.get('router.currentHandlerInfos').pop()
+      currentRoute = routes.get('router.currentHandlerInfos').slice(-1)[0]

       if currentRoute.handler.get('title')
         content.pushObject(currentRoute.handler.get('title'))


Add saveNewValue stashed code

Add saveNewValue stashed code

--- app/coffee/modules/admin/project-values.coffee
+++ app/coffee/modules/admin/project-values.coffee
@@ -415,8 +415,9 @@
             promise = $repo.create(valueType, $scope.newValue)
             promise.then (data) ->
                 target.addClass("hidden")
-                data.days_to_due_abs = data.days_to_due
-                data.sign = 1
+                data.sign = $scope.newValue.sign
+                data.days_to_due_abs = $scope.newValue.days_to_due_abs
+
                 $scope.values.push(data)

                 initializeNewValue()


Add DAR to list of projects

Add DAR to list of projects

--- scripts/pivotal-listener.coffee
+++ scripts/pivotal-listener.coffee
@@ -40,7 +40,8 @@
         "TechDebt": "TD-",
         "SAT": "SAT-",
         "Salesforce": "SF-",
-        "CCK12 Design": "CCK12D-"
+        "CCK12 Design": "CCK12D-",
+        "Data Architecture Revamp": "DAR-"

       project =
         projectId: reqBody["project"]["id"]


Don't wait server response when updating flags

--- client/app/actions/message_action_creator.coffee
+++ client/app/actions/message_action_creator.coffee
@@ -107,13 +107,23 @@
     updateFlag: (message, flags, callback) ->
         msg = message.toJSON()
         patches = jsonpatch.compare {flags: msg.flags}, {flags}
-        XHRUtils.messagePatch message.get('id'), patches, (error, message) ->
+        XHRUtils.messagePatch message.get('id'), patches, (error, messageUpdated) ->
             if not error?
-                AppDispatcher.handleViewAction
-                    type: ActionTypes.RECEIVE_RAW_MESSAGE
-                    value: message
+                if not _.isEqual(flags, messageUpdated.flags)
+                    AppDispatcher.handleViewAction
+                        type: ActionTypes.RECEIVE_RAW_MESSAGE
+                        value: messageUpdated
             if callback?
                 callback error
+
+        # dont wait for server response to display update
+        setTimeout ->
+            messageUpdated = message.toJS()
+            messageUpdated.flags = flags
+            AppDispatcher.handleViewAction
+                type: ActionTypes.RECEIVE_RAW_MESSAGE
+                value: messageUpdated
+        , 0

     setCurrent: (messageID) ->
         AppDispatcher.handleViewAction


IDE: Code cleanup.

IDE: Code cleanup.

--- client/ide/views/modals/machinestatemodal.coffee
+++ client/ide/views/modals/machinestatemodal.coffee
@@ -35,7 +35,6 @@
       @updateStatus { status: Unknown }

     @show()
-    # @getOptions().container.setClass 'blurred'

   updateStatus: (event) ->
@@ -43,25 +42,20 @@
     {status, percentage} = event

     if status is @state
-
       if percentage?
-
         @progressBar?.updateBar Math.max percentage, 10
         @progressBar?.show()

     else
-
       @state = status

       if percentage? and percentage is 100
-
         @progressBar?.updateBar 100
         @progressBar?.show()

         KD.utils.wait 500, @bound 'buildViews'

       else
-
         @buildViews()

       @prepareIDE()  if status is Running
@@ -82,6 +76,7 @@
         .catch => @buildViews()
     else
       @buildViews()
+

   buildViews: (response)->

@@ -210,7 +205,6 @@

   startIDE: ->
     @destroy()
-    # @getOptions().container.unsetClass 'blurred'

   prepareIDE: ->