Client: Activity: Renamed emailForm to userProfileForm and updated share location field by user is in team context or not

--- client/account/lib/views/accounteditusername.coffee
+++ client/account/lib/views/accounteditusername.coffee
@@ -8,6 +8,7 @@
 remote = require('app/remote').getInstance()
 s3upload = require 'app/util/s3upload'
 whoami = require 'app/util/whoami'
+isKoding = require 'app/util/iskoding'
 showError = require 'app/util/showError'
 JView = require 'app/jview'
 AvatarStaticView = require 'app/commonviews/avatarviews/avatarstaticview'
@@ -58,72 +59,78 @@
       callback       : =>
         @account.modify "profile.avatar": ""

-    @emailForm = new KDFormViewWithFields
+    @userProfileFormFields =
+      firstName          :
+        cssClass         : 'Formline--half'
+        placeholder      : "firstname"
+        name             : "firstName"
+        label            : 'Name'
+      lastName           :
+        cssClass         : 'Formline--half'
+        placeholder      : "lastname"
+        name             : "lastName"
+        label            : 'Last name'
+      email              :
+        cssClass         : 'Formline--half'
+        placeholder      : "you@yourdomain.com"
+        name             : "email"
+        testPath         : "account-email-input"
+        label            : 'Email'
+      username           :
+        cssClass         : 'Formline--half'
+        placeholder      : "username"
+        name             : "username"
+        label            : 'Username'
+        attributes       :
+          readonly       : "#{not /^guest-/.test @account.profile.nickname}"
+        testPath         : "account-username-input"
+      verifyEmail        :
+        itemClass        : KDCustomHTMLView
+        tagName          : "a"
+        partial          : "You didn't verify your email yet Verify now"
+        cssClass         : "hidden action-link verify-email"
+        testPath         : "account-email-edit"
+        click            : @bound 'verifyUserEmail'
+      passwordHeader     :
+        itemClass        : KDCustomHTMLView
+        partial          : 'CHANGE PASSWORD'
+        cssClass         : 'AppModal-sectionHeader'
+      password           :
+        cssClass         : 'Formline--half'
+        placeholder      : "password"
+        name             : "password"
+        type             : "password"
+        label            : 'Password'
+      confirm            :
+        cssClass         : 'Formline--half'
+        placeholder      : "confirm password"
+        name             : "confirmPassword"
+        type             : "password"
+        label            : 'Password (again)'
+
+    if isKoding()
+
+      @userProfileFormFields.locationHeader =
+        itemClass        : KDCustomHTMLView
+        partial          : 'LOCATION SERVICES'
+        cssClass         : 'AppModal-sectionHeader'
+
+      @userProfileFormFields.shareLocationLabel =
+        itemClass        : KDCustomHTMLView
+        partial          : 'Share my location when I post on a #channel'
+        tagName          : 'ul'
+        cssClass         : 'AppModal--account-switchList left-aligned'
+        name             : 'shareLocationLabel'
+        nextElement      :
+          shareLocation      :
+            defaultValue     : whoami().shareLocation
+            itemClass        : KodingSwitch
+            #cssClass         : 'AppModal--account-switchList'
+            name             : 'shareLocation'
+
+    @userProfileForm = new KDFormViewWithFields
       cssClass             : 'AppModal-form'
-      fields               :
-        firstName          :
-          cssClass         : 'Formline--half'
-          placeholder      : "firstname"
-          name             : "firstName"
-          label            : 'Name'
-        lastName           :
-          cssClass         : 'Formline--half'
-          placeholder      : "lastname"
-          name             : "lastName"
-          label            : 'Last name'
-        email              :
-          cssClass         : 'Formline--half'
-          placeholder      : "you@yourdomain.com"
-          name             : "email"
-          testPath         : "account-email-input"
-          label            : 'Email'
-        username           :
-          cssClass         : 'Formline--half'
-          placeholder      : "username"
-          name             : "username"
-          label            : 'Username'
-          attributes       :
-            readonly       : "#{not /^guest-/.test @account.profile.nickname}"
-          testPath         : "account-username-input"
-        verifyEmail        :
-          itemClass        : KDCustomHTMLView
-          tagName          : "a"
-          partial          : "You didn't verify your email yet Verify now"
-          cssClass         : "hidden action-link verify-email"
-          testPath         : "account-email-edit"
-          click            : @bound 'verifyUserEmail'
-        passwordHeader     :
-          itemClass        : KDCustomHTMLView
-          partial          : 'CHANGE PASSWORD'
-          cssClass         : 'AppModal-sectionHeader'
-        password           :
-          cssClass         : 'Formline--half'
-          placeholder      : "password"
-          name             : "password"
-          type             : "password"
-          label            : 'Password'
-        confirm            :
-          cssClass         : 'Formline--half'
-          placeholder      : "confirm password"
-          name             : "confirmPassword"
-          type             : "password"
-          label            : 'Password (again)'
-        locationHeader     :
-          itemClass        : KDCustomHTMLView
-          partial          : 'LOCATION SERVICES'
-          cssClass         : 'AppModal-sectionHeader'
-        shareLocationLabel :
-          itemClass        : KDCustomHTMLView
-          partial          : 'Share my location when I post on a #channel'
-          tagName          : 'ul'
-          cssClass         : 'AppModal--account-switchList left-aligned'
-          name             : 'shareLocationLabel'
-          nextElement      :
-            shareLocation      :
-              defaultValue     : whoami().shareLocation
-              itemClass        : KodingSwitch
-              #cssClass         : 'AppModal--account-switchList'
-              name             : 'shareLocation'
+      fields               : @userProfileFormFields
       buttons              :
         Save               :
           title            : 'Save Changes'
@@ -249,8 +256,8 @@
               profileUpdated = false
               return queue.next()
             JUser.changePassword password, (err,docs)=>
-              @emailForm.inputs.password.setValue ""
-              @emailForm.inputs.confirm.setValue ""
+              @userProfileForm.inputs.password.setValue ""
+              @userProfileForm.inputs.confirm.setValue ""
               if err
                 return queue.next()  if err.message is "PasswordIsSame"
                 return notify err.message
@@ -274,8 +281,8 @@

     remote.api.JUser.verifyByPin resendIfExists: yes, (err) =>

-      @emailForm.fields.verifyEmail.hide()
-      @emailForm.inputs.verifyEmail.hide()
+      @userProfileForm.fields.verifyEmail.hide()
+      @userProfileForm.inputs.verifyEmail.hide()
       return showError err if err

       notify "We've sent you a confirmation mail.", 3500
@@ -325,14 +332,16 @@
     {email} = @userInfo
     {nickname, firstName, lastName} = @account.profile

-    @emailForm.inputs.email.setDefaultValue Encoder.htmlDecode email
-    @emailForm.inputs.username.setDefaultValue Encoder.htmlDecode nickname
-    @emailForm.inputs.firstName.setDefaultValue Encoder.htmlDecode firstName
-    @emailForm.inputs.lastName.setDefaultValue Encoder.htmlDecode lastName
-    @emailForm.inputs.shareLocation.setDefaultValue whoami().shareLocation
+    @userProfileForm.inputs.email.setDefaultValue Encoder.htmlDecode email
+    @userProfileForm.inputs.username.setDefaultValue Encoder.htmlDecode nickname
+    @userProfileForm.inputs.firstName.setDefaultValue Encoder.htmlDecode firstName
+    @userProfileForm.inputs.lastName.setDefaultValue Encoder.htmlDecode lastName
+
+    if isKoding()
+      @userProfileForm.inputs.shareLocation.setDefaultValue whoami().shareLocation

     {focus} = kd.utils.parseQuery()
-    @emailForm.inputs[focus]?.setFocus()  if focus
+    @userProfileForm.inputs[focus]?.setFocus()  if focus

     notify = (message)->
       new KDNotificationView
@@ -340,8 +349,8 @@
         duration : 3500

     if @userInfo.status is "unconfirmed"
-      @emailForm.fields.verifyEmail.show()
-      @emailForm.inputs.verifyEmail.show()
+      @userProfileForm.fields.verifyEmail.show()
+      @userProfileForm.inputs.verifyEmail.show()

   getAvatarOptions: ->
     tagName       : 'figure'
@@ -351,7 +360,7 @@
       height      : 95

-  hideSaveButtonLoader: -> @emailForm.buttons.Save.hideLoader()
+  hideSaveButtonLoader: -> @userProfileForm.buttons.Save.hideLoader()

   pistachio: ->
@@ -364,7 +373,7 @@
         {{> @useGravatarBtn}}

-    {{> @emailForm}}
+    {{> @userProfileForm}}
     """


add coment

add coment

--- client/app/lib/components/contentModal/index.coffee
+++ client/app/lib/components/contentModal/index.coffee
@@ -26,6 +26,7 @@
     @createBody()
     @createFooter()

+  # commented function in kd.ModalView class
   keyup: (e) ->
     @cancel() if e.which is 27


EnvironmentsModal: Change modal title.

EnvironmentsModal: Change modal title.

--- client/app/lib/environment/environmentsmodal.coffee
+++ client/app/lib/environment/environmentsmodal.coffee
@@ -11,14 +11,14 @@
   constructor: (options = {}, data) ->

     options.cssClass = kd.utils.curry 'environments-modal', options.cssClass
+    options.title    = 'Your Machines'
     options.width    = 742
-    options.title    = 'Your VMs'
     options.overlay  = yes

     super options, data

-    listView   = new EnvironmentList
-    controller = new EnvironmentListController
+    listView     = new EnvironmentList
+    controller   = new EnvironmentListController
       view       : listView
       wrapper    : no
       scrollView : no


:lipstick: Preserve progress bar on reopen

--- lib/conflict-marker.coffee
+++ lib/conflict-marker.coffee
@@ -45,7 +45,7 @@
     else
       atom.emit 'merge-conflicts:resolved',
         file: @editor().getPath(),
-        total: 0, resolved: 0,
+        total: 1, resolved: 1,
         source: this
       @conflictsResolved()


updating readme

updating readme

--- src/toaster/parser.coffee
+++ src/toaster/parser.coffee
@@ -22,18 +22,18 @@
 		# usage += "  toaster -nc myawsomeapp\n"
 		# usage += "  toaster -nskc myawsomeapp"

-		adendo = "" #"use w/ [-s]"
-		# adendo = "use w/ [-s, -k, -c]"
+		adendo = "" #", use w/ [-s]"
+		# adendo = ", use w/ [-s, -k, -c]"

 		@argv = (@opts = optimist.usage( usage )
     		.alias('n', 'new')
-			.describe('n', "Scaffold a very basic new App, #{adendo}")
+			.describe('n', "Scaffold a very basic new App#{adendo}")

 			.alias('i', 'init')
-			.describe('i', "Create a config (toaster.coffee) file, #{adendo}")
+			.describe('i', "Create a config (toaster.coffee) file#{adendo}")

 			.alias('w', 'watch')
-			.describe('w', "Start watching/compiling your project, #{adendo}")
+			.describe('w', "Start watching/compiling your project#{adendo}")

 			.alias('c', 'compile')
 			.boolean( 'c' )


Modernize ref

Modernize ref

--- resources/assets/coffee/react/profile-page/main.coffee
+++ resources/assets/coffee/react/profile-page/main.coffee
@@ -68,14 +68,14 @@
     $.subscribe 'stickyHeader.profilePage', @_tabsStick
     $(window).on 'throttled-scroll.profilePage', @pageScan

-    $(@refs.pages).sortable
+    $(@pages).sortable
       cursor: 'move'
       handle: '.js-profile-page-extra--sortable-handle'
       revert: 150
       scrollSpeed: 10
       update: @updateOrder

-    $(@refs.tabs).sortable
+    $(@tabs).sortable
       items: '[data-page-id]'
       tolerance: 'pointer'
       cursor: 'move'
@@ -96,8 +96,8 @@
     $.unsubscribe '.profilePage'
     $(window).off '.profilePage'

-    for sortable in ['pages', 'tabs']
-      $(@refs[sortable]).sortable 'destroy'
+    for sortable in [@pages, @tabs]
+      $(sortable).sortable 'destroy'

     document.body.dataset.profilePageState = JSON.stringify(@state)

@@ -175,7 +175,7 @@

       div
         className: "hidden-xs page-extra-tabs #{'page-extra-tabs--floating' if @state.tabsSticky}"
-        ref: 'tabs'
+        ref: (el) => @tabs = el

         div
           className: 'js-sticky-header'
@@ -204,7 +204,9 @@

       div
         className: 'osu-layout__section osu-layout__section--extra'
-        div className: 'osu-layout__row', ref: 'pages',
+        div
+          className: 'osu-layout__row'
+          ref: (el) => @pages = el
           for name in @state.profileOrder
             @extraPage name, extraPageParams[name]


That was a nice try

That was a nice try

--- resources/assets/coffee/react/profile-page/main.coffee
+++ resources/assets/coffee/react/profile-page/main.coffee
@@ -76,11 +76,11 @@

     withMePage = @props.userPage.html != '' || @props.withEdit

-    profileOrder = @props.user.profileOrder.map (m) ->
-      if m is not 'me'
-        return m
-      else if withMePage and m is 'me'
-        return m
+    profileOrder = _.filter @props.user.profileOrder, (p) =>
+      if p == 'me'
+        withMePage
+      else
+        true

     div className: 'osu-layout__section',
       el ProfilePage.Header,


use filename for stacktrace

use filename for stacktrace

--- src/svg.coffee
+++ src/svg.coffee
@@ -6,7 +6,7 @@
     constructor: () ->
         filename = require.resolve('../../node_modules/raphael/raphael')
         code = fs.readFileSync(filename)
-        @_script = vm.createScript(code, 'raphael.vm')
+        @_script = vm.createScript(code, filename)

     _raphael: (win, doc, nav) ->
         ctx =


Indicate which fields are incorrect

Indicate which fields are incorrect

--- resources/static/brunch/src/app/views/home_view.coffee
+++ resources/static/brunch/src/app/views/home_view.coffee
@@ -20,14 +20,20 @@
   checkRules: ->
     callback = (data) ->
       f = (x, xs) -> x && xs
-      r = _.foldr data, f, true
-      if r
+      if _.foldr data, f, true
         $("#dialog").html("That's correct!")
         $("#dialog").dialog
           title: "That's correct!",
           modal: true
           buttons:
             Ok: => $("#dialog").dialog("close")
+      else
+        $('#rules-tree-div input[type="text"]').each(
+          -> if data.shift()
+               $(this).css "background-color", "#afa"
+             else
+               $(this).css "background-color", "#faa"
+        )

     $.ajax
       url:  '/rules/check'


Better formatting for the search results summary

--- app/assets/javascripts/components/search/results.js.jsx.coffee
+++ app/assets/javascripts/components/search/results.js.jsx.coffee
@@ -5,6 +5,9 @@

   render: ->
     message =  (@props.results.map (group)-> `<span>{group.pagination.total_items} <GenericLink link={{url: 'javascript:void(0)', onclick: this.scrollTo, text: group.header, className: ''}} /></span>`)
+    if @props.results.length > 1
+      for i in [(@props.results.length-1)..1] by -1
+        message.splice(i, 0, `<span>, </span>`)
     all_results = @props.results.map (group)-> `<SearchResultGroup group={group} key={group.type} />`
     return `(
       <div id='offering_list'>


Only spacing

Only spacing

--- app/assets/javascripts/javascript_renderer/helpers/date.coffee
+++ app/assets/javascripts/javascript_renderer/helpers/date.coffee
@@ -8,21 +8,21 @@
      if withSeconds
        distance_in_seconds = Math.abs((to_time - from_time) / 1000)
        switch
-         when distance_in_seconds < 5  then ['less_than_x_seconds', { count: 5  }]
-         when distance_in_seconds < 10 then ['less_than_x_seconds', { count: 10 }]
-         when distance_in_seconds < 20 then ['less_than_x_seconds', { count: 20 }]
-         when distance_in_seconds < 40 then ['half_a_minute',       {}           ]
-         when distance_in_seconds < 60 then ['less_than_x_minutes', { count: 1  }]
+         when distance_in_seconds < 5  then [ 'less_than_x_seconds', { count: 5  } ]
+         when distance_in_seconds < 10 then [ 'less_than_x_seconds', { count: 10 } ]
+         when distance_in_seconds < 20 then [ 'less_than_x_seconds', { count: 20 } ]
+         when distance_in_seconds < 40 then [ 'half_a_minute',       {           } ]
+         when distance_in_seconds < 60 then [ 'less_than_x_minutes', { count: 1  } ]
          else ['x_minutes', { count: 1 }]
      else
        ['less_than_x_minutes', { count: 1 }]
-    when distance_in_minutes < 45     then ['x_minutes',      { count: Math.floor(distance_in_minutes)           }]
-    when distance_in_minutes < 90     then ['about_x_hours',  { count: 1                                         }]
-    when distance_in_minutes < 1440   then ['about_x_hours',  { count: Math.floor(distance_in_minutes / 60.0)    }]
-    when distance_in_minutes < 2520   then ['x_days',         { count: 1                                         }]
-    when distance_in_minutes < 43200  then ['x_days',         { count: Math.floor(distance_in_minutes / 1440.0)  }]
-    when distance_in_minutes < 86400  then ['about_x_months', { count: Math.floor(distance_in_minutes / 43200.0) }]
-    when distance_in_minutes < 525600 then ['x_months',       { count: Math.floor(distance_in_minutes / 43200.0) }]
+    when distance_in_minutes < 45     then [ 'x_minutes',      { count: Math.floor(distance_in_minutes)           } ]
+    when distance_in_minutes < 90     then [ 'about_x_hours',  { count: 1                                         } ]
+    when distance_in_minutes < 1440   then [ 'about_x_hours',  { count: Math.floor(distance_in_minutes / 60.0)    } ]
+    when distance_in_minutes < 2520   then [ 'x_days',         { count: 1                                         } ]
+    when distance_in_minutes < 43200  then [ 'x_days',         { count: Math.floor(distance_in_minutes / 1440.0)  } ]
+    when distance_in_minutes < 86400  then [ 'about_x_months', { count: Math.floor(distance_in_minutes / 43200.0) } ]
+    when distance_in_minutes < 525600 then [ 'x_months',       { count: Math.floor(distance_in_minutes / 43200.0) } ]
     else
       remainder         = distance_in_minutes % 525600
       distance_in_years = Math.floor( distance_in_minutes / 525600 )


sort starred convs by name

sort starred convs by name

--- src/ui/models/conv.coffee
+++ src/ui/models/conv.coffee
@@ -332,7 +332,7 @@
         if sort
             starred = (c for c in convs when isStarred(c))
             convs = (c for c in convs when not isStarred(c))
-            starred.sort (e1, e2) -> sortby(e2) - sortby(e1)
+            starred.sort (e1, e2) -> e1.name.localeCompare(e2.name)
             convs.sort (e1, e2) -> sortby(e2) - sortby(e1)
             return starred.concat convs
         convs


add narrow-query OR(|) expression

add narrow-query OR(|) expression

--- lib/get-filter-spec-for-query.coffee
+++ lib/get-filter-spec-for-query.coffee
@@ -15,26 +15,37 @@
   segments.join('')

 getRegExpForWord = (word, {wildcard, sensitivity}={}) ->
-  if word.length > 1 # don't expand wildcard for sole `*`.
-    pattern = expandWildCard(word)
+  isIncludeUpperCase = /[A-Z]/.test(word)
+
+  if not word.startsWith('|') and not word.endsWith('|')
+    words = word.split('|')
   else
-    pattern = _.escapeRegExp(word)
+    words = [word]

-  # Translate
-  # - ">word<" to "\bword\b"
-  # - ">word" to "\bword"
-  # - "word<" to "word\b"
-  if /^>./.test(pattern)
-    pattern = pattern[1...]
-    pattern = "\\b" + pattern if /^\w/.test(pattern)
-  if /.<$/.test(pattern)
-    pattern = pattern[...-1]
-    pattern = pattern + "\\b" if /\w$/.test(pattern)
+  patterns = []
+  for word in words
+    if word.length > 1 # don't expand wildcard for sole `*`.
+      pattern = expandWildCard(word)
+    else
+      pattern = _.escapeRegExp(word)

-  if (sensitivity is 'sensitive') or (sensitivity is 'smartcase' and /[A-Z]/.test(word))
-    new RegExp(pattern)
-  else
-    new RegExp(pattern, 'i')
+    # Translate
+    # - ">word<" to "\bword\b"
+    # - ">word" to "\bword"
+    # - "word<" to "word\b"
+    if /^>./.test(pattern)
+      pattern = pattern[1...]
+      pattern = "\\b" + pattern if /^\w/.test(pattern)
+    if /.<$/.test(pattern)
+      pattern = pattern[...-1]
+      pattern = pattern + "\\b" if /\w$/.test(pattern)
+    patterns.push(pattern)
+
+  options = ''
+  if (sensitivity is 'sensitive') or (sensitivity is 'smartcase' and isIncludeUpperCase)
+    options += 'i'
+
+  new RegExp(patterns.join('|'), options)

 module.exports = (query, options={}) ->
   include = []


Tests: IDE: Folder: Added folder test to parallel-sets.

--- scripts/test-instance/parallel-sets.coffee
+++ scripts/test-instance/parallel-sets.coffee
@@ -53,6 +53,7 @@

   [
     'ide file'
+    'ide folder'
   ]

   [


Closing issue #709

Closing issue #709

--- admin/static/coffee/servers/index.coffee
+++ admin/static/coffee/servers/index.coffee
@@ -184,8 +184,6 @@
             max_traffic =
                 recv: 0
                 sent: 0
-
-

             num_machine_in_datacenter = 0
             all_machine_in_datacenter_ready = true


The REST resource moved to common.

The REST resource moved to common.

--- test/unit/rest.spec.coffee
+++ test/unit/rest.spec.coffee
@@ -1,4 +1,4 @@
-`import Rest from "src/rest.resource.coffee"`
+`import Rest from "src/common/rest.resource.coffee"`

 RestSpec =
   describe 'Unit Testing the REST Service', ->


test(macTime): Switched to use scope function instead of click event and fixed how invalid dates are tested

--- test/unit/time.spec.coffee
+++ test/unit/time.spec.coffee
@@ -46,7 +46,8 @@
       element          = $compile("<mac-time mac-time-model='model'></mac-time>") $rootScope
       $rootScope.$digest()

-      $("input", element).click()
+      $rootScope.$$childHead.clickEvent()
+      $rootScope.$digest()

       expect($rootScope.model).toBe "12:00 AM"

@@ -58,7 +59,8 @@
       $rootScope.model = ""
       $rootScope.$digest()

-      $("input", element).click()
+      $rootScope.$$childHead.clickEvent()
+      $rootScope.$digest()

       expect($rootScope.model).toBe "12:00 AM"

@@ -184,11 +186,15 @@
       $rootScope.$digest()

       input = $("input", element)
-      input.click()
+
+      $rootScope.$$childHead.clickEvent()
+      $rootScope.$digest()

       changeInputValue input, "14:41 AM"
-
-      expect(input.hasClass("ng-invalid")).toBeTruthy()
+      $rootScope.$$childHead.blurEvent()
+      $rootScope.$digest()
+
+      expect($rootScope.model).toBe("12:00 AM")

     it "should reset back to the original time when input is invalid - 2", ->
       $rootScope.model = ""
@@ -196,11 +202,15 @@
       $rootScope.$digest()

       input = $("input", element)
-      input.click()
+
+      $rootScope.$$childHead.clickEvent()
+      $rootScope.$digest()

       changeInputValue input, "123"
-
-      expect(input.hasClass("ng-invalid")).toBeTruthy()
+      $rootScope.$$childHead.blurEvent()
+      $rootScope.$digest()
+
+      expect($rootScope.model).toBe("12:00 AM")

   describe "model -> view", ->
     $compile   = null


moved into blueprint

moved into blueprint

--- api/controllers/MessageController.coffee
+++ api/controllers/MessageController.coffee
@@ -1,49 +1,3 @@
-## -- Dependencies -------------------------------------------------------------
-
-sailor     = require 'sailorjs'
-validator  = sailor.validator
-actionUtil = sailor.actionUtil
-translate  = sailor.translate
-errorify   = sailor.errorify
-
 ## -- Exports -------------------------------------------------------------

-module.exports =
-
-  sendMessage: (req, res) ->
-    from     = req.param 'from'
-    to       = req.param 'to'
-    text     = req.param 'text'
-
-    User.findOne(from).exec (err, user) ->
-      return res.badRequest(err)  if err
-
-      User.findOne(to).exec (err, friend) ->
-        return res.badRequest(err)  if err
-
-        unless user and friend
-          errors = []
-          errorify.addError(errors, 'from', translate.get("Model.NotFound")) unless user
-          errorify.addError(errors, 'to', translate.get("Model.NotFound")) unless friend
-          return res.notFound(errorify.serialize(errors))
-
-        message =
-          from: user.id
-          to: friend.id
-          text: text
-
-        Message.create(message).exec (err, newInstance) ->
-          return res.negotiate(err)  if err
-
-          # Use find method to return the model for the populate option
-          Message.findOne(newInstance.id).populateAll().exec (err, newInstance) ->
-
-            # If we have the pubsub hook, use the model class's publish method
-            # to notify all subscribers about the created item
-            if req._sails.hooks.pubsub
-              if req.isSocket
-                Message.subscribe req, newInstance
-                Message.introduce newInstance
-              Message.publishCreate newInstance, not req.options.mirror and req
-
-            res.created newInstance
+module.exports = {}


put colored cube

put colored cube

--- app/assets/javascripts/mythree.js.coffee
+++ app/assets/javascripts/mythree.js.coffee
@@ -41,15 +41,22 @@
   light = new THREE.DirectionalLight( 0xffffff, 1 );
   light

-#cube with wireframe
+#キューブ作成
 MYTHREE.createCube = (pos, color) ->
   console.log 'col'
   console.log color
   texture_path = "../assets/cube_texture.png"
-  material = new THREE.MeshLambertMaterial( { color: color, ambient: 0x00ff00, shading: THREE.FlatShading, map: THREE.ImageUtils.loadTexture( texture_path ) } )
-  #material = new THREE.MeshLambertMaterial()
-  material.ambient = material.color
-  material.ambient = 0xff0000
+  param =
+    wireframe: false
+    color: color
+    #ambient: color
+    shading: THREE.FlatShading
+    #map: THREE.ImageUtils.loadTexture( texture_path )
+  #material = new THREE.MeshLambertMaterial( param )
+  material = new THREE.MeshPhongMaterial( param )
+  #material.ambient = material.color
+  #material.ambient = 0xff0000
+  #material.color = 0xff0000
   geometry = new THREE.CubeGeometry(1, 1, 1)
   voxel = new THREE.Mesh(geometry, material)
   #ワイヤフレーム表示


Trying to make ajax cors working for ie

Trying to make ajax cors working for ie

--- app/assets/javascripts/ors_api.js.coffee
+++ app/assets/javascripts/ors_api.js.coffee
@@ -1,4 +1,5 @@
 $(document).on 'ready page:load', ->
+  $.support.cors = true;
   new Questionnaires($('.questionnaires-container'), $('.questionnaires'))

   if $('.questionnaire-info').length > 0


trying to fix iPhone js

trying to fix iPhone js

--- app/assets/javascripts/welcome.js.coffee
+++ app/assets/javascripts/welcome.js.coffee
@@ -1,10 +1,10 @@
 # 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/
+$ ->
+  if $('#verification_phone').val()?.length == 0
+    $('#verification_phone').val('+34')

-if $('#verification_phone').val()?.length == 0
-  $('#verification_phone').val('+34')
-
-$('#submit').click ->
-  $('#form').submit()
-  return false+  $('#submit').click ->
+    $('#form').submit()
+    return false


WIP: fix dropdown option keys

WIP: fix dropdown option keys

--- app/classifier/tasks/dropdown/index.cjsx
+++ app/classifier/tasks/dropdown/index.cjsx
@@ -92,6 +92,7 @@
     annotationValues = @props.annotation.value
     unless annotationValues.length
       @props.annotation.value = @props.task.selects.map -> {value: null, option: false}
+      @syncAnnotations()

     if @props.autoFocus is true
       @handleFocus()
@@ -108,11 +109,12 @@
     # clear selections, then check each annotation.value
     # and set the corresponding selected option for each select
     selectedOptions = []
-    optionsKeys = []
+    optionsKeys = {}
     @props.annotation.value.map (annotation, i) =>
       if annotation.option
+        select = @props.task.selects[i]
         [selected] = @getOptions(i, optionsKeys).filter (option) -> option.value is annotation.value
-        optionsKeys.push selected.value if selected?.value
+        optionsKeys[select.id] = selected.value if selected?.value
         selectedOptions[i] = selected
       else
         selectedOptions[i] = {label: annotation.value, value: annotation.value}
@@ -122,15 +124,19 @@
     @menus[0].focus()

   getOptions: (i, optionsKeys) ->
-    optionsKey = if optionsKeys.length then optionsKeys.join(';') else '*'
     select = @props.task.selects[i]
+    conditions = select.condition?.split ';'
+    conditions ?= []
+    optionsKey = conditions.map (condition) -> optionsKeys[condition]
+    optionsKey = if optionsKey.length then optionsKey.join(';') else '*'
     options = select.options[optionsKey]
     if options then options else []

   getDisabledAttribute: (i) ->
     {selects} = @props.task
     select = selects[i]
-    optionsKeys = (o.value for o in @state.selectedOptions.slice(0,i))
+    optionsKeys = {}
+    @state.selectedOptions.slice(0,i).map (option, j) => optionsKeys[@props.task.selects[j].id] = option.value if option?.value
     [condition] = selects.filter (filterSelect) => filterSelect.id is select.condition
     conditionIndex = selects.indexOf(condition)

@@ -150,7 +156,7 @@

   render: ->
     {selects} = @props.task
-    optionsKeys = []
+    optionsKeys = {}

     <GenericTask question={@props.task.instruction} help={@props.task.help} required={@props.task.required}>

@@ -159,7 +165,7 @@
           options.push option for option in @getOptions(i, optionsKeys)
           disabled = @getDisabledAttribute(i)
           selectedOption = if @state.selectedOptions[i]?.value then @state.selectedOptions[i] else null
-          optionsKeys.push selectedOption.value if selectedOption?.value
+          optionsKeys[select.id] = selectedOption.value if selectedOption?.value

             {if select.title isnt @props.task.instruction

{select.title}
}
@@ -196,7 +202,8 @@
     selectedOptions[i] = option
     value = @props.annotation.value

-    optionsKeys = (o.value for o in selectedOptions.slice(0,i))
+    optionsKeys = {}
+    selectedOptions.slice(0,i).map (option, j) => optionsKeys[@props.task.selects[j].id] = option.value if option?.value
     options = @getOptions(i, optionsKeys)
     newIndex = options?.indexOf(option)
     if newIndex is -1 or newIndex is undefined


Add me to the list? (#4595)

Add me to the list? (#4595)

Add AnitaOlsen to nb Diplomats

--- app/views/contribute/DiplomatView.coffee
+++ app/views/contribute/DiplomatView.coffee
@@ -82,7 +82,7 @@
     sl: []             # slovenščina, Slovene
     fi: []             # suomi, Finnish
     bg: []             # български език, Bulgarian
-    nb: ['bardeh', 'ebirkenes', 'matifol', 'mcclane654', 'mogsie', 'torehaug']             # Norsk Bokmål, Norwegian (Bokmål)
+    nb: ['bardeh', 'ebirkenes', 'matifol', 'mcclane654', 'mogsie', 'torehaug', 'AnitaOlsen']             # Norsk Bokmål, Norwegian (Bokmål)
     nn: ['Ayexa']             # Norsk Nynorsk, Norwegian (Nynorsk)
     he: ['OverProgram', 'monetita']             # עברית, Hebrew
     lt: []             # lietuvių kalba, Lithuanian


Remove WorkspaceView::indexOfPane

Remove WorkspaceView::indexOfPane

--- src/workspace-view.coffee
+++ src/workspace-view.coffee
@@ -267,10 +267,6 @@
   getPaneViews: ->
     @panes.getPanes()

-  # Public: Return the id of the given a {PaneView}
-  indexOfPane: (pane) ->
-    @panes.indexOfPane(pane)
-
   # Public: Fires a callback on each open {EditorView}.
   eachEditorView: (callback) ->
     callback(editor) for editor in @getEditorViews()


fix jQuery 1.9 compatibility issue

fix jQuery 1.9 compatibility issue

As per this discussion:
https://github.com/gregbell/active_admin/pull/1879#discussion_r3453478

--- app/assets/javascripts/active_admin/pages/application.js.coffee
+++ app/assets/javascripts/active_admin/pages/application.js.coffee
@@ -13,4 +13,4 @@

   # Filter form: don't send any inputs that are empty
   $('#q_search').submit ->
-    $(@).find(':input[value=""]').attr 'disabled', 'disabled'
+    $(@).find(':input').filter(-> @value is '').prop 'disabled', true


:fire: Remove some redundant methods

:fire: Remove some redundant methods

--- lib/linter.coffee
+++ lib/linter.coffee
@@ -2,6 +2,7 @@
 {CompositeDisposable, Emitter} = require 'atom'

 {LinterTrace, LinterMessage, LinterError, LinterWarning} = require './messages'
+EditorLinter = require './editor-linter'

 class Linter

@@ -16,14 +17,9 @@
     return ActiveEditor unless ActiveEditor
     return @Editors.get ActiveEditor

-  getEditorLinter:(Editor)->
+  getLinter:(Editor)->
     return @Editors.get Editor

-  observeEditorLinters:(Callback)->
-    @Emitter.on 'linters-observe', Callback
-
-  onDidAddEditorLinter:(Callback)->
-    @Emitter.on 'linter-add', Callback
-
-  onDidRemoveEditorLinter:(Callback)->
-    @Emitter.on 'linter-remove', Callback+  observeLinters:(Callback)->
+    Callback(Linter[1]) for Linter of @Editors
+    @Emitter.on 'linters-observe', Callback


added chroma.version

added chroma.version

--- src/api.coffee
+++ src/api.coffee
@@ -75,6 +75,7 @@
 chroma.luminance = (color) ->
     chroma(color).luminance()

+chroma.version = '@@version'

 # exposing raw classes for testing purposes


fixed search issue

fixed search issue

--- src/app.coffee
+++ src/app.coffee
@@ -16,7 +16,7 @@
   minZoom: 6
   maxZoom: 15

-app.geoserverUrl = "http://data.azgs.az.gov/arizona/azgs/ows"
+app.geoserverUrl = "http://data.azgs.az.gov/arizona-hazards/azgs/ows"

 # Setup data layers
 dataLayers = [
@@ -274,10 +274,10 @@
     new app.models.WmsLayer
       id: "floodPotential"
       layerName: "Flood Potential"
-      serviceUrl: "http://data.azgs.az.gov/arizona/azgs/wms"
+      serviceUrl: "http://data.azgs.az.gov/arizona-hazards/azgs/wms"
       serviceType: "WMS"
-      wfsUrl: "http://data.azgs.az.gov/arizona/azgs/ows"
-      typeName: "azgs:highflood_statewide"
+      wfsUrl: "http://data.azgs.az.gov/arizona-hazards/azgs/ows"
+      typeName: "azgs:floods"
       active: false
       citation: "Arizona Division of Emergency Management"
       details: '
This layer shows areas with potentially High and Medium Risk of flooding. Data are drawn from the Federal Emergency Management Agency (FEMA) digital flood insurance rate maps (DFIRM) database, dated May 2010. High flooding potential includes areas covered by all of the “A” Special Flood Hazard zones. These areas have a 1% annual chance of flooding, also known as the 100-year flood, and a 26% chance of flooding within the span of a 30-year mortgage. Medium flood potential includes  areas within the “Shaded X” zones. These are areas between the limits of the 100-year and 500-year flood zones.

The flood potential layer was created by JE Fuller/Hydrology and Geomorpholgy, Inc. for the Arizona Division of Emergency Management (ADEM), as part of a larger study for the 2010 State of Arizona Multi-Hazard Mitigation Plan. Data is current as of May 2010. These data are provided as guidance only. Local Flood Control Districts should be consulted for additional or more detailed information.
'
@@ -298,10 +298,6 @@
           caption: "High"
           imageInfo:
             png: "img/legend_imgs/png/fp_high.png"
-        ,
-          caption: "Medium"
-          imageInfo:
-            png: "img/legend_imgs/png/fp_low.png"
       ],
         legendHeading: "Flood Potential"
         heading: "Flood Potential"


Blink interval of 200ms was too slow to be seen - reverting to 400ms used in api.coffee

--- src/app.coffee
+++ src/app.coffee
@@ -17,10 +17,10 @@
 			if connectivityState
 				console.log('Waiting for connectivity...')
 				connectivityState = false
-			interval = setInterval(utils.blink,200)
-			Promise.delay(1000)
+			interval = setInterval(utils.blink,400)
+			Promise.delay(2000)
 			.then ->
-				# Clear the blinks after 1 second
+				# Clear the blinks after 2 second
 				clearInterval(interval)
 				ensureConnected(continuous)
 		else


Replace SearchBarView with TypeaheadView for artist autocompletion on /works-for-you

--- apps/notifications/client/sidebar.coffee
+++ apps/notifications/client/sidebar.coffee
@@ -1,7 +1,7 @@
 _ = require 'underscore'
 Backbone = require 'backbone'
 qs = require 'querystring'
-SearchBarView = require '../../../components/search_bar/view.coffee'
+TypeaheadView = require '../../../components/typeahead/view.coffee'
 filterArtistTemplate = -> require('../templates/filter_artist.jade') arguments...

 module.exports = class SidebarView extends Backbone.View
@@ -46,21 +46,19 @@
       initialLoad: false

   setupSearch: (options = {}) ->
-    @searchBarView = new SearchBarView
-      mode: 'artists'
-      el: @$('#notifications-search-container')
-      $input: @$searchInput ?= @$('#notifications-search')
+    @typeahead = new TypeaheadView
+      kind: 'artists'
       autoselect: true
-      displayKind: false

-    @listenTo @searchBarView, 'search:selected', @follow
+    @$('#notifications-search-container').html @typeahead.render().$el

-  follow: (e, model) ->
-    @searchBarView?.clear()
+    @listenTo @typeahead, 'selected', @follow
+
+  follow: (model) ->
     @following.follow model.get('id')
     @$('.notifications-artist-list').prepend filterArtistTemplate
       artist:
         id: model.get('id')
         name: model.get('name')
         published_artworks_count: model.get('published_artworks_count')
-    @$(".filter-artist[data-artist=#{model.get('id')}]").children('.filter-artist-name').click()+    @$(".filter-artist[data-artist=#{model.get('id')}]").children('.filter-artist-name').click()


temporary alert

temporary alert

--- app/assets/javascripts/angular/services/GradeSchemeElementsService.js.coffee
+++ app/assets/javascripts/angular/services/GradeSchemeElementsService.js.coffee
@@ -25,6 +25,9 @@
     update_scheme = (index) ->
       if(index != elements.length-1)
         elements[index+1].high_range = elements[index].low_range-1
+      if(elements[index].low_range > elements[index].high_range)
+        alert('Low Range is Higher Than High Range')
+        elements[index].low_range = ""

     getGradeSchemeElements = ()->
       $http.get('/gse_mass_edit/').success((response) ->


only try to show header balance is user is signed in

--- app/assets/javascripts/backbone/apps/header/show/header_controller.js.coffee
+++ app/assets/javascripts/backbone/apps/header/show/header_controller.js.coffee
@@ -6,7 +6,7 @@
         model: App.currentUser

       @listenTo @layout, 'show', ->
-        @showBalance()
+        @showBalance() if App.currentUser.isSignedIn()

       App.mainHeaderRegion.show @layout


:bug: degradation multiple RepeatFind hover shown when previous Find is not there

--- lib/operation-stack.coffee
+++ lib/operation-stack.coffee
@@ -37,8 +37,8 @@
       @processing = true
       @process()
     catch error
+      @vimState.reset()
       unless error.instanceof?('OperationAbortedError')
-        @vimState.reset()
         throw error
     finally
       @processing = false


:art: scroll to center if destination was not within screen.

--- lib/motion.coffee
+++ lib/motion.coffee
@@ -607,7 +607,8 @@
       return

     range = ranges[(@getCount(1) - 1) % ranges.length]
-    cursor.setBufferPosition(range.start)
+    @editor.scrollToBufferPosition(range.start, center: true)
+    cursor.setBufferPosition(range.start, center: true)

     if settings.get('flashOnSearch')
       @flash range


Use base overlay top function for photos

This corretly positions the overlay in the middle of the screen

--- app/assets/javascripts/photo_overlay_dimensions.js.coffee
+++ app/assets/javascripts/photo_overlay_dimensions.js.coffee
@@ -76,8 +76,5 @@
   leftPaneWidth: ->
     @width() - @commentWidth

-  top: ->
-    window.scrollY + @minMargin
-
   closeButtonLeftPosition: ->
     @width() - @closeButtonOffset


7808: Removed field_with_errors dependency from form view

--- app/assets/javascripts/views/form_settings_view.js.coffee
+++ app/assets/javascripts/views/form_settings_view.js.coffee
@@ -15,19 +15,20 @@
     @init_recipient_select()

   show_setting_fields: (event) ->
-    event.preventDefault()
+    event.preventDefault() if event
     $('.more-settings').hide()
     $('.less-settings').show()
     $('.setting-fields').show()

   hide_setting_fields: (event) ->
-    event.preventDefault()
+    event.preventDefault() if event
     $('.more-settings').show()
     $('.less-settings').hide()
     $('.setting-fields').hide()

   show_fields_with_errors: ->
-    $('.field_with_errors:hidden').closest('.setting-fields').show()
+    if @$('.setting-fields .form-field.has-errors').length > 0
+      @show_setting_fields()

   show_hide_sms_settings: ->
     read_only = @$('#smsable div.ro-val').length > 0


Update object.coffee code to eliminate .isString and .isRaw hacks and replace with the Buffer object so that anything can be supported.

--- lib/object.coffee
+++ lib/object.coffee
@@ -15,12 +15,9 @@
         else if typeof object is 'string'
             '/' + object

-        else if object?.isString
-            '(' + object + ')'
-
-		else if object?.isRaw
-			object.toString()
-
+        else if Buffer.isBuffer(object)
+            object.toString()
+
         else if object instanceof PDFReference
             object.toString()

@@ -67,10 +64,7 @@
         if swap
             string = swapBytes(new Buffer('\ufeff' + string, 'ucs-2')).toString('binary')

-        return {
-            isString: yes
-            toString: -> string
-        }
+        return new Buffer("("+string+")")

 module.exports = PDFObject
 PDFReference = require './reference'


get config from json directly for deploy

--- lib/runnable/deploy.coffee
+++ lib/runnable/deploy.coffee
@@ -64,16 +64,16 @@
     console.log ""

     [local, remote] = op.parseMapping options.mapping
-    [userName, pass] = op.getCreds options.config_file
+    {user_name, password} = (require options.config_file)

     #Assume current author by default
-    remote = "#{userName}/#{remote}"  if remote.indexOf("/") is -1
+    remote = "#{user_name}/#{remote}"  if remote.indexOf("/") is -1

     tempFile = "#{basePath}/archive.zip"

     confirm "Are you sure you want to deploy " +  (color local, "white") + " to " + (color remote, "white") + "?", ()->
         createTempZip local, tempFile, ()->
-            getToken userName, pass, remote, (token)->
+            getToken user_name, password, remote, (token)->
                 uploadFile token, remote, ()->
                     st = fs.statSync(tempFile)
                     sizeInMB = (st.size / (1024 * 1024)).toFixed(2)


:shirt: Parens Around Comprehension

:shirt: Parens Around Comprehension

--- lib/symbol-provider.coffee
+++ lib/symbol-provider.coffee
@@ -222,7 +222,7 @@
   getLocalityScore: (bufferPosition, bufferRowsContainingSymbol) ->
     if bufferRowsContainingSymbol?
       rowDifference = Number.MAX_VALUE
-      rowDifference = Math.min(rowDifference, bufferRow - bufferPosition.row) for bufferRow in bufferRowsContainingSymbol
+      rowDifference = (Math.min(rowDifference, bufferRow - bufferPosition.row) for bufferRow in bufferRowsContainingSymbol)
       locality = @computeLocalityModifier(rowDifference)
       locality
     else


update sentry_client in authentication header

--- lib/sentry.coffee
+++ lib/sentry.coffee
@@ -43,7 +43,7 @@
       uri: "https://app.getsentry.com/api/#{@project_id}/store/"
       method: 'post'
       headers:
-        'X-Sentry-Auth': "Sentry sentry_version=4, sentry_key=#{@key}, sentry_secret=#{@secret}, sentry_client=getclever.com/0.1"
+        'X-Sentry-Auth': "Sentry sentry_version=4, sentry_key=#{@key}, sentry_secret=#{@secret}, sentry_client=sentry-node/0.1.0"
       json: data
     quest options, (err, res, body) ->
       if err? or res.statusCode > 299


Fix autostart not returning original vms

--- src/cli.coffee
+++ src/cli.coffee
@@ -41,8 +41,8 @@
       do (vm) -> seq = seq.then -> Q.fcall fn, vm
     seq

-  autoStart: (headless) ->
-    addDsl @then (vms) => @where('!running').all (vm) -> vm.start headless
+  autoStart: (headless) -> addDsl @then (vms) =>
+    @where('!running').all((vm) -> vm.start headless).then -> vms

   maybeAutoStart: (maybe, headless) -> if maybe then @autoStart headless else @


Better duration in webconf invitations

Better duration in webconf invitations

refs #1179

--- app/assets/javascripts/app/custom_bigbluebutton_rooms/_invitation_form.js.coffee
+++ app/assets/javascripts/app/custom_bigbluebutton_rooms/_invitation_form.js.coffee
@@ -95,8 +95,10 @@
 updateDuration = ->
   duration = previousDuration
   duration = ignoreSeconds(new Date(duration * 1000)).getTime()
-  duration = moment.duration(duration, "milliseconds")
-  text = duration.humanize()
+  #duration = moment.duration(duration, "milliseconds")
+  #text = duration.humanize()
+  text = moment.utc(duration).format("HH:mm")
+
   $(durationSelector).text(text)

 # Adjusts the end date according to the start date. The end can never be lower


fundings onEdit fix

fundings onEdit fix

--- app/assets/javascripts/components/company_profile/content/funding/view.js.coffee
+++ app/assets/javascripts/components/company_profile/content/funding/view.js.coffee
@@ -11,6 +11,8 @@
   render: ->
     if @state.funding || @state.new
       CompanyProfile_Content_Funding_Form(funding: @state.funding, saveProfile: @props.saveProfile, onCancel: @_onFormCancel)
+    else if @state.edit_mode
+      @_renderListings()
     else if _.isEmpty(@state.company.fundings)
       @_renderEmpty()
     else


Changes week start date

Changes week start date


Cleanup: minor

Cleanup: minor

--- server/lib/crawler/staticpages/feed.coffee
+++ server/lib/crawler/staticpages/feed.coffee
@@ -1,8 +1,9 @@
-{argv}                               = require 'optimist'
-{uri}                                = require('koding-config-manager').load("main.#{argv.c}")
-{ daisy }                            = require "bongo"
-{ Relationship }                     = require 'jraphical'
-{ createActivityContent, decorateComment } = require '../helpers'
+{argv}                  = require 'optimist'
+{uri}                   = require('koding-config-manager').load("main.#{argv.c}")
+{daisy}                 = require "bongo"
+{Relationship}          = require 'jraphical'
+{createActivityContent,
+ decorateComment}       = require '../helpers'

 ITEMSPERPAGE = 20


Selected index should not be -1

Selected index should not be -1

--- app/assets/javascripts/1-components/change_view.js.coffee
+++ app/assets/javascripts/1-components/change_view.js.coffee
@@ -298,7 +298,7 @@
     # calculate top that points to the selected file
     selectedPathname = getLocationHash()['P']
     pathnames = @props.pathnames
-    selectedIndex = _.indexOf(pathnames, selectedPathname) || 0
+    selectedIndex = Math.max(_.indexOf(pathnames, selectedPathname), 0)
     itemHeight = @refs.item0 && @refs.item0.getDOMNode().scrollHeight || 0
     paddingTop = 15
     top = e.clientY - (selectedIndex + 0.5) * itemHeight - paddingTop


Fix issues expanding notifications' table rows

--- app/assets/javascripts/admin/views/notifications/index.js.coffee
+++ app/assets/javascripts/admin/views/notifications/index.js.coffee
@@ -16,8 +16,8 @@
   renderTable: ->
     @$el.find('#notifications-view').html JST["admin/templates/notifications/notifications_table"](notifications: Augury.notifications)
     @$el.find('#notifications-table').find('td.actions a').on 'click', ->
-      @parent().parent().next().toggle()
-      @parent().parent().toggleClass('without-border')
+      $(@).parent().parent().next().toggle()
+      $(@).parent().parent().toggleClass('without-border')
     SyntaxHighlighter.all()

   search: ->


add console logs

add console logs

--- app/assets/javascripts/angular/controllers/graphs_ctrl.js.coffee
+++ app/assets/javascripts/angular/controllers/graphs_ctrl.js.coffee
@@ -27,7 +27,9 @@
       for key, value of result[0]
         if key[0] != '$'
           array.push {time: key, data: value}
+      console.log array
       $scope.hourData = array
+      console.log $scope.hourData
       $scope.refreshPage()
     )


Updates cache syntax

Updates cache syntax

--- app/assets/javascripts/sprangular/services/catalog.coffee
+++ app/assets/javascripts/sprangular/services/catalog.coffee
@@ -11,7 +11,7 @@
       @getPaged(page, taxon: path)

     taxonomies: ->
-      $http.get("/api/taxonomies", {cache: true})
+      $http.get("/api/taxonomies", cache: true)
         .then (response) ->
           response.data.taxonomies


tweak

tweak

--- app/assets/javascripts/swell_media/custom/login.js.coffee
+++ app/assets/javascripts/swell_media/custom/login.js.coffee
@@ -67,8 +67,8 @@

 	$('body').on(
 		'click',
-		'a.popup',
+		'a.auth-popup',
 	(e) ->
-		popupCenter($(this).attr("href"), $(this).attr("data-width"), $(this).attr("data-height"), "authPopup");
+		popupCenter($(this).attr("href"), $(this).attr("data-width") || 600, $(this).attr("data-height") || 400, "authPopup");
 		e.stopPropagation(); return false;
 	);


Remove log line

Remove log line

--- assets/javascripts/controllers/index_controller.js.coffee
+++ assets/javascripts/controllers/index_controller.js.coffee
@@ -23,7 +23,6 @@
         createdAt: new Date()
         user: currentUser

-      console.log messageParams
       msg = @store.createRecord("message", messageParams)
       successCallback = ->
         console.log "message has been posted"


team: creation: more invitee addability

team: creation: more invitee addability

--- client/landing/site.landing/coffee/team/teaminvitetabform.coffee
+++ client/landing/site.landing/coffee/team/teaminvitetabform.coffee
@@ -4,6 +4,13 @@
 module.exports = class TeamInviteTabForm extends KDFormView

   JView.mixin @prototype
+  count = 0
+  createInput = ->
+    count++
+    new KDInputView
+      placeholder : "email@domain.com"
+      name        : "invitee#{count}"
+

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

@@ -21,26 +28,34 @@
       name         : 'allow'
       label        : @label

-    @input1 = new KDInputView placeholder : 'email@domain.com'
-    @input2 = new KDInputView placeholder : 'email@domain.com'
-    @input3 = new KDInputView placeholder : 'email@domain.com'
+    @input1 = createInput()
+    @input2 = createInput()
+    @input3 = createInput()
+
     @add = new KDButtonView
-      title       : 'ADD INVITATION'
-      style       : 'SignupForm-button compact SignupForm-button--gray add'
+      title    : 'ADD INVITATION'
+      style    : 'SignupForm-button compact SignupForm-button--gray add'
+      callback : @bound 'addInvitee'

     @skip = new CustomLinkView
-      title       : 'Skip this step'
-      cssClass    : 'SignupForm-linkButton skip'
-      href        : '/Team/username'
+      title    : 'Skip this step'
+      cssClass : 'SignupForm-linkButton skip'
+      href     : '/Team/username'

     @button = new KDButtonView
-      title       : 'NEXT'
-      style       : 'SignupForm-button SignupForm-button--green'
-      attributes  : testpath  : 'invite-button'
-      loader      : yes
-      callback    : =>
-        console.log 'go to username:'
-        KD.singletons.router.handleRoute '/Team/username'
+      title      : 'NEXT'
+      style      : 'SignupForm-button SignupForm-button--green'
+      attributes : testpath : 'invite-button'
+      type       : 'submit'
+
+
+  addInvitee: ->
+
+    input   = createInput()
+    wrapper = new KDCustomHTMLView cssClass : 'login-input-view'
+    wrapper.addSubView input
+    @addSubView wrapper, '.additional'
+    input.setFocus()

   pistachio: ->
@@ -49,6 +64,7 @@

{{> @input1}}

{{> @input2}}

{{> @input3}}

+

     {{> @add}}

if you’d like, you can send invitations after you finish setting up your team.

     {{> @skip}}{{> @button}}


Fix typo.

Fix typo.

--- app/assets/javascripts/lib/components/datepicker.js.coffee
+++ app/assets/javascripts/lib/components/datepicker.js.coffee
@@ -39,7 +39,7 @@
         dateMin: today
         format: config.dateFormat
         onSelect: ->
-          self.dateSelec8ted(this.getDate(config.dateFormat), "start")
+          self.dateSelected(this.getDate(config.dateFormat), "start")
       })

       @out_date.pickadate({


load asyncImg on search pagination

load asyncImg on search pagination

--- app/assets/javascripts/modules/search/pagination.js.coffee
+++ app/assets/javascripts/modules/search/pagination.js.coffee
@@ -1,4 +1,4 @@
-define('pagination', [], ->
+define('pagination', ['asyncImg'], (asyncImg) ->
   class Pagination
     constructor: (@container, @resultClass) ->
       @render()
@@ -10,6 +10,8 @@
         itemSelector: @resultClass
         loading:
           msgText: ''
+      , (newResults) ->
+        asyncImg()
       )

   return Pagination


Remove trailing whitespaces

Remove trailing whitespaces

--- app/assets/javascripts/prevent_double_submission.js.coffee
+++ app/assets/javascripts/prevent_double_submission.js.coffee
@@ -22,15 +22,15 @@

   initialize: ->
     $('form').on('submit', (event) ->
-      unless event.target.id == "new_officing_voter" ||
+      unless event.target.id == "new_officing_voter" ||
              event.target.id == "admin_download_emails"

         buttons = $(this).find(':button, :submit')
         App.PreventDoubleSubmission.disable_buttons(buttons)
     ).on('ajax:success', (event) ->
-      unless event.target.id == "new_officing_voter" ||
+      unless event.target.id == "new_officing_voter" ||
              event.target.id == "admin_download_emails"
-
+
         buttons = $(this).find(':button, :submit')
         App.PreventDoubleSubmission.reset_buttons(buttons)
     )


fucking fixed it.

fucking fixed it.

--- app/assets/javascripts/views/clouds/chat/message.js.coffee
+++ app/assets/javascripts/views/clouds/chat/message.js.coffee
@@ -60,16 +60,12 @@
     # Greentext
     content = content.replace(/((^>|\\n>)[\w\d\s\!\'\"\'\.\,\-\_\/\?\:\&\^\<\>\=\#\%\+\*\~\\√\◊\(\)\[\]\{\}]*\\n)/ig,"$1")

-    # Zee text.
-    # if @model.get('user').get('role') == 'founder'
-    #   content = content.replace(/^\[ZEE\](.*)/ig,"$1")
-
     elem = $("

")

     if message.selfReference()
-      content = content.replace(/\\n$/ig,"").replace(/\\n/ig,"")
-      content = message.get('content').replace(/^\/me/i,message.user().get('name'))
-      elem.html(escapeHTML(content))
+      content = content.replace(/\\n$/ig,"").replace(/\\n/ig," ")
+      content = content.replace(/^\/me/i,message.user().get('name'))
+      elem.html(content)
     else
       content = content.replace(/\\n$/ig,"").replace(/\\n/ig,"
")
       elem.html(content)


Render 100 messages at a time.

Render 100 messages at a time.

--- app/assets/javascripts/web/routes/messages_route.js.coffee
+++ app/assets/javascripts/web/routes/messages_route.js.coffee
@@ -95,7 +95,6 @@

       if params = @store.get(key + ':more')
         @store.set(key + ':more', undefined)
-        params.limit = 1
         Ember.Logger.debug("Fetching more #{key} from server")

       else if @store.get(key + ':initial') == undefined
@@ -103,7 +102,7 @@
         Ember.Logger.debug("Fetching initial #{key} from server")

         topic  = convo.get('topic')
-        params = { topic: { id: topic.id, type: topic.get('type') }, limit: 50 }
+        params = { topic: { id: topic.id, type: topic.get('type') }, limit: 100 }

       if params
         @store.find('message', params).then(


benchmark: fix createBrowserOnly mode

benchmark: fix createBrowserOnly mode

--- benchmarks/clients/client_process.coffee
+++ benchmarks/clients/client_process.coffee
@@ -285,6 +285,7 @@
                     @_initialSocketIo()
                 )
             else
+                @emit("clientEngineReady")
                 @stopped = true

     _initialSocketIo : ()->


Use underscore node module

Use underscore node module

--- lib/wrap-guide-view.coffee
+++ lib/wrap-guide-view.coffee
@@ -1,6 +1,6 @@
 {View} = require 'space-pen'
 $ = require 'jquery'
-_ = require 'underscore'
+_ = nodeRequire 'underscore'

 module.exports =
 class WrapGuideView extends View


findercontroller: refactor "mountVms" as a method

--- client/app/MainApp/filetree/controllers/findercontroller.coffee
+++ client/app/MainApp/filetree/controllers/findercontroller.coffee
@@ -72,15 +72,15 @@
     else
       @loadVms()

+  mountVms: (vms) ->
+    unless Array.isArray vms
+      return callback? "vmNames should be an Array"
+    @cleanup()
+    @mountVm vm  for vm in vms
+    callback?()
+
   loadVms:(vmNames, callback)->
-    mountVms = (vms)=>
-      unless Array.isArray vms
-        return callback? "vmNames should be an Array"
-      @cleanup()
-      @mountVm vm  for vm in vms
-      callback?()
-
-    if vmNames then mountVms vmNames
+    if vmNames then @mountVms vmNames
     else
       groupSlug  = KD.getSingleton("groupsController").getGroupSlug()
       groupSlug ?= 'koding'
@@ -88,16 +88,16 @@
         vms            or= {}
         vms[groupSlug] or= []
         if vms[groupSlug].length > 0
-          mountVms vms[groupSlug]
+          @mountVms vms[groupSlug]
         else
           KD.remote.api.JVM.fetchVmsByContext {}, (err, vms)=>
             return callback? err  if err
             if not vms or vms.length is 0
               KD.getSingleton('vmController').fetchDefaultVmName (vm)=>
-                if vm then mountVms [vm]
+                if vm then @mountVms [vm]
                 else @noVMFoundWidget.show()
             else
-              mountVms vms
+              @mountVms vms

   getVmNode:(vmName)->
     return null  unless vmName


automatically handle case where Earl is used with url contain base .html file

--- earl.coffee
+++ earl.coffee
@@ -35,7 +35,7 @@
 #   Earl.start_work
 #     opts:
 #        history_aware_links: Enables history aware link. Wraps basic dom.A. [false]
-#        root: the base path that urls are relative too, such as my_root.html. ['/']
+
 #   Earl.load_page
 #     Convenience method for changing the page's url

@@ -47,10 +47,9 @@
     if opts.history_aware_links
       install_history_aware_links()

-    opts.root ||= '/'
-    if opts.root[0] != '/'
-      opts.root = '/' + opts.root
-    Earl.root = opts.root
+    Earl.root = '/'
+    if window.location.pathname.match('.html')
+      Earl.root += location.pathname.match(/\/(\w+\.html)/)[1] + '/'

     # Earl, don't forget to update us if the browser back or forward button pressed
     window.addEventListener 'popstate', (ev) ->
@@ -90,7 +89,7 @@
       # after it is processed.
       seek_to_hash = true

-    loc.url = url
+    loc.url = url or '/'
     loc.hash = hash

     save loc
@@ -189,7 +188,8 @@

       # update browser history if it hasn't already been updated
       if url_from_browser_location() != new_location
-        history.pushState loc.query_params, title, (Earl.root + '/' + new_location).replace(/(\/)+/', '/')
+        h = (Earl.root + new_location)
+        history.pushState loc.query_params, title, h.replace(/(\/){2,}/, '/').replace(/(\/)$/, '')

       @last_location = new_location

@@ -214,15 +214,15 @@
   search = location.search?.replace(/\%2[fF]/g, '/')
   loc = location.pathname?.replace(/\%20/g, ' ')

-  if Earl.root && !!loc.match(Earl.root)
-    loc = loc.split(Earl.root)[1]
+  if Earl.root
+    loc = (loc + '/').split(Earl.root)[1]

   "#{loc}#{search}#{location.hash}"

 url_from_statebus = ->
   loc = fetch 'location'

-  relative_url = loc.url or ''
+  relative_url = loc.url or '/'

   if loc.query_params && Object.keys(loc.query_params).length > 0
     query_params = ("#{k}=#{v}" for own k,v of loc.query_params)


create new worksheet and name it with .sagews extension results in .sagews.sagews; also ban creation of certain file types

--- salvus/page/project.coffee
+++ salvus/page/project.coffee
@@ -941,11 +941,11 @@
             s = $.trim(@new_file_tab.find(".project-new-file-path").text() + name)
             if ext?
                 if misc.filename_extension(s) != ext
-                    s += ext
+                    s += '.' + ext
             return s

         @new_file_tab.find("a[href=#new-terminal]").click () =>
-            p = path('.term')
+            p = path('term')
             if p.length == 0
                 @new_file_tab_input.focus()
                 return false
@@ -955,21 +955,18 @@
             return false

         @new_file_tab.find("a[href=#new-worksheet]").click () =>
-            create_file('.sagews')
-            return false
-
-        @new_file_tab.find("a[href=#old-worksheet]").click () =>
-            p = path('.sage-worksheet')
-            if p.length == 0
-                @new_file_tab_input.focus()
-                return false
-            @display_tab("project-editor")
-            tab = @editor.create_tab(filename:p, content:"")
-            @editor.display_tab(path:p)
-            return false
+            create_file('sagews')
+            return false
+
+        BANNED_FILE_TYPES = ['doc', 'docx', 'pdf', 'sws', 'ipynb']

         create_file = (ext) =>
             p = path(ext)
+            ext = misc.filename_extension(p)
+            if ext in BANNED_FILE_TYPES
+                alert_message(type:"error", message:"Creation of #{ext} files not supported.", timeout:3)
+                return false
+
             if p.length == 0
                 @new_file_tab_input.focus()
                 return false


elektron: don't show menu after checking kd

--- elektron/src/trayicon.coffee
+++ elektron/src/trayicon.coffee
@@ -241,7 +241,7 @@
         ,
           label   : 'Start kd ...'
           click   : handleOpen 'sudo kd start', 'terminal'
-        ], yes
+        ], no

         @_isKdRunning = no


use the focus*() functions when opening the dialog

--- lib/buffer-find-and-replace-view.coffee
+++ lib/buffer-find-and-replace-view.coffee
@@ -130,13 +130,11 @@
   showFind: =>
     @attach()
     @addClass('find-mode').removeClass('replace-mode')
-    @findEditor.selectAll()
-    @findEditor.focus()
+    @focusFind()
   showReplace: =>
     @attach()
     @addClass('replace-mode').removeClass('find-mode')
-    @replaceEditor.selectAll()
-    @replaceEditor.focus()
+    @focusReplace()

   focusFind: =>
     @replaceEditor.clearSelections()


Remove hack for currentResult clearing

Remove hack for currentResult clearing

--- lib/buffer-find-and-replace-view.coffee
+++ lib/buffer-find-and-replace-view.coffee
@@ -91,7 +91,6 @@
         view = new SearchResultsView(@searchModel, editor, {@active})
         @searchResultsViews.push(view)
         editor.underlayer.append(view)
-        editor.on 'cursor:moved', @onCursorMoved

     @findEditor.on 'keyup', (e) =>
       # When the user types something in the find box, we dont want to lose it
@@ -109,16 +108,6 @@
     editor = @currentEditor()
     @trigger('active-editor-changed', editor: editor)

-  onCursorMoved: =>
-    if @cursorMoveOriginatedHere
-      # HACK: I want to reset the current result whenever the cursor is moved
-      # so it removes the '# of' from '2 of 100'. But I cant tell if I moved
-      # the cursor or the user did as it happens asynchronously. Thus this
-      # crappy boolean. Open to suggestions.
-      @cursorMoveOriginatedHere = false
-    else
-      @currentEditor().trigger('find-and-replace:clear-current-result')
-
   onSearchModelChanged: (model, args) =>
     @updateOptionButtons()

@@ -183,12 +172,10 @@

   findPrevious: =>
     @search()
-    @cursorMoveOriginatedHere = true # See HACK above.
     @currentEditor().trigger('find-and-replace:find-previous')

   findNext: =>
     @search()
-    @cursorMoveOriginatedHere = true # See HACK above.
     @currentEditor().trigger('find-and-replace:find-next')

   setSelectionAsSearchPattern: =>


:memo: Use ### for example sections

:memo: Use ### for example sections

--- src/git.coffee
+++ src/git.coffee
@@ -27,12 +27,14 @@
 #
 # ## Examples
 #
+# ### Logging the URL of the origin remote
+#
 # ```coffee
 #   git = atom.project.getRepo()
 #   console.log git.getOriginUrl()
 # ```
 #
-# ## Requiring in packages
+# ### Requiring in packages
 #
 # ```coffee
 #   {Git} = require 'atom'


applied a class on overlay elements, use CSS to define backgroundColor and opacity

--- plugins/overlay.coffee
+++ plugins/overlay.coffee
@@ -153,10 +153,8 @@
             return m

         _getBasicPiece: ->
-            p = jQuery('<div>')
+            p = jQuery('<div class="halloOverlay">')
             p.css
                 position: 'absolute'
-                backgroundColor: @options.backgroundColor
-                opacity: @.options.opacity

 )(jQuery)


firefox throws an exception before firing an ajax delete request if processData is false. jQuery seems to automatically add data: {} to the request options, and if this is not stringified, firefox throws up

--- vendor/assets/javascripts/brainstem/brainstem-sync.coffee
+++ vendor/assets/javascripts/brainstem/brainstem-sync.coffee
@@ -58,7 +58,7 @@
         beforeSend.apply this, arguments

   # Don't process data on a non-GET request.
-  if params.type != 'GET' && !options.emulateJSON
+  if params.type != 'GET' && !options.emulateJSON && params.type != 'DELETE'
     params.processData = false

   # If we're sending a `PATCH` request, and we're in an old Internet Explorer


Fix unmountVm for new environments.

Fix unmountVm for new environments.

--- client/finder/filetree/controllers/findertreecontroller.coffee
+++ client/finder/filetree/controllers/findertreecontroller.coffee
@@ -82,8 +82,8 @@
     KD.getSingleton('vmController').reinitialize vmName

   unmountVm:(nodeView)->
-    {vmName} = nodeView.data
-    @getDelegate().unmountVm vmName
+    { machine: { uid } } = nodeView.getData()
+    @getDelegate().unmountMachine uid

   openVmTerminal:(nodeView)->
     {vmName} = nodeView.data
@@ -92,7 +92,7 @@
   toggleDotFiles:(nodeView)->

     finder = @getDelegate()
-    { machine:{ uid } } = nodeView.getData()
+    { machine: { uid } } = nodeView.getData()

     if finder.isNodesHiddenFor uid
     then finder.showDotFiles uid


more accurate condition for setting the default title on CustomLinkView

--- client/landing/app/CommonViews/linkviews/customlinkview.coffee
+++ client/landing/app/CommonViews/linkviews/customlinkview.coffee
@@ -4,7 +4,7 @@

     options.tagName or= 'a'
     options.cssClass  = KD.utils.curryCssClass 'custom-link-view', options.cssClass
-    data.title        = options.title
+    data.title        ?= options.title

     options.attributes ?= {}
     options.attributes.href     = options.href      if options.href?


Updated comment question to use icons

Updated comment question to use icons

--- core/app/backbone/views/evidence/add_evidence_form_view.coffee
+++ core/app/backbone/views/evidence/add_evidence_form_view.coffee
@@ -55,13 +55,13 @@
     @_showQuestion()

   _updateQuestion: ->
-    @ui.question.text switch @_argumentTypeModel.get('argument_type')
+    @ui.question.html switch @_argumentTypeModel.get('argument_type')
       when 'believes'
-        "Why do you #{Factlink.Global.t.fact_believe_opinion}?"
+        'Why do you ?'
       when 'disbelieves'
-        "Why do you #{Factlink.Global.t.fact_disbelieve_opinion}?"
+        'Why do you  ?'
       when 'doubts'
-        "What do you think?"
+        'What do you think?'
       else
         ''


OX-299 adjusted cube-datastructure for brainflight

--- app/assets/javascripts/oxalis/model/binary/cube.coffee
+++ app/assets/javascripts/oxalis/model/binary/cube.coffee
@@ -12,10 +12,12 @@
   LOOKUP_DEPTH_UP : 0
   LOOKUP_DEPTH_DOWN : 1
   MAXIMUM_BUCKET_COUNT : 5000
+  ARBITRARY_MAX_ZOOMSTEP : 2

   LOADING_PLACEHOLDER : {}

-  cube : null
+  arbitraryCube : null
+  cubes : null
   upperBoundary : null
   access : null
   bucketCount : 0
@@ -50,7 +52,7 @@

     @LOOKUP_DEPTH_UP = @ZOOM_STEP_COUNT
     @BUCKET_LENGTH = 1 << @BUCKET_SIZE_P * 3
-    @cube = []
+    @cubes = []
     @access = new RingBuffer(@MAXIMUM_BUCKET_COUNT * 20)

     # Initializing the cube-arrays with boundaries
@@ -60,9 +62,11 @@
       @upperBoundary[2] >> @BUCKET_SIZE_P
     ]

+    @arbitraryCube = { boundary: cubeBoundary.slice(), buckets: new Array(cubeBoundary[0] * cubeBoundary[1] * cubeBoundary[2]) }
+
     for i in [0..@ZOOM_STEP_COUNT]

-      @cube[i] = { boundary: cubeBoundary.slice(), buckets: new Array(cubeBoundary[0] * cubeBoundary[1] * cubeBoundary[2]) }
+      @cubes[i] = { boundary: cubeBoundary.slice(), buckets: new Array(cubeBoundary[0] * cubeBoundary[1] * cubeBoundary[2]) }
       cubeBoundary = [
         (cubeBoundary[0] + 1) >> 1
         (cubeBoundary[1] + 1) >> 1
@@ -70,9 +74,14 @@
       ]

+  getArbitraryCube : ->
+
+    @arbitraryCube
+
+
   getBucketIndexByZoomedAddress : ([bucket_x, bucket_y, bucket_z, zoomStep]) ->

-    boundary = @cube[zoomStep].boundary
+    boundary = @cubes[zoomStep].boundary

     if bucket_x >= 0 and bucket_x < boundary[0] and
     bucket_y >= 0 and bucket_y < boundary[1] and
@@ -90,7 +99,7 @@

   getBucketByZoomedAddress : (address) ->

-    buckets = @cube[address[3]].buckets
+    buckets = @cubes[address[3]].buckets
     bucketIndex = @getBucketIndexByZoomedAddress(address)

     if bucketIndex?
@@ -116,7 +125,7 @@

   isBucketRequestedByZoomedAddress : (address) ->

-    buckets = @cube[address[3]].buckets
+    buckets = @cubes[address[3]].buckets
     bucketIndex = @getBucketIndexByZoomedAddress(address)

     # if the bucket lies inseide the dataset
@@ -143,7 +152,7 @@
     # return if no request is needed
     return if @isBucketRequestedByZoomedAddress(address)

-    buckets = @cube[address[3]].buckets
+    buckets = @cubes[address[3]].buckets
     bucketIndex = @getBucketIndexByZoomedAddress(address)

     # mark the bucket as requested
@@ -177,6 +186,29 @@

       @trigger("bucketLoaded", [bucket_x, bucket_y, bucket_z, zoomStep])

+      if zoomStep <= @ARBITRARY_MAX_ZOOMSTEP
+
+        arbitraryCube = @arbitraryCube.buckets
+        width = 1 << zoomStep
+
+        for dx in [0...width] by 1
+          for dy in [0...width] by 1
+            for dz in [0...width] by 1
+
+              subBucket = [
+                (bucket_x << zoomStep) + dx
+                (bucket_y << zoomStep) + dy
+                (bucket_z << zoomStep) + dz
+                0
+              ]
+
+              bucketIndex = @getBucketIndexByZoomedAddress(subBucket)
+
+              if not arbitraryCube[bucketIndex] or arbitraryCube[bucketIndex].zoomStep > zoomStep
+
+                bucketData.zoomStep = zoomStep
+                arbitraryCube[bucketIndex] = bucketData
+
     else

       bucket.data = null
@@ -186,7 +218,7 @@

     return false if zoomStep == 0 or zoomStep == @ZOOM_STEP_COUNT

-    cube = @cube[zoomStep]
+    cube = @cubes[zoomStep]
     bucketIndex = @getBucketIndexByZoomedAddress([bucket_x, bucket_y, bucket_z, zoomStep])

     cube.buckets[bucketIndex] = { data: null, level: @LOOKUP_DEPTH_DOWN + 1, access: 0 } unless cube.buckets[bucketIndex]?
@@ -198,7 +230,7 @@
     oldBucketLevel = bucket.level
     bucket.level = 0

-    subCube = @cube[zoomStep - 1]
+    subCube = @cubes[zoomStep - 1]

     for dx in [0..1]
       for dy in [0..1]


billing: update credit card view to understand card number changed

--- client/home/lib/billing/components/creditcard/view.coffee
+++ client/home/lib/billing/components/creditcard/view.coffee
@@ -11,15 +11,15 @@

   render: ->

-    console.log {@props}
-

       Card Number
       <CardNumber
         hasError={@props.formErrors.get 'number'}
         onChange={@props.onInputValueChange.bind null, 'number'}
         cardType={@props.formValues.get 'cardType'}
-        value={@props.formValues.get 'number'} />
+        value={@props.formValues.get 'number'}
+        isEdited={@props.formValues.get 'isEdited'}
+        mask={@props.formValues.get 'mask'} />
       <fieldset className='wrapper--expiration'>
         Expiration
         <Expiration type='month'
@@ -42,19 +42,13 @@

-CardNumber = ({ onChange, hasError, value, cardType }) ->
-
-  mask = switch cardType
-    when 'American Express' then '9999 999999 99999'
-    else '9999 9999 9999 9999'
+CardNumber = ({ onChange, hasError, value, cardType, isEdited, mask }) ->

   type = kd.utils.slugify cardType

   placeholder = ''

-  # means that the value is coming from the group card.
-  # so we will use this as a placeholder
-  if /^\*/.test(value)
+  unless isEdited
     placeholder = value
     value = ''


improved tbot message after "build json" command

--- scripts/example.coffee
+++ scripts/example.coffee
@@ -32,6 +32,7 @@

      request.post options, (error, response, data)->
        res.reply 'Request sent, take a look at https://ci.appveyor.com/project/DinisCruz/tm-4-0-json-data where a new build should have just started'
+       res.reply 'In a bit, if there were changes to the Lib_Uno xml files, the updated Json files will be at https://github.com/tm-build/Lib_UNO-json'
        #res.reply data.json_Parse().json_Pretty()


Removed registration code

Removed registration code

--- core/app/assets/javascripts/base/registration_forms.coffee
+++ core/app/assets/javascripts/base/registration_forms.coffee
@@ -52,8 +52,6 @@
   form = $('#' + formId)

   form.on "ajax:success", (event, data, status, response) ->
-    registration_code = $("#" + formId + "_user_registration_code").val()
-
     window.location = data.location

   form.on "ajax:error", (event, response, error) ->


replace htmlmin with $.minifyHtml

replace htmlmin with $.minifyHtml

Signed-off-by: Bo-Yi Wu <f80eec1bf98b3feebacc247f35f2b506218004cb@gmail.com>

--- templates/gulpfile.coffee
+++ templates/gulpfile.coffee
@@ -51,9 +51,7 @@
     .pipe $.if '*.html', $.minifyHtml()<% } else { %>
     .pipe $.replace 'js/main', 'js/' + filename
     .pipe $.replace 'vendor/requirejs/require.js', 'js/require.js'
-    .pipe $.htmlmin
-      removeComments: true
-      collapseWhitespace: true<% } %>
+    .pipe $.minifyHtml()<% } %>
     .pipe gulp.dest paths.dist

 gulp.task 'styles', ->


Touchpad friendly. (chrome)

Touchpad friendly. (chrome)

--- fattable.coffee
+++ fattable.coffee
@@ -320,7 +320,7 @@
         onMouseWheel = (evt)=>
             # TODO support other browsers
             if evt.type is "mousewheel"
-                @setScrollXY @scrollLeft, @scrollTop - evt.wheelDelta
+                @setScrollXY @scrollLeft - evt.wheelDeltaX, @scrollTop - evt.wheelDeltaY

         if @container.addEventListener
             @container.addEventListener "mousewheel", onMouseWheel, false


change reload to 5 minutes

change reload to 5 minutes

--- javascripts/dashing.coffee
+++ javascripts/dashing.coffee
@@ -102,7 +102,7 @@
     console.log("Connection closed")
     setTimeout (->
       window.location.reload()
-    ), 10000
+    ), 5*60*1000

 source.addEventListener 'message', (e) ->
   data = JSON.parse(e.data)


updated zoom on google maps

updated zoom on google maps

--- app/assets/javascripts/map.coffee
+++ app/assets/javascripts/map.coffee
@@ -2,7 +2,7 @@
   latlng = new google.maps.LatLng(latitude, longitude)

   mapOptions =
-    zoom: 8,
+    zoom: 15,
     center: latlng,
     mapTypeId: google.maps.MapTypeId.ROADMAP


increase time before autostop

increase time before autostop

--- server/lib/autostop.coffee
+++ server/lib/autostop.coffee
@@ -47,7 +47,7 @@
                         app.state is "installed"
                             console.log "stop : " + name
                             stopApp app
-    , 3 * 60 * 1000
+    ,10 * 60 * 1000

 ###
 Restart tiemout for application.


Added initialization of the schema files

--- app/initialize.coffee
+++ app/initialize.coffee
@@ -1,4 +1,21 @@
 app = require 'application'
+
+channelSchemas =
+  'app': require './schemas/subscriptions/app'
+  'bus': require './schemas/subscriptions/bus'
+  'editor': require './schemas/subscriptions/editor'
+  'errors': require './schemas/subscriptions/errors'
+  'level': require './schemas/subscriptions/level'
+  'misc': require './schemas/subscriptions/misc'
+  'play': require './schemas/subscriptions/play'
+  'surface': require './schemas/subscriptions/surface'
+  'tome': require './schemas/subscriptions/tome'
+  'user': require './schemas/subscriptions/user'
+  'world': require './schemas/subscriptions/world'
+
+definitionSchemas =
+  'bus': require './schemas/definitions/bus'
+  'misc': require './schemas/definitions/misc'

 init = ->
   app.initialize()
@@ -8,6 +25,10 @@
   treemaExt = require 'treema-ext'
   treemaExt.setup()
   filepicker.setKey('AvlkNoldcTOU4PvKi2Xm7z')
+
+  # Set up Backbone.Mediator schemas
+  configureChannels()
+  configureDefinitions()

 $ -> init()

@@ -32,3 +53,10 @@

       return false

+configureChannels = ->
+  for channel of channelSchemas
+    Backbone.Mediator.addChannelSchemas channelSchemas[channel]
+
+configureDefinitions = ->
+  for definition of definitionSchemas
+    Backbone.Mediator.addDefSchemas definitionSchemas[definition]


Revert "Express server creating in 2.x.x fixed"

This reverts commit aae0326fb4fc5dc0d76a4e5901d05ccd893fb462.

--- servers/embed/index.coffee
+++ servers/embed/index.coffee
@@ -7,7 +7,7 @@
 nconf = require("nconf")
 request = require("request")

-module.exports = app = express.createServer()
+module.exports = app = express()

 apiUrl = nconf.get("url:api")


using new dev ouroboros server

using new dev ouroboros server

--- app/lib/config.coffee
+++ app/lib/config.coffee
@@ -14,7 +14,7 @@
       workflowId: '502a701e516bcb0001000002'

   development:
-    apiHost: 'http://localhost:3000'
+    apiHost: 'https://dev.zooniverse.org'
     surveys:
       candels:
         id: '50251c3b516bcb6ecb000001'
@@ -43,7 +43,7 @@

 env = if window.jasmine
   'test'
-else if window.location.port > 9294
+else if window.location.port is '9294'
   'development'
 else
   'production'


fix(attachments): Present filesystem access errors

--- src/flux/stores/file-download-store.coffee
+++ src/flux/stores/file-download-store.coffee
@@ -192,12 +192,15 @@
       mkdirpAsync(targetFolder)

   _fetch: (file) ->
-    @_runDownload(file).catch ->
+    @_runDownload(file)
+    .catch(@_catchFSErrors)
+    .catch (error) ->
       # Passively ignore

   _fetchAndOpen: (file) ->
     @_runDownload(file).then (download) ->
       shell.openItem(download.targetPath)
+    .catch(@_catchFSErrors)
     .catch =>
       @_presentError(file)

@@ -224,6 +227,7 @@
       @_runDownload(file)
       .then (download) => @_saveDownload(download, savePath)
       .then => shell.showItemInFolder(savePath)
+      .catch(@_catchFSErrors)
       .catch =>
         @_presentError(file)

@@ -251,6 +255,7 @@
       Promise.all(savePromises)
       .then =>
         shell.showItemInFolder(lastSavePath) if lastSavePath
+      .catch(@_catchFSErrors)
       .catch =>
         @_presentError(file)

@@ -292,5 +297,16 @@
                Check your network connection and try again."
       buttons: ["OK"]

+  _catchFSErrors: (error) ->
+    if error.code in ['EPERM', 'EMFILE', 'EACCES']
+      remote.dialog.showMessageBox
+        type: 'warning'
+        message: "Download Failed"
+        detail: "N1 could not save an attachment. Check that permissions are set correctly and that you have enough disk space.\n\n#{error.message}"
+        buttons: ["OK"]
+      return Promise.resolve()
+    else
+      return Promise.reject(error)
+
 # Expose the Download class for our tests, and possibly for other things someday
 FileDownloadStore.Download = Download


Make sure documentation is json

Make sure documentation is json

--- test/documentation.coffee
+++ test/documentation.coffee
@@ -27,6 +27,7 @@
         resp.body.should.include 'reate'
         resp.body.should.include 'API'
         resp.body.should.include 'curl'
+        JSON.parse resp.body
         done()

   describe '( GET /<box_name> )', ->
@@ -48,5 +49,6 @@
         resp.body.should.include 'ssh'
         resp.body.should.include 'curl'
         resp.body.should.include '@'
+        JSON.parse resp.body
         done()


fix playlist when using feed as source

fix playlist when using feed as source

--- src/javascripts/extensions/playlist.coffee
+++ src/javascripts/extensions/playlist.coffee
@@ -9,12 +9,15 @@
 class PlaylistItem
   constructor: (@episode, @callback) ->
     @media = @context().media
+    if @episode.duration
+      @humanDuration = Utils.secondsToHHMMSS(_.clone(@episode.duration))

+  humanDuration: null
   active: false
   context: () ->
     _.merge(@episode, {
       active: @active,
-      humanDuration: Utils.secondsToHHMMSS(_.clone(@episode.duration))
+      humanDuration: @humanDuration
     })

   activate: ->
@@ -42,7 +45,7 @@

       { number }.

-      { humanDuration }
+      { humanDuration }

     """


Sidebar: Append more link to pistachio

Sidebar: Append more link to pistachio

--- client/Social/Activity/sidebar/activitysideview.coffee
+++ client/Social/Activity/sidebar/activitysideview.coffee
@@ -7,7 +7,7 @@

     super options, data

-    {itemClass, headerLink, noItemText} = @getOptions()
+    {itemClass, headerLink, noItemText, searchLink} = @getOptions()
     sidebar = @getDelegate()

     if noItemText
@@ -59,6 +59,10 @@
       @listController.selectSingleItem item
       sidebar.selectedItem = item

+    {countSource, limit} = @getOptions()
+    @moreLink = new SidebarMoreLink {href: searchLink, countSource, limit}
+    @moreLink.hide()
+

   init: ->

@@ -91,4 +95,5 @@
     """
     {{> @header}}
     {{> @listView}}
+    {{> @moreLink}}
     """


Groups: remove usage of bodyView since it's removed.

--- client/Social/Activity/sidebar/groupdescription.coffee
+++ client/Social/Activity/sidebar/groupdescription.coffee
@@ -40,6 +40,6 @@
       @addSubView @titleView
       # @addSubView @bodyView

-      if "admin" in KD.config.roles
-        @bodyView.setPartial "You can have a short description for your group here"  unless hasBody
+      # if "admin" in KD.config.roles
+      #   @bodyView.setPartial "You can have a short description for your group here"  unless hasBody


reserved keyword final fixed

reserved keyword final fixed

--- client/landing/app/MainApp/kodingappscontroller.coffee
+++ client/landing/app/MainApp/kodingappscontroller.coffee
@@ -136,15 +136,15 @@

       async.parallel asyncStack, (error, result)=>

-        final = "/* KDAPP STARTS */"
+        _final = "/* KDAPP STARTS */"
         result.forEach (output)=>
-          final += "\n\n/* BLOCK STARTS */\n\n"
-          final += "#{output}"
-          final += "\n\n/* BLOCK ENDS */\n\n"
-        final += "/* KDAPP ENDS */"
+          _final += "\n\n/* BLOCK STARTS */\n\n"
+          _final += "#{output}"
+          _final += "\n\n/* BLOCK ENDS */\n\n"
+        _final += "/* KDAPP ENDS */"

-        @saveCompiledApp app, final
-        @defineApp app, final
+        @saveCompiledApp app, _final
+        @defineApp app, _final

     unless KodingAppsController.apps[name]
       @fetchApps (apps)=> kallback apps[name]


app logic WIP

app logic WIP

--- client/landing/app/MainApp/kodingappscontroller.coffee
+++ client/landing/app/MainApp/kodingappscontroller.coffee
@@ -36,3 +36,96 @@
               KodingAppsController.apps["#{app.name}-#{app.version}"] = app
             log KodingAppsController.apps
             callback? KodingAppsController.apps
+
+  addScript:(scriptInput, callback)->
+
+    log scriptInput, ">>>>>"
+
+    if /^\.\//.test scriptInput
+      @getSingleton("kiteController").run
+        withArgs  :
+          command : "cat /Users/sinan/Applications/Ace.kdapp/src/#{scriptInput}"
+      , (err, response)=>
+        if err then warn err
+        callback err, "#{response}"
+    else
+      callback null, "#{scriptInput}"
+
+  saveCompiledApp:(script)->
+
+    log FSHelper.escapeFilePath "/Users/sinan/Applications/Ace.kdapp/index.js"
+
+    @getSingleton("kiteController").run
+      toDo        : "uploadFile"
+      withArgs    : {
+        path      : FSHelper.escapeFilePath "/Users/sinan/Applications/Ace.kdapp/index.js"
+        contents  : script
+      }
+    , (err, response)=>
+      if err then warn err
+      log err, response, "<<<<<<"
+
+  compileSource:(name)->
+
+    kallback = (app)=>
+
+      return warn "No such app!" unless app
+
+      {source} = app
+      {blocks} = source
+
+      orderedBlocks = []
+      for blockName, blockOptions of blocks
+        blockOptions.name = blockName
+        if blockOptions.order? and not isNaN(order = parseInt(blockOptions.order, 10))
+          orderedBlocks[order] = blockOptions
+        else
+          orderedBlocks.push blockOptions
+
+      blockStrings = []
+
+      asyncStack   = []
+
+      orderedBlocks.forEach (block)=>
+        # log block.pre  if block.pre
+        if block.pre
+          asyncStack.push (callback)=> @addScript block.pre, callback
+
+        # log ">>>>>>> processing block named #{block.name} <<<<<<<<"
+        if block.files
+          {files} = block
+          files.forEach (file, index)=>
+            if "object" is typeof file
+              for fileName, fileExtras of file
+                do =>
+                  # log fileExtras.pre  if fileExtras.pre
+                  if fileExtras.pre
+                    asyncStack.push (callback)=> @addScript fileExtras.pre, callback
+                  # log fileName
+                  asyncStack.push (callback)=> @addScript fileName, callback
+                  # log fileExtras.post if fileExtras.post
+                  if fileExtras.post
+                    asyncStack.push (callback)=> @addScript fileExtras.post, callback
+            else
+              # log file
+              asyncStack.push (callback)=> @addScript file, callback
+        # log block.post if block.post
+        if block.post
+          asyncStack.push (callback)=>
+            @addScript block.post, callback
+
+      async.parallel asyncStack, (error, result)=>
+
+        final = ""
+        result.forEach (output)=>
+          final += "#{output}"
+          final += "\n\n/*-------------------------------------------------------*/\n\n"
+
+        @saveCompiledApp final
+
+
+
+    unless KodingAppsController.apps[name]
+      @fetchApps (apps)=> kallback apps[name]
+    else
+      kallback KodingAppsController.apps[name]


Landing: home fixed default bg image order bug

--- client/landing/site.landing/coffee/home/AppView.coffee
+++ client/landing/site.landing/coffee/home/AppView.coffee
@@ -189,7 +189,7 @@

       [slide, dot]

-    INDEX = KD.utils.getRandomNumber(COLORS.length - 1)
+    INDEX = KD.utils.getRandomNumber(COLORS.length) - 1
     @changeColor()

     @once 'viewAppended', ->


Remove dead code

Remove dead code

--- components/simple_contact/views/contact_partner.coffee
+++ components/simple_contact/views/contact_partner.coffee
@@ -1,19 +0,0 @@
-ContactView = require './index.coffee'
-ArtworkInquiry = require '../../../models/artwork_inquiry.coffee'
-template = -> require('../templates/contact_partner.jade') arguments...
-
-module.exports = class ContactPartnerView extends ContactView
-  successMessage: 'Thank you. Your inquiry has been sent.'
-
-  template: ->
-    template arguments...
-
-  initialize: ({ @artwork }) ->
-    @model = new ArtworkInquiry
-
-  render: ->
-    @$el.html @template
-      user: @user
-      artwork: @artwork
-      partner: @artwork.related().partner
-    this


support python source

support python source

--- lib/middleware/static.coffee
+++ lib/middleware/static.coffee
@@ -16,6 +16,7 @@
   return 'markdown' if path.match /\.(:?markdown|md)$/
   return 'rst' if path.match /\.rst$/
   return 'javascript' if path.match /\.js$/
+  return 'python' if path.match /\.py$/
   return

@@ -75,6 +76,10 @@
         data = html.escape data
         data = html.tag 'code', data.toString(), {'data-language': 'javascript'}
         data = html.tag 'pre', data
+      when 'python'
+        data = html.escape data
+        data = html.tag 'code', data.toString(), {'data-language': 'python'}
+        data = html.tag 'pre', data
       else
         data = html.tag 'pre', html.escape(data)


Remove `lib/models/git-commit.coffee`

Remove `lib/models/git-commit.coffee`

--- lib/models/git-commit.coffee
+++ lib/models/git-commit.coffee
@@ -1,164 +0,0 @@
-{CompositeDisposable} = require 'atom'
-fs = require 'fs-plus'
-Path = require 'flavored-path'
-os = require 'os'
-
-git = require '../git'
-notifier = require '../notifier'
-GitPush = require './git-push'
-
-module.exports =
-class GitCommit
-  # Public: Helper method to return the current working directory.
-  #
-  # Returns: The cwd as a String.
-  dir: ->
-    # path is different for submodules
-    if @submodule ?= git.getSubmodule()
-      @submodule.getWorkingDirectory()
-    else
-      @repo.getWorkingDirectory()
-
-  # Public: Helper method to join @dir() and filename to use it with fs.
-  #
-  # Returns: The full path to our COMMIT_EDITMSG file as {String}
-  filePath: -> Path.join(@repo.getPath(), 'COMMIT_EDITMSG')
-
-  constructor: (@repo, {@amend, @andPush, @stageChanges}={}) ->
-    @currentPane = atom.workspace.getActivePane()
-    @disposables = new CompositeDisposable
-
-    # Check if we are amending right now.
-    @amend ?= ''
-    @isAmending = @amend.length > 0
-
-    # Load the commentchar from git config, defaults to '#'
-    @commentchar = '#'
-    git.cmd(['config', '--get', 'core.commentchar'])
-    .then (data) =>
-      # unless data.trim?() is ''
-      if data
-        @commentchar = data.trim()
-    .then =>
-      if @stageChanges
-        git.add(@repo, update: true)
-        .then => @getStagedFiles()
-      else
-        @getStagedFiles()
-
-  getStagedFiles: ->
-    git.stagedFiles(@repo)
-    .then (files) =>
-      if not @isAmending or files.length >= 1
-        git.cmd(['status'], cwd: @repo.getWorkingDirectory())
-      else
-        Promise.reject "Nothing to commit."
-    .then (status) => @prepFile status
-    .catch (error) =>
-      @cleanup()
-      notifier.addInfo error
-
-  # Public: Prepares our commit message file by writing the status and a
-  #         possible amend message to it.
-  #
-  # status - The current status as {String}.
-  prepFile: (status) ->
-    # format the status to be ignored in the commit message
-    status = status.replace(/\s*\(.*\)\n/g, "\n")
-    status = status.trim().replace(/\n/g, "\n#{@commentchar} ")
-    @getTemplate().then (template) =>
-      fs.writeFileSync @filePath(),
-        """#{ if @amend.length > 0 then @amend else template}
-        #{@commentchar} Please enter the commit message for your changes. Lines starting
-        #{@commentchar} with '#{@commentchar}' will be ignored, and an empty message aborts the commit.
-        #{@commentchar}
-        #{@commentchar} #{status}"""
-      @showFile()
-
-  getTemplate: ->
-    git.cmd(['config', '--get', 'commit.template'])
-    .then (data) =>
-      if data then fs.readFileSync(Path.get(data.trim())) else ''
-
-  # Public: Helper method to open the commit message file and to subscribe the
-  #         'saved' and `destroyed` events of the underlaying text-buffer.
-  showFile: ->
-    atom.workspace
-      .open(@filePath(), searchAllPanes: true)
-      .done (textEditor) =>
-        if atom.config.get('git-plus.openInPane')
-          @splitPane(atom.config.get('git-plus.splitPane'), textEditor)
-        else
-          @disposables.add textEditor.onDidSave => @commit()
-          @disposables.add textEditor.onDidDestroy =>
-            if @isAmending then @undoAmend() else @cleanup()
-
-  splitPane: (splitDir, oldEditor) ->
-    pane = atom.workspace.paneForURI(@filePath())
-    options = { copyActiveItem: true }
-    hookEvents = (textEditor) =>
-      oldEditor.destroy()
-      @disposables.add textEditor.onDidSave => @commit()
-      @disposables.add textEditor.onDidDestroy =>
-        if @isAmending then @undoAmend() else @cleanup()
-
-    directions =
-      left: =>
-        pane = pane.splitLeft options
-        hookEvents(pane.getActiveEditor())
-      right: ->
-        pane = pane.splitRight options
-        hookEvents(pane.getActiveEditor())
-      up: ->
-        pane = pane.splitUp options
-        hookEvents(pane.getActiveEditor())
-      down: ->
-        pane = pane.splitDown options
-        hookEvents(pane.getActiveEditor())
-    directions[splitDir]()
-
-  # Public: When the user is done editing the commit message an saves the file
-  #         this method gets invoked and commits the changes.
-  commit: ->
-    args = ['commit', '--cleanup=strip', "--file=#{@filePath()}"]
-    git.cmd(args, cwd: @dir())
-    .then (data) =>
-      notifier.addSuccess data
-      @destroyCommitEditor()
-      if @andPush
-        new GitPush(@repo)
-      git.refresh()
-
-  destroyCommitEditor: ->
-    @cleanup()
-    atom.workspace.getPanes().some (pane) ->
-      pane.getItems().some (paneItem) ->
-        if paneItem?.getURI?()?.includes 'COMMIT_EDITMSG'
-          if pane.getItems().length is 1
-            pane.destroy()
-          else
-            paneItem.destroy()
-          return true
-
-  # Public: Undo the amend
-  #
-  # err - The error message as {String}.
-  undoAmend: (err='') ->
-    git.cmd
-      args: ['reset', 'ORIG_HEAD'],
-      stdout: ->
-        notifier.addError "#{err}: Commit amend aborted!"
-      stderr: ->
-        notifier.addError 'ERROR! Undoing the amend failed! Please fix your repository manually!'
-      exit: =>
-        # Set @isAmending to false since the amending process has been aborted.
-        @isAmending = false
-
-        # Destroying the active EditorView will trigger our cleanup method.
-        @destroyCommitEditor()
-
-  # Public: Cleans up after the EditorView gets destroyed.
-  cleanup: ->
-    @currentPane.activate() if @currentPane.alive
-    @disposables.dispose()
-    try fs.unlinkSync @filePath()


top processes

top processes

--- lib/plugins/processes.coffee
+++ lib/plugins/processes.coffee
@@ -17,7 +17,7 @@
         mem: parseFloat mem
         vsz: parseInt vsz
         rss: parseInt rss
-        tty: (if tty is '?' then null else tty)
+        tty: tty unless tty is '?'
         stat: stat
         start: start
         time: time
@@ -33,4 +33,5 @@

   all: (done) -> runPs "aux", done
   mine: (done) -> runPs "ux", done
-  grep: (done, text) -> runPs "aux | grep #{text}", done+  grep: (done, text) -> runPs "aux | grep #{text}", done
+  top: (done, num=10) -> runPs "aux | sort -nr -k 3 -k 4 | head -#{num+1}", done


Fixing problem of reopening the chart with the same name.

--- lib/proto-repl-charts.coffee
+++ lib/proto-repl-charts.coffee
@@ -69,6 +69,7 @@
       console.log("Unexpected data: " + data)

   activate: (state) ->
+    window.protoReplCharts = this
     @registerExtension()

     @subscriptions = new CompositeDisposable
@@ -80,9 +81,6 @@
       pane = atom.workspace.paneForItem(item)
       @handleActivePaneItemChanged(pane, item)

-
-    # TODO if you close a chart view and then rerun the code then it doesn't reopen it.
-    # no exception occurs
     atom.workspace.onDidDestroyPaneItem (event)=>
       item = event.item
       pane = event.pane
@@ -103,10 +101,11 @@

       return unless protocol == PROTOCOL

+      name = pathname.substr(1)
       if host == "chart"
-        new ChartView(pathname)
+        new ChartView(name)
       else if host == "table"
-        new TableView(pathname)
+        new TableView(name)
       else
         console.log("Unexpected host #{host} in #{uriToOpen}")


s/res/response/

s/res/response/

--- lib/resource-combiner.coffee
+++ lib/resource-combiner.coffee
@@ -47,15 +47,15 @@
         resourceRequest.get(
           content.href,
           req,
-          (err, res) ->
+          (err, response) ->
             if err
               console.log "Unable to load combined resource #{content.href}", err
               content.data = ''
               content.complete = true
             else
-              res.on 'data', (chunk) ->
+              response.on 'data', (chunk) ->
                 chunks.push chunk
-              res.on 'end', ->
+              response.on 'end', ->
                 content.data = chunks.join('') + (separator ? '')
                 content.complete = true
                 checkComplete resource


External resource definition for resource-combiner (Handled via redis)

--- lib/resource-combiner.coffee
+++ lib/resource-combiner.coffee
@@ -8,6 +8,43 @@

 idResourceCache = {}
 pathResourceCache = {}
+
+HREF_PREFIX = 'href_'
+HREF_PREFIX_LEN = HREF_PREFIX.length
+
+externalResourceCache =
+  store: ({path, prefix, separator, contentType, root, hrefs}) ->
+    separator = separator ? ''
+    root = root ? ''
+    info = {
+      path
+      prefix
+      separator
+      contentType
+      root
+    }
+
+    # Flatten the array into hash components
+    for i in [0...hrefs.length]
+      info[HREF_PREFIX + i] = hrefs[i]
+
+    client?.hmset path, info
+  load: (path, callback) ->
+    client?.hgetall path, (err, obj) ->
+      if err or not obj.path
+        console.error "Failed to retrieve #{path} from redis instance", err
+        callback()
+      else
+        resource = {
+          root: {}
+          resources: []
+        }
+        for key, value of obj
+          if key.indexOf(HREF_PREFIX) == 0
+            resource.resources[parseInt key.substring HREF_PREFIX_LEN] = { href: value }
+          else
+            resource[key] = value
+        callback resource

 checkComplete = (resource) ->
   # Determine if there are any incomplete operations
@@ -64,6 +101,16 @@
                 checkComplete resource
         )

+  # Let the world know
+  externalResourceCache.store {
+    path
+    prefix
+    separator
+    contentType
+    root: root.url
+    hrefs: (item.href for item in resources)
+  }
+
   contentPath + path

 exports.middleware = (options) ->
@@ -106,7 +153,16 @@
       path = req.url.substring contentPath.length
       resource = pathResourceCache[path]
       if not resource
-        next()
+        externalResourceCache.load path, (resource) ->
+          if not resource
+            return next()
+
+          # Init the new object
+          resource.req = req
+          exports.combine resource
+
+          # Start wait for build to complete then serve it up
+          checkDeferred pathResourceCache[path]
       else
         checkDeferred resource
     else