changes the form controller to support both new and edit

--- app/assets/javascripts/controllers/expense_report_form_controller.js.coffee
+++ app/assets/javascripts/controllers/expense_report_form_controller.js.coffee
@@ -1,15 +1,20 @@
 @ExpenseReportFormController = ($scope, $routeParams, ExpenseReport, Expense, $location, flashService) ->

-  $scope.newExpenseReport = new ExpenseReport
-    userId: $routeParams.user_id
-    status: "open"
+  if $routeParams.id
+    ExpenseReport.get($routeParams.id).then (report) ->
+      $scope.expenseReport = report
+  else
+    $scope.expenseReport = new ExpenseReport
+      userId: $routeParams.user_id
+      status: "open"
+    $scope.expenseReport.addPerDiemExpense()

   $scope.addExpense = ->
-    $scope.newExpenseReport.addExpense()
+    $scope.expenseReport.addExpense()

-  $scope.updateRate = (expense) ->
+  $scope.updateRates = ->
     $scope.showSpinner()
-    $scope.newExpenseReport.updateRate(expense, $scope.hideSpinner)
+    $scope.expenseReport.updateRates($scope.hideSpinner)

   $scope.showSpinner = ->
     $("body").spin()
@@ -25,15 +30,21 @@
       onUnblock: ->
         $("body").spin(false)

-  $scope.$watch("newExpenseReport.endTime - newExpenseReport.startTime", ->
-    $scope.newExpenseReport.updatePerDiemExpense()
-    for exp in $scope.newExpenseReport.expenses
-      $scope.updateRate(exp) if $scope.newExpenseReport.endTime and $scope.newExpenseReport.startTime
+  $scope.$watch("expenseReport", (before, after) ->
+
+    #if before and after
+    #  $scope.expenseReport.updatePerDiemExpense()
+    #  $scope.updateRates()
   )

+  $scope.dateChanged = (newDate, oldDate) ->
+    $scope.expenseReport.updatePerDiemExpense()
+    $scope.updateRates()
+
+
   $scope.submitReport = ->
-    $scope.newExpenseReport.create().then ((expenseReport) ->
-      $scope.newExpenseReport = ""
+    $scope.expenseReport.create().then ((expenseReport) ->
+      $scope.expenseReport = ""
       flashService.flash("success", "Expense report created")
       $location.path("/users/#{expenseReport.userId}/expense_reports")
     ), (error) ->


Fixing binding in update_canvas_rect function.

--- engine/myou.coffee
+++ engine/myou.coffee
@@ -21,6 +21,7 @@
         @all_anim_objects= []
         @root = @canvas = canvas = root
         @MYOU_PARAMS = MYOU_PARAMS
+        @hash = Math.random()
         # The root element needs to be positioned, so the mouse events (layerX/Y) are
         # registered correctly, and the canvas is scaled inside
         if getComputedStyle(root).position == 'static'
@@ -38,17 +39,13 @@
             MYOU_PARAMS.gl_options or {antialias: true, alpha: false}
         )

-        update_canvas_rect = =>
-            canvas.rect = @canvas_rect = canvas.getClientRects()[0]
-            @canvas_rect.update = update_canvas_rect
-            return

-        update_canvas_rect()
+        @update_canvas_rect()

-        resize_canvas = ->
+        resize_canvas = =>
             render_manager.resize canvas.clientWidth, canvas.clientHeight
-            update_canvas_rect()
+            @update_canvas_rect()

         window.addEventListener 'resize', resize_canvas

@@ -87,6 +84,10 @@
                 if s.length
                     window.requestAnimationFrame(=> @on_scene_ready(k))

+    update_canvas_rect:  =>
+        @canvas_rect = @canvas.getClientRects()[0]
+        @canvas.rect = @canvas_rect
+
 create_canvas = (root)->
     canvas = document.createElement 'canvas'
     if root?


add directive list gallerie

add directive list gallerie

--- app/scripts/controllers.coffee
+++ app/scripts/controllers.coffee
@@ -82,6 +82,7 @@
 .controller('ArtworkController', ($scope, $stateParams, $sce, Lightbox, Artworks, AmeRestangular,  Events) ->
   $scope.artwork = null
   $scope.events = []
+  $scope.galleries_types = ["teaser_galleries", "in_situ_galleries","mediation_galleries", "press_galleries", "process_galleries"]
   $scope.main_picture_gallery = {media: []}
   # ame gallery vars for gallery
   $scope.ame_artwork_gallery = {media: []}


disable serialport on close

disable serialport on close

--- app/scripts/robot/radio.coffee
+++ app/scripts/robot/radio.coffee
@@ -84,6 +84,7 @@
       close: ->
         if _init
           _ndl3Radio.close() if _ndl3Radio?
+          _serialPort.close() if _serialPort?
           _ndl3Radio = undefined
           _serialPort = undefined
           _portPath = ''


quest/add view: don't refetch realms on render, only on initialize

--- www/src/views/quest/add.coffee
+++ www/src/views/quest/add.coffee
@@ -9,6 +9,8 @@
     class extends Common
         template: _.template(html)

+        activated: false # look below for activate() override
+
         activeMenuItem: -> "new-quest"
         pageTitle: -> "New quest"

@@ -34,7 +36,7 @@
         initialize: ->
             super
             _.bindAll this
-            @render()
+            @activate()

         setRealmList: (realm) ->
             @$(".quest-add-realm-list ul li").removeClass("active")
@@ -161,11 +163,13 @@
             realms: sharedModels.realms.toJSON()
             selectedRealm: @getRealmId()

+        activate: ->
+            unless sharedModels.realms.length
+                sharedModels.realms.fetch().success => @activate()
+                return
+            super
+
         render: ->
-            unless sharedModels.realms.length
-                sharedModels.realms.fetch().success => @render()
-                return
-
             @initRealm()
             super
             @setRealmList @getRealmId()


slight simplification of the if-else grammar rules

--- grammar.coffee
+++ grammar.coffee
@@ -481,16 +481,11 @@
   # The most basic form of *if* is a condition and an action. The following
   # if-related rules are broken up along these lines in order to avoid
   # ambiguity.
-  IfStart: [
+  IfBlock: [
     o "IF Expression Block",                    -> new IfNode $2, $3
     o "UNLESS Expression Block",                -> new IfNode $2, $3, {invert: true}
-    o "IfStart ELSE IF Expression Block",       -> $1.addElse (new IfNode($4, $5)).forceStatement()
-  ]
-
-  # An **IfStart** can optionally be followed by an else block.
-  IfBlock: [
-    o "IfStart"
-    o "IfStart ELSE Block",                     -> $1.addElse $3
+    o "IfBlock ELSE IF Expression Block",       -> $1.addElse (new IfNode($4, $5)).forceStatement()
+    o "IfBlock ELSE Block",                     -> $1.addElse $3
   ]

   # The full complement of *if* expressions, including postfix one-liner


Fixing issue #676, chained accesses against the super() keyword.

--- grammar.coffee
+++ grammar.coffee
@@ -296,11 +296,9 @@
     o "{ ClassBody }",                          -> $2
   ]

-  # The three flavors of function call: normal, object instantiation with `new`,
-  # and calling `super()`
+  # The two flavors of function call: normal, and object instantiation with `new`.
   Call: [
     o "Invocation"
-    o "Super"
     o "NEW Invocation",                         -> $2.newInstance()
     o "NEW Value",                              -> (new CallNode($2, [])).newInstance()
   ]
@@ -315,6 +313,8 @@
   Invocation: [
     o "Value OptFuncExist Arguments",           -> new CallNode $1, $3, $2
     o "Invocation OptFuncExist Arguments",      -> new CallNode $1, $3, $2
+    o "SUPER",                                  -> new CallNode 'super', [new SplatNode(new LiteralNode('arguments'))]
+    o "SUPER Arguments",                        -> new CallNode 'super', $2
   ]

   # An optional existence check on a function.
@@ -327,12 +327,6 @@
   Arguments: [
     o "CALL_START CALL_END",                    -> []
     o "CALL_START ArgList OptComma CALL_END",   -> $2
-  ]
-
-  # Calling super.
-  Super: [
-    o "SUPER",                                  -> new CallNode 'super', [new SplatNode(new LiteralNode('arguments'))]
-    o "SUPER Arguments",                        -> new CallNode 'super', $2
   ]

   # A reference to the *this* current object.
@@ -584,6 +578,7 @@
 #     (2 + 3) * 4
 operators = [
   ["right",     '?', 'NEW']
+  ["left",      'CALL_START', 'CALL_END']
   ["nonassoc",  '++', '--']
   ["right",     'UNARY']
   ["left",      'MATH']


Add missing IDs to React form

Add missing IDs to React form

--- picoCTF-web/web/coffee/front-page.coffee
+++ picoCTF-web/web/coffee/front-page.coffee
@@ -38,15 +38,15 @@

           <Row>
             <Col md={6}>
-              <Input type="text" valueLink={@props.firstname} label="Firstname"/>
+              <Input type="text" id="first-name" valueLink={@props.firstname} label="Firstname"/>
             </Col>
             <Col md={6}>
-              <Input type="text" valueLink={@props.lastname} label="Lastname"/>
+              <Input type="text" id="last-name" valueLink={@props.lastname} label="Lastname"/>
             </Col>
           </Row>
           <Row>
             <Col md={12}>
-              <Input type="email" valueLink={@props.email} label="E-mail"/>
+              <Input type="email" id="email" valueLink={@props.email} label="E-mail"/>
             </Col>
           </Row>
           <ButtonInput type="submit">Register</ButtonInput>
@@ -62,7 +62,7 @@
                 Go back to Login.
               else
                 <Button type="submit">Login</Button>
-                <Button onClick={@props.setPage.bind null, "Register"}>Register</Button>
+                <Button id="set-register" onClick={@props.setPage.bind null, "Register"}>Register</Button>
               }
             </Col>
             <Col md={6}>


Update UI: Remove unique warnings of modal-area.

--- views/modal-area.cjsx
+++ views/modal-area.cjsx
@@ -32,7 +32,13 @@
           <Modal.Title>{@state.title}</Modal.Title>
         </Modal.Header>
         <Modal.Body>
-          {@state.body}
+          {
+            if @state.body instanceof Array
+              for body, i in @state.body
+
{body}

+            else
+              @state.body
+          }
         </Modal.Body>
         <Modal.Footer>
           {@state.footer}


renumber question when it is marked as first in grid

--- app/assets/javascripts/angular/controllers/grid_questions_ctrl.js.coffee
+++ app/assets/javascripts/angular/controllers/grid_questions_ctrl.js.coffee
@@ -30,6 +30,8 @@
   $scope.updateQuestion = (question) ->
     question.project_id = $scope.project_id
     question.instrument_id = $scope.instrument_id
+    if question.first_in_grid
+      question.number_in_instrument = $scope.questions[0].number_in_instrument
     question.$update({},
       (data, headers) -> $scope.getGridQuestions($scope.project_id, $scope.instrument_id, $scope.grid_id),
       (result, headers) -> $scope.saveQuestionFailure(result, headers)


fix chrome specific bug inserting a stray <meta> tag

--- app/assets/javascripts/ckeditor/plugins/effective_menus/plugin.js.coffee
+++ app/assets/javascripts/ckeditor/plugins/effective_menus/plugin.js.coffee
@@ -127,7 +127,7 @@
       node.parentsUntil(@menu, 'li.dropdown').addClass('open')

     cleanupAfterDrop: ->
-      @menu.find('li.effective-menu-expand').remove()
+      @menu.find('meta,li.effective-menu-expand').remove()

       # Convert empty dropdowns back to leafs
       @menu.find('.dropdown-menu:empty').each (index, item) ->


adding quad trees for collisions

adding quad trees for collisions

--- src/quad_tree.coffee
+++ src/quad_tree.coffee
@@ -1,5 +1,5 @@
 (
-  window.QuadTree(I) ->
+  window.QuadTree = (I) ->
     I ||= {}

     $.reverseMerge I,


better variable names

better variable names

--- src/quad_tree.coffee
+++ src/quad_tree.coffee
@@ -1,5 +1,4 @@
 ((window) ->
-
   QuadTree = (I) ->
     I ||= {}

@@ -58,9 +57,8 @@

       index = TOP_LEFT

-      if left
-        if !top
-          index = BOTTOM_LEFT
+      if left && !top
+        index = BOTTOM_LEFT
       else
         if top
           index = TOP_RIGHT
@@ -104,47 +102,49 @@
         return I.children

       subdivide: ->
-        depth = I.depth + 1
+        increased_depth = I.depth + 1

-        b_x = I.bounds.x
-        b_y = I.bounds.y
+        x_bounds = I.bounds.x
+        y_bounds = I.bounds.y
+        width = I.bounds.width
+        height = I.bounds.height

-        b_w_h = (I.bounds.width / 2).floor()
-        b_h_h = (I.bounds.height / 2).floor()
-        bx_b_w_h = b_x + b_w_h
-        by_b_h_h = b_y + b_h_h
+        half_width = (width / 2).floor()
+        half_height = (height / 2).floor()
+        x_midpoint = x_bounds + half_width
+        y_midpoint = y_bounds + half_height

         I.nodes[TOP_LEFT] = Node
           bounds:
-            x: b_x
-            y: b_y
-            width: b_w_h
-            height: b_h_h
-          depth: depth
+            x: x_bounds
+            y: y_bounds
+            width: half_width
+            height: half_height
+          depth: increased_depth

         I.nodes[TOP_RIGHT] = Node
           bounds:
-            x: bx_b_w_h
-            y: b_y
-            width: b_w_h
-            height: b_h_h
-          depth: depth
+            x: x_midpoint
+            y: y_bounds
+            width: half_width
+            height: half_height
+          depth: increased_depth

         I.nodes[BOTTOM_LEFT] = Node
           bounds:
-            x: b_x
-            y: by_b_h_h
-            width: b_w_h
-            height: b_h_h
-          depth: depth
+            x: x_bounds
+            y: y_midpoint
+            width: half_width
+            height: half_height
+          depth: increased_depth

         I.nodes[BOTTOM_RIGHT] = Node
           bounds:
-            x: bx_b_w_h
-            y: by_b_h_h
-            width: b_w_h
-            height: b_h_h
-          depth: depth
+            x: x_midpoint
+            y: y_midpoint
+            width: half_width
+            height: half_height
+          depth: increased_depth

     self


Facade for jQuery compatibility

Facade for jQuery compatibility

--- src/quo.style.coffee
+++ src/quo.style.coffee
@@ -32,6 +32,8 @@
         else
             this[0].style[property] or _computedStyle(this[0], property)

+    $$.fn.css = (property, value) -> @style property, value
+
     $$.fn.vendor = (property, value) ->
         @style("#{vendor}#{property}", value) for vendor in VENDORS


fix redeemInvitation function

fix redeemInvitation function

--- workers/social/lib/social/models/user/index.coffee
+++ workers/social/lib/social/models/user/index.coffee
@@ -568,10 +568,10 @@

     return invitation.accept account, callback  if invitation

-    JInvitation.one { email, groupName : slug }, (err, invitation) ->
+    JInvitation.one { email, groupName : slug }, (err, invitation_) ->
       # if we got error or invitation doesnt exist, just return
-      return callback null if err or not invitation
-      return invitation.accept account, callback
+      return callback null if err or not invitation_
+      return invitation_.accept account, callback

   # check if user's email domain is in allowed domains


Update email in tracking identifier

Update email in tracking identifier

--- workers/social/lib/social/models/user/index.coffee
+++ workers/social/lib/social/models/user/index.coffee
@@ -1892,6 +1892,8 @@

             callback null

+            Tracker.identify @username, { email }
+

   fetchHomepageView: (options, callback) ->


activity: increase timeout to 20000 secs

--- client/landing/app/Applications/Activity.kdapplication/AppController.coffee
+++ client/landing/app/Applications/Activity.kdapplication/AppController.coffee
@@ -381,6 +381,7 @@
       KD.utils.getTimedOutCallbackOne
         name      : "populateActivity",
         onTimeout : @bound 'recover'
+        timeout   : 20000

   recover:->
     @isLoading = no


ActivityAppController: Put back accidentally removed code.

--- client/landing/app/Applications/Activity.kdapplication/AppController.coffee
+++ client/landing/app/Applications/Activity.kdapplication/AppController.coffee
@@ -52,6 +52,8 @@
     @status = KD.getSingleton "status"
     @status.on "reconnected", (conn)=>
       if conn?.reason is "internetDownForLongTime" then @refresh()
+
+    @on "activitiesCouldntBeFetched", => @listController?.hideLazyLoader()

   loadView:->
     @getView().feedWrapper.ready (controller)=>


remove senthil's duplicate activity debugging code

--- client/landing/app/Applications/Activity.kdapplication/AppController.coffee
+++ client/landing/app/Applications/Activity.kdapplication/AppController.coffee
@@ -207,33 +207,17 @@

     unless isLoading
       if @listController.itemsOrdered.last
-
-        # DEBUG: duplicate entries in activity feed
         lastItemData = @listController.itemsOrdered.last.getData()
-        lastDate = @getTimeFromItem(lastItemData)
-        lastId = lastItemData._id
-
-        firstItemData = @listController.itemsOrdered.first.getData()
-        firstDate = @getTimeFromItem(firstItemData)
-        firstId = firstItemData._id
-
-        timeStamps =
-          top:
-            date:firstDate
-            id:lastId
-          bottom:
-            date:lastDate
-            id:lastId
-          correct:firstDate>lastDate
-
-        _rollbar.push(msg:"duplicate entries debug", timeStamps:timeStamps, level:"debug")
-        # DEBUG: duplicate entries in activity feed
+        # memberbucket data has no serverside model it comes from cache
+        # so it has no meta, that's why we check its date by its overview
+        lastDate = if lastItemData.createdAtTimestamps
+          new Date lastItemData.createdAtTimestamps.first
+        else
+          new Date lastItemData.meta.createdAt
       else
         lastDate = new Date
-        _rollbar.push(msg:"could not find date", date:lastDate)

       lastTimeStamp = lastDate.getTime()
-
       @populateActivity {slug : "before/#{lastTimeStamp}", to: lastTimeStamp}

   teasersLoaded:->


minor

minor

--- client/landing/app/MainApp/filetree/modals/openwith/openwithmodal.coffee
+++ client/landing/app/MainApp/filetree/modals/openwith/openwithmodal.coffee
@@ -48,13 +48,11 @@
       modal.addSubView new OpenWithModalItem { delegate: modal }, manifest

     label = new KDLabelView
-      title        : "Always open with..."
-      attributes   :
-        "for"      : "alwaysOpenWith"
+      title : "Always open with..."

     @alwaysOpenWith = new KDInputView
-      type         : "checkbox"
-      domId        : "alwaysOpenWith"
+      label : label
+      type  : "checkbox"

     modal.buttonHolder.addSubView @alwaysOpenWith
     modal.buttonHolder.addSubView label


Easier to read gruntfile

Easier to read gruntfile

--- app/templates/Gruntfile.coffee
+++ app/templates/Gruntfile.coffee
@@ -24,23 +24,40 @@

       styles:
         files: '<%%= config.app %>/styles/{,*/}*.scss'
-        tasks: [ 'compass', 'autoprefixer' ]<% } %><% if ( stylesLang === 'less') { %>
+        tasks: [
+          'compass'
+          'autoprefixer'
+        ]<% } %><% if ( stylesLang === 'less') { %>

       styles:
         files: '<%%= config.app %>/styles/{,*/}*.less'
-        tasks: [ 'less', 'autoprefixer' ]<% } %><% if ( stylesLang === 'vanilla') { %>
+        tasks: [
+          'less'
+          'autoprefixer'
+        ]<% } %><% if ( stylesLang === 'vanilla') { %>

       styles:
         files: [ '<%%= config.app %>/styles/{,*/}*.css' ]
-        tasks: [ 'copy:styles', 'autoprefixer' ]<% } %><% if ( scriptsLang === 'coffeescript') { %>
+        tasks: [
+          'copy:styles'
+          'autoprefixer'
+        ]<% } %><% if ( scriptsLang === 'coffeescript') { %>

       scripts:
         files: [ '<%%= config.app %>/scripts/{,*/}*.coffee' ]
-        tasks: [ 'coffeelint', 'coffee:jitter', 'replace:scripts' ]<% } %><% if ( scriptsLang === 'javascript') { %>
+        tasks: [
+          'coffeelint'
+          'coffee:jitter'
+          'replace:scripts'
+        ]<% } %><% if ( scriptsLang === 'javascript') { %>

       scripts:
         files: [ '<%%= config.app %>/scripts/{,*/}*.js' ]
-        tasks: [ 'jshint', 'copy:scripts', 'replace:scripts' ]<% } %>
+        tasks: [
+          'jshint'
+          'copy:scripts'
+          'replace:scripts'
+        ]<% } %>

       pages:
         files: [ '<%%= config.app %>/{,*/}*.html' ]
@@ -102,7 +119,7 @@
       imports:
         files:
           '<%%= config.temp %>/scripts/imports-global.js': [
-            '<%%= config.bower %>/jquery/jquery.js',
+            '<%%= config.bower %>/jquery/jquery.js'
             '<%%= config.bower %>/modernizr/modernizr.js'
           ]

@@ -140,7 +157,7 @@
     replace:
       options:
         patterns: [
-          match: 'VERSION',
+          match: 'VERSION'
           replacement: '<%%= pkg.version %>'
         ,
           match: 'DATE'
@@ -210,8 +227,14 @@

     bump:
       options:
-        files: [ 'package.json', 'bower.json' ]
-        commitFiles: [ 'package.json', 'bower.json' ]
+        files: [
+          'package.json'
+          'bower.json'
+        ]
+        commitFiles: [
+          'package.json'
+          'bower.json'
+        ]
         pushTo: 'origin'

     connect:
@@ -233,23 +256,59 @@
           livereload: false

     concurrent:
-      lint:     [ <% if ( scriptsLang === 'coffeescript') { %>'coffeelint'<% } %><% if ( scriptsLang === 'javascript') { %>'jshint'<% } %> ]
-      compile:  [ <% if ( stylesLang === 'sass') { %>'compass', <% } %><% if ( stylesLang === 'less') { %>'less', <% } %><% if ( stylesLang === 'vanilla') { %>'copy:styles', <% } %><% if ( scriptsLang === 'coffeescript') { %>'coffee',<% } %><% if ( scriptsLang === 'javascript') { %>'copy:scripts',<% } %> 'concat' ]
-      post:     [ 'autoprefixer', 'replace' ]
-      minify:   [ 'cssmin', 'uglify', 'htmlmin' ]
-
-  grunt.registerTask 'build', [ 'concurrent:compile', 'concurrent:post' ]
+      lint: [ <% if ( scriptsLang === 'coffeescript') { %>
+        'coffeelint'<% } %><% if ( scriptsLang === 'javascript') { %>
+        'jshint'<% } %>
+      ]
+      compile: [ <% if ( stylesLang === 'sass') { %>
+        'compass'<% } %><% if ( stylesLang === 'less') { %>
+        'less'<% } %><% if ( stylesLang === 'vanilla') { %>
+        'copy:styles'<% } %><% if ( scriptsLang === 'coffeescript') { %>
+        'coffee'<% } %><% if ( scriptsLang === 'javascript') { %>
+        'copy:scripts'<% } %>
+        'concat'
+      ]
+      post: [
+        'autoprefixer'
+        'replace'
+      ]
+      minify: [
+        'cssmin'
+        'uglify'
+        'htmlmin'
+      ]
+
+  grunt.registerTask 'build', [
+    'concurrent:compile'
+    'concurrent:post'
+  ]

   grunt.registerTask 'serve', 'Serve a local copy', ( target ) ->
     if grunt.option 'allow-remote'
       grunt.config.set 'connect.options.hostname', '0.0.0.0'

     if target is undefined
-      grunt.task.run [ 'default', 'connect:livereload', 'watch' ]
+      grunt.task.run [
+        'default'
+        'connect:livereload'
+        'watch'
+      ]

     else if target is 'dist'
-      grunt.task.run [ 'dist', 'connect:dist' ]
-
-  grunt.registerTask 'dist', [ 'clean:dist', 'default', 'concurrent:minify', 'copy:images' ]
-
-  grunt.registerTask 'default', [ 'clean:server', 'concurrent:lint', 'build' ]
+      grunt.task.run [
+        'dist'
+        'connect:dist'
+      ]
+
+  grunt.registerTask 'dist', [
+    'clean:dist'
+    'default'
+    'concurrent:minify'
+    'copy:images'
+  ]
+
+  grunt.registerTask 'default', [
+    'clean:server'
+    'concurrent:lint'
+    'build'
+  ]


Klient: use custom proxy based on the environment

--- client/Main/kite/kites/klient.coffee
+++ client/Main/kite/kites/klient.coffee
@@ -43,9 +43,14 @@
     #           or
     #      http://localhost:8090/-/userproxy/54.164.243.111/kite

-    {hostname, protocol, port} = document.location
+    proxy = {
+      dev        : 'devproxy'
+      production : 'prodproxy'
+      sandbox    : 'sandboxproxy'
+    }[KD.config.environment] or 'devproxy'

-    changedUrl = "#{protocol}//#{hostname}#{if port then ":#{port}" else ""}/-/userproxy/#{parser.hostname}/kite"
+    {protocol} = document.location
+    changedUrl = "#{protocol}//proxy.koding.com/-/#{proxy}/#{parser.hostname}/kite"

     @transport.options.url = changedUrl


fix the workfow visualization

fix the workfow visualization

--- app/pages/lab/workflow-viewer/workflow.cjsx
+++ app/pages/lab/workflow-viewer/workflow.cjsx
@@ -1,6 +1,6 @@
 React = require 'react'
 ReactDOM = require 'react-dom'
-{StartEndNode} = require './task.cjsx'
+{Task, StartEndNode} = require './task.cjsx'

 DETACHABLE = false


Fixed missing Match.OneOf

Fixed missing Match.OneOf

Fixes #16

--- lib/behaviours.coffee
+++ lib/behaviours.coffee
@@ -124,7 +124,7 @@
     @configure.apply @, arguments

   configure: (nameOrObject, options) ->
-    check nameOrObject, Object, String
+    check nameOrObject, Match.OneOf Object, String
     check options, Match.Optional Object

     if Match.test nameOrObject, String


perf(web): uglify js

perf(web): uglify js

--- apps/actor-web/gulpfile.coffee
+++ apps/actor-web/gulpfile.coffee
@@ -47,6 +47,7 @@
     .pipe(buffer())
     .pipe(gulpif(!argv.production, sourcemaps.init({loadMaps: true})))
     .pipe(gulpif(!argv.production, sourcemaps.write('./')))
+    .pipe(gulpif(argv.production, uglify()))
     .pipe(gulp.dest('./dist/assets/js'))
     .pipe(connect.reload())


render app before module initialization finishes

--- app/app.coffee
+++ app/app.coffee
@@ -76,10 +76,14 @@
       if @props.footer
         React.DOM.div {className: 'modal-footer'}, @props.footer

+initializationPromise = null
 AppComponent = React.createClass
   displayName: 'AppComponent'
   getInitialState: ->
+    initializationPromise.finally =>
+      @setState initializationState: initializationPromise.inspect()
     modal: null
+    initializationState: initializationPromise.inspect()
   mixins: [Router.Navigation]
   componentWillMount: ->
     modalModel.onValue (modals) =>
@@ -89,10 +93,13 @@
     appComponent = @

     modal = @state.modal
-    if @props.bodyWrapper
-      body = @props.bodyWrapper null, @props.activeRouteHandler()
+    # TODO warn on initialization failure
+    if @state.initializationState.state == 'pending'
+      body = null
     else
       body = @props.activeRouteHandler()
+    if @props.bodyWrapper
+      body = @props.bodyWrapper null, body
     React.DOM.div {className: 'lead'},
       React.DOM.div {className: 'nav-bar'},
         Router.Link {to: 'notebook', className: 'title'}, 'lead'
@@ -273,9 +280,10 @@
       Router.NotFoundRoute {handler: NotFoundComponent}

   # TODO handle errors, timeouts
-  Modules.init_modules(module_names).finally ->
-    React.renderComponent routesComponent, target
-  .done()
+  initializationPromise = Modules.init_modules(module_names)
+
+  React.renderComponent routesComponent, target
+  initializationPromise.done()

 exports.raw_cell_url = (value) ->
   # TODO don't require appComponent


[client][app][mainapp] changed notify message

--- client/app/MainApp/KD.extend.coffee
+++ client/app/MainApp/KD.extend.coffee
@@ -35,6 +35,7 @@
             if groupName and KD.isLoggedIn()
               @joinGroup_ groupName, (res)=>
                 unless res then return @notify_ "Joining to #{groupName} group failed", "error"
+                @notify_ "You have joined to #{groupName} group!", "success"
                 KD.lastFuncCall?()
                 KD.lastFuncCall = null
         KD.lastFuncCall = callback
@@ -59,7 +60,7 @@
             return callback true
         currentGroup.join (err)=>
           if err then return callback false
-          @notify_ "Joined to #{groupName} group!", "success"
+          @notify_ "You have joined to #{groupName} group!", "success"
           return callback true

   jsonhTest:->


removed "undefined" from animal html table reporting

--- client/coffee/animalEvidence.coffee
+++ client/coffee/animalEvidence.coffee
@@ -70,21 +70,24 @@
         txt = ""
         val = share.getAnimalEndpointIncidents(@endpointGroups)
         if val isnt ""
-            txt = "
#{val}	#{@incidence_significance}
"
+            sig = @incidence_significance or ""
+            txt = "
#{val}	#{sig}
"
         return txt

     getMultiplicities: () ->
         txt = ""
         val = share.getAnimalEndpointMultiplicities(@endpointGroups)
         if val isnt ""
-            txt = "
#{val}	#{@multiplicity_significance}
"
+            sig = @multiplicity_significance or ""
+            txt = "
#{val}	#{sig}
"
         return txt

     getTotalTumours: () ->
         txt = ""
         val = share.getAnimalTotalTumours(@endpointGroups)
         if val isnt ""
-            txt = "
#{val}	#{@total_tumours_significance}
"
+            sig = @total_tumours_significance or ""
+            txt = "
#{val}	#{sig}
"
         return txt


Added message that submit list is reloaded automatically

--- client/components/SubmitList.coffee
+++ client/components/SubmitList.coffee
@@ -95,6 +95,7 @@
                 <OpenSubmit submit={@state.openSubmit} close={@closeSubmit}/>
             }

Попытки

+
Не обновляйте страницу; список посылок обновляется автоматически.

             {
             if @dataOutdated()
                 <CometSpinLoader />


remove skus association

remove skus association

--- client/skr/models/SalesOrder.coffee
+++ client/skr/models/SalesOrder.coffee
@@ -46,10 +46,10 @@
         terms:            { model: "PaymentTerm"  }
         billing_address:  { model: "Address"      }
         shipping_address: { model: "Address"      }
-        skus:             { collection: "Sku"     }
-        invoices:         { collection: "Invoice" }
-        lines:            { collection: "SoLine", fk: 'sales_order_id' }
-        pick_tickets:     { collection: "PickTicket" }
+
+        invoices:         { collection: "Invoice",    inverse: 'sales_order' }
+        lines:            { collection: "SoLine",     inverse: 'sales_order', fk: 'sales_order_id',  }
+        pick_tickets:     { collection: "PickTicket", inverse: 'sales_order' }

     constructor: ->
         super


removing useless console output

removing useless console output

That was probably a test for theme structure, anyways, it’s useless and
should not have been committed in the first place

--- opinionated_theme/default/opinionated/assets/javascripts/opinionated/application.coffee
+++ opinionated_theme/default/opinionated/assets/javascripts/opinionated/application.coffee
@@ -1,5 +1,2 @@
 #= require jquery
-#= require_self
-
-$(document).ready ->
-  console?.log 'ready...'+#= require_self


add docs and hook function in extensions interface

--- lib/extensions.coffee
+++ lib/extensions.coffee
@@ -1,49 +1,41 @@
 _ = require 'lodash'
+
+###*
+ * @class Extensions
+ * @classdesc  Responsable for managing roots extensions
+###

 class Extensions

   constructor: (@roots) ->
     @all = []

+  ###*
+   * register a roots extension with your project
+   * @param  {Object} ext       - extension object/instance
+   * @param  {Integer} priority - optional, how early the extension is run
+  ###
+
   register: (ext, priority) ->
     if typeof priority == undefined then return @all.push(ext)
     @all.splice(priority, 0, ext)
+
+  ###*
+   * return a given extension's hook, if it exists
+   * @param  {String} name - hook name, separated with periods
+   * @return {Function}      the hook function if exists, otherwise undefined
+  ###
+
+  hooks: (name) ->
+    name = name.split('.')
+    @all.filter((e) -> if e[name[0]] then e[name[0]][name[1]])
+
+  ###*
+   * remove an extension
+   * @param  {String} name - name of the extension you'd like to remove
+  ###

   remove: (name) ->
     _.remove(@all, ((i) -> i.name == name))

 module.exports = Extensions
-
-###
-
-Roots Extensions
-----------------
-
-The roots extension API is an extremely powerful managed set of hooks into
-roots' internals that allow external packages to customize roots' behavior.
-This class is responsible for the management of extensions in a roots project.
-
-Extensions can expose hooks that link into a 4 different spots in the roots
-compile pipeline, detailed more thoroughly below.
-
-## FS Parse Hooks
-
-The first step in the roots compile pipeline is parsing the project directory and categorizing files. By default, roots splits all files into two categories: compiled and copied. By hooking into the fs parser, an extension can filter files into its own category. FS parse hooks can come in three pieces:
-
-- detection function & category name
-- extract or pass through
-- detect before or after the default (compile/copy) categories
-
-## Compile Order Hook
-
-After parsing the project, roots takes each category and runs the files through the compiler. In this hook, you can choose whether you need for your category to be compiled before or after the default compile tasks. For example, the dynamic content extension requires that dynamic content files be compiled before normal content so that the dynamic content can be available in the locals. If no before/after is chosen, it will be compiled in parallel with the other tasks.
-
-## Compile Hooks
-
-You might want to also jump directly into the compile process, and these two hooks make this possible. The roots compiler first grabs a list of compilers that need to be used to compile the file, and the options that need to be passed into the compiler. Next, roots goes through the list and compiles the file once for each compiler, passing the content of the previous compiler on to the next pass. You can activate hooks right before and right after this compile has finished. In the before hook, you can add, remove, or swap compile adapters, or options before the compile goes off, and in the after hook, you can modify the compiled content before passing it to be written, or prevent the write.
-
-## Category Hooks
-
-As mentioned above, by hooking into the fs parser, you are able to sort files into your own category. Sometimes you want to be able to have a hook when a specified category has finished compiling all of its files. An extension that precompiles files and writes all the contents to a single `templates` file would want to store the contents, then write them all once that category is finished compiling through. Thats what this hook is for.
-
-###


Don't go into parameter territory for parsing function name.


small change so strings are highlighted properly within a list

--- grammars/lisp.cson
+++ grammars/lisp.cson
@@ -252,7 +252,7 @@
         captures:
           "1":
             name: "punctuation.section.quoted.symbol.common-lisp"
-        match: "(')\\s*([[:alpha:]][[:alnum:]!$%&*+-./:<=>?@^_~]*)"
+        match: "(')\\s*([0-9a-zA-Z!$%&*+-./:<=>?@^_~]*)"
         name: "constant.symbol.common-lisp"
       }
       {
@@ -271,7 +271,7 @@
       }
       {
         coment: "This is for quoted lists: '(foo bar baz)"
-        begin: "('\\s*\\()"
+        begin: "\\b('\\s*\\()"
         beginCaptures:
           "1":
             name: "punctuation.section.quoted.common-lisp"
@@ -381,10 +381,13 @@
             include: "#comment"
           }
           {
+            include: "#string"
+          }
+          {
+            include: "#quote"
+          }
+          {
             include: "#sexp"
-          }
-          {
-            include: "#quote"
           }
           {
             include: "#illegal"


changed some ting

changed some ting

--- graphs/test.coffee
+++ graphs/test.coffee
@@ -1,7 +0,0 @@
-noflo = require 'noflo'
-
-exports.getComponent = ->
-  g = new noflo.Graph 'Test'
-
-  # Finally return the component instance
-  g


:lipstick: Cleanup.

:lipstick: Cleanup.

- Remove the last deprecation for statusBar.

--- lib/jumpy-view.coffee
+++ lib/jumpy-view.coffee
@@ -3,7 +3,6 @@
 # Currently shadow dom mode works!

 # MAJOR Before 2.0
-# TODO: Status bar code
 # TODO: Beacon code
 # TODO: Merge in @willdady's code for better accuracy.
 # TODO: Investigate using markers (if time permitting)
@@ -53,8 +52,9 @@

         @workspaceElement = atom.views.getView(atom.workspace)
         @statusBar = document.querySelector 'status-bar'
-        @statusBar?.prependLeft(
-            '

')
+        @statusBar?.addLeftTile
+            item: $('

')
+            priority: -1
         @statusBarJumpy = document.getElementById 'status-bar-jumpy'

     getKey: (character) ->


:art: Cleanup

:art: Cleanup

- Decided these console.logs.  They are not really useful anymore. They
  also break the output of `apm test`.
- Fix fat arrows.

--- lib/jumpy-view.coffee
+++ lib/jumpy-view.coffee
@@ -71,7 +71,7 @@

         isMatchOfCurrentLabels = (character, labelPosition) =>
             found = false
-            @disposables.add atom.workspace.observeTextEditors (editor) ->
+            @disposables.add atom.workspace.observeTextEditors (editor) =>
                 editorView = atom.views.getView(editor)
                 return if $(editorView).is ':not(:visible)'

@@ -114,7 +114,7 @@

     reset: ->
         @clearKeys()
-        @disposables.add atom.workspace.observeTextEditors (editor) ->
+        @disposables.add atom.workspace.observeTextEditors (editor) =>
             editorView = atom.views.getView(editor)
             overlayer = @getOverlayer editorView
             $(overlayer).find '.irrelevant'
@@ -238,9 +238,8 @@
     jump: ->
         location = @findLocation()
         if location == null
-            console.log "Jumpy canceled jump.  No location found."
             return
-        @disposables.add atom.workspace.observeTextEditors (currentEditor) =>
+        @disposables.add atom.workspace.observeTextEditors (currentEditor) ->
             editorView = atom.views.getView(currentEditor)

             # Prevent other editors from jumping cursors as well
@@ -267,8 +266,6 @@
                     setTimeout ->
                         cursor.classList.remove 'beacon'
                     , 150
-            console.log "Jumpy jumped to: #{@firstChar}#{@secondChar} at " +
-                "(#{location.position.row},#{location.position.column})"

     findLocation: ->
         label = "#{@firstChar}#{@secondChar}"
@@ -282,6 +279,5 @@

     # Tear down any state and detach
     destroy: ->
-        console.log 'Jumpy: "destroy" called.'
         @commands?.dispose()
         @clearJumpMode()


Force le succes de la tache make

Force le succes de la tache make

--- grunt/shell.coffee
+++ grunt/shell.coffee
@@ -18,5 +18,6 @@
 		options:
 			stdout: true
 			stderr: true
+			failOnError: false
 			execOptions:
 				cwd: 'server/'


Write JSONP test

Write JSONP test

--- integration_test/cobalt.coffee
+++ integration_test/cobalt.coffee
@@ -135,8 +135,31 @@
     it 'I can see an index page for subdirectories'
     it 'I can follow my own symlinks'
     it 'I cannot follow naughty symlinks'
-    describe 'as JSONP', ->
-      it 'the JSONP thing works'
+
+    describe 'When I specify a callback parameter', (done) ->
+      resp = null
+      body = null
+      before (done) ->
+        scp_cmd "./integration_test/fixtures/scraperwiki-database.json", "http/test.json", ->
+          options =
+            uri: "http://#{host}/#{boxname}/http/test.json"
+            qs:
+              callback: "cb_test"
+          request.get options, (err, response, body) ->
+            should.not.exist err
+            resp = response
+            done()
+
+      it 'returns the expected JSON wrapped in the expected callback', ->
+        expected = JSON.parse fs.readFileSync "./integration_test/fixtures/scraperwiki-database.json", 'ascii'
+        cb_test = (json) -> return json
+        a = JSON.stringify(eval resp.body)
+        b = JSON.stringify(expected)
+        a.should.equal(b)
+        resp.should.have.status 200
+
+      it 'does not return JSONP if the requested file is not JSON'
+
     describe 'as JSON', ->
       it 'the CORS headers are still present'


no less in dist, was messing up min build

--- webpack.config.coffee
+++ webpack.config.coffee
@@ -8,7 +8,8 @@
           filename: 'main.js'
       }, {isProduction, excludeExternals: true}]
     'main.min': [{
-        entry: ['./index', './resources/styles/main.less']
+        entry:
+          main: './index'
         output:
           filename: 'main.min.js'
       }, {isProduction, excludeExternals: true, minify: true}]


this didn't work on mac for some reason

this didn't work on mac for some reason

--- lib/misc/paths.coffee
+++ lib/misc/paths.coffee
@@ -3,7 +3,7 @@
 path =  require 'path'
 fs =    require 'fs'

-{selector} = require '../ui'
+selector = require '../ui/selector'

 module.exports =


Improved highlighting of function names.

--- grammars/dart.cson
+++ grammars/dart.cson
@@ -165,8 +165,10 @@
         'name': 'support.class.dart'
       }
       {
-        'match': '(_?[a-z][a-zA-Z]+)(?=\\\(\\\[)'
-        'name': 'entity.name.function.dart'
+        'match': '(_?[a-z][a-zA-Z0-9]+)\\('
+        'captures':
+          '1':
+            'name': 'entity.name.function.dart'
       }
       {
         'match': '\\b[A-Z_0-9]+\\b'


Add "ldots" and "dollar" as GNU Eqn keywords

--- grammars/roff.cson
+++ grammars/roff.cson
@@ -2227,10 +2227,11 @@
 		},{

 			# GNU Eqn: Character names
-			name: "constant.language.greek-letter.eqn.gnu.roff"
+			name: "constant.language.eqn.gnu.roff"
 			match: """(?x)\\b
 				(Alpha|Beta|Chi|Delta|Epsilon|Eta|Gamma|Iota|Kappa|Lambda|Mu|Nu
-				|Omega|Omicron|Phi|Pi|Psi|Rho|Sigma|Tau|Theta|Upsilon|Xi|Zeta)\\b"""
+				|Omega|Omicron|Phi|Pi|Psi|Rho|Sigma|Tau|Theta|Upsilon|Xi|Zeta
+				|ldots|dollar)\\b"""
 		},{

 			# GNU Eqn: Set MathML variables


Adds source files to watch task for test

--- grunt/watch.coffee
+++ grunt/watch.coffee
@@ -1,5 +1,5 @@
 module.exports = (grunt) ->
   grunt.config 'watch',
     tests:
-      files: 'test/unit/**/*.coffee'
+      files: ['test/unit/**/*.coffee', 'src/lib/**/*.coffee']
       tasks: 'mochaTest'


add a styleguide page for the swipe

add a styleguide page for the swipe

--- app/assets/javascripts/styleguide.js.coffee
+++ app/assets/javascripts/styleguide.js.coffee
@@ -22,10 +22,10 @@
     'lib/utils/feature_detect'
   ], (SelectGroupManager, ScrollPerf, ToggleActive, Konami, Swipe) ->

-    new ScrollPerf
+    new ScrollPerf()
     new SelectGroupManager()
     new ToggleActive()
-    new Swipe
+    new Swipe()
     d = new Date()
     $('.input--datepicker').pickadate({
       min: [d.getFullYear(), (d.getMonth() + 1), d.getDate()]


changed dayShift method

changed dayShift method

--- app/coffee/drm-calendar/drm-calendar.coffee
+++ app/coffee/drm-calendar/drm-calendar.coffee
@@ -133,7 +133,7 @@
             numberDays = self.getDaysInMonth (month + 1), year
             prevMonthNumberDays = self.getDaysInMonth month, year
             firstDay = self.getDayOfWeek month, year, 1
-            dayShift = if firstDay is 7 then 0 else daysPerWeek + (firstDay - daysPerWeek)
+            dayShift = if firstDay is 7 then 0 else firstDay
             numberWeeks = Math.ceil (numberDays + dayShift) / 7

             # console.log "Days Per Week: #{daysPerWeek}"


If condition on one line

If condition on one line

--- src/server/common/AuthService.coffee
+++ src/server/common/AuthService.coffee
@@ -24,10 +24,9 @@
 server.exchange oauth2.exchange.code (client, code, redirectURI, done) ->
 	db.authorizationCodes.find code, (err, authCode) ->
 		if err then return done err
-		if authCode is undefined
-			db.accessTokens.deleteByAuthCode authCode, (err) ->
-				if err then return done err
-				else return done null, false
+		if !authCode then	db.accessTokens.deleteByAuthCode authCode, (err) ->
+			if err then return done err
+			else return done null, false
 		if client.id isnt authCode.clientID then return done null, false
 		if redirectURI isnt authCode.redirectURI then return done null, false
 		db.authorizationCodes.delete code, (err) ->


plot resizing alsu use offset in width

plot resizing alsu use offset in width

--- bokehjs/src/coffee/models/plots/plot.coffee
+++ bokehjs/src/coffee/models/plots/plot.coffee
@@ -589,13 +589,13 @@
   _resize_width_height: (use_width, use_height, maintain_ar, avail_width, avail_height) =>
     min_size = @mget('min_size')

-    # We need some extra space in height to account for padding and toolbar.
-    # This seems not to be needed in width.
-    height_offset = 20  # What we need to avoid scrolling, accounts for padding around canvas
-    if @model.toolbar_location == 'above'
-      height_offset += 30
-    if @model.toolbar_location == 'below'
-      height_offset += 80  # need this space to avoid scrolling, this could be a layout bug
+    # We need some extra space to account for padding and toolbar. Otherwise we get scrollbars.
+    # Note that during resizing, the canvas may be too large, causing scrollbars to briefly show.
+    width_offset = height_offset = 20
+    if @model.toolbar_location == 'above' then height_offset += 30
+    if @model.toolbar_location == 'below' then height_offset += 80  # bug in layout?
+    if @model.toolbar_location in ['left', 'right'] then width_offset += 30
+    avail_width -= width_offset
     avail_height -= height_offset

     if maintain_ar is false


code cleaning

code cleaning

--- app/controllers/mailboxes_controller.coffee
+++ app/controllers/mailboxes_controller.coffee
@@ -12,7 +12,7 @@

 # shared functionnality : find the mailbox via its ID
 before ->
-    Mailbox.find req.params.id, (err, box) =>
+    Mailbox.find params.id, (err, box) =>
         if err
             send 500
         else if not box


Fixed: the package sleep was not used anymore

--- app/controllers/reminders_controller.coffee
+++ app/controllers/reminders_controller.coffee
@@ -5,8 +5,6 @@
 compliant with the standard.

 ###
-
-sleep = require 'sleep'

 before ->
     VTodo.find req.params.id, (err, vtodo) =>


Remove duplicate check for subscriber info

--- lib/subscriber.coffee
+++ lib/subscriber.coffee
@@ -129,12 +129,6 @@
                         num = parseInt(value)
                         @info[key] = if num + '' is value then num else value
                     cb(@info)
-                else if @info?.updated? # subscriber exists
-                    # transform numeric value to number type
-                    for own key, value of @info
-                        num = parseInt(value)
-                        @info[key] = if num + '' is value then num else value
-                    cb(@info)
                 else
                     cb(@info = null) # null if subscriber doesn't exist + flush cache


Update demos to have one that creates a large table

--- lib/table-edit.coffee
+++ lib/table-edit.coffee
@@ -31,34 +31,56 @@
     TableView.registerViewProvider(true)

     atom.commands.add 'atom-workspace',
-      'table-edit:demo-in-pane': => @openDemoInPane()
+      'table-edit:demo-basic-table': => @openDemoInPane()
+      'table-edit:demo-large-table': => @openLargeDemoInPane()

-    atom.workspace.addOpener (uriToOpen) ->
+    atom.workspace.addOpener (uriToOpen) =>
       url ||= require 'url'

       {protocol, host} = url.parse uriToOpen
       return unless protocol is 'table:'

-      table = new Table
-
-      table.addColumn 'key'
-      table.addColumn 'value', align: 'right'
-      table.addColumn 'foo', align: 'right'
-
-      for i in [0...1000]
-        table.addRow [
-          "row#{i}"
-          Math.random() * 100
-          if i % 2 is 0 then 'yes' else 'no'
-        ]
-
-      table.clearUndoStack()
-
-      return table
+      switch host
+        when 'demo' then @getBasicTableDemo()
+        when 'large-demo' then @getLargeTableDemo()

   deactivate: ->

   serialize: ->

-  openDemoInPane: ->
-    atom.workspace.open('table://demo')
+  openDemoInPane: -> atom.workspace.open('table://demo')
+
+  openLargeDemoInPane: -> atom.workspace.open('table://large-demo')
+
+  getBasicTableDemo: ->
+    table = new Table
+
+    table.addColumn 'key'
+    table.addColumn 'value', align: 'right'
+    table.addColumn 'foo', align: 'right'
+
+    for i in [0...1000]
+      table.addRow [
+        "row#{i}"
+        Math.random() * 100
+        if i % 2 is 0 then 'yes' else 'no'
+      ]
+
+    table.clearUndoStack()
+
+    return table
+
+  getLargeTableDemo: ->
+    table = new Table
+
+    for n in [0..50]
+      table.addColumn("column #{n + 1}")
+
+    for r in [0..1000]
+      rowData = []
+      for c in [0..50]
+        rowData.push "cell #{r}-#{c} data"
+
+      table.addRow(rowData)
+
+    return table


Change the name of method.

Change the name of method.

--- lib/tag_search.coffee
+++ lib/tag_search.coffee
@@ -18,13 +18,13 @@
         info = new TagSearchAtom browser.window.document.innerHTML
         @callback(info)

-  uri : -> @host() + @path() + '?' + @param()
+  uri : -> @host() + @path() + '?' + @query_param()

   host : -> 'http://www.nicovideo.jp/'

   path : -> "tag/#{@search_string}"

-  param : ->
+  query_param : ->
     param = []
     param.push page_param()
     param.push sort_param() if sort_param()?


Check recurse flag before verifying path is directory

Avoid an unnecessary native call if recursing into the current
path has already been avoided.

--- src/stdlib/fs.coffee
+++ src/stdlib/fs.coffee
@@ -109,7 +109,7 @@
     for path in @list(rootPath)
       recurse = true
       fn(path, prune)
-      @traverseTree(path, fn) if @isDirectory(path) and recurse
+      @traverseTree(path, fn) if recurse and @isDirectory(path)

   lastModified: (path) ->
     $native.lastModified(path)


Store help dialog injected strings together, inject all at once

--- background_scripts/main.coffee
+++ background_scripts/main.coffee
@@ -144,13 +144,18 @@
     command = Commands.keyToCommandRegistry[key].command
     commandsToKey[command] = (commandsToKey[command] || []).concat(key)

+  replacementStrings =
+    version: currentVersion
+    title: customTitle || "Help"
+
+  for group of Commands.commandGroups
+    replacementStrings[group] =
+        helpDialogHtmlForCommandGroup(group, commandsToKey, Commands.availableCommands,
+                                      showUnboundCommands, showCommandNames)
+
   dialogHtml = fetchFileContents("pages/help_dialog.html")
-  for group of Commands.commandGroups
-    dialogHtml = dialogHtml.replace("{{#{group}}}",
-        helpDialogHtmlForCommandGroup(group, commandsToKey, Commands.availableCommands,
-                                      showUnboundCommands, showCommandNames))
-  dialogHtml = dialogHtml.replace("{{version}}", currentVersion)
-  dialogHtml = dialogHtml.replace("{{title}}", customTitle || "Help")
+  for placeholder, replacementString of replacementStrings
+    dialogHtml = dialogHtml.replace "{{#{placeholder}}}", replacementString
   dialogHtml

 #


Updated to allow for adding array of elements to tag input.

--- src/tag_input.coffee
+++ src/tag_input.coffee
@@ -9,36 +9,42 @@
 ## - mac-tag-input-placeholder: placeholder text for tag input
 ## - mac-tag-input-no-result:   custom text when there is no search result
 ##
-##

 angular.module("Mac").directive "macTagInput", [
   "$rootScope",
   "$parse",
   ($rootScope, $parse) ->
-    restrict:   "A"
-    scope:      {}
+    restrict: "A"
+    scope:    {}

     compile: (element, attr) ->
-      tagsList    = attr.macTagInput            or []
-      selectedExp = attr.macTagInputSelected
-      placeholder = attr.macTagInputPlaceholder or ""
-      noResult    = attr.macTagInputNoResult
-      options     = {}
-      getSelected = $parse selectedExp
+      tagsListName = attr.macTagInput
+      selectedExp  = attr.macTagInputSelected
+      placeholder  = attr.macTagInputPlaceholder or ""
+      noResult     = attr.macTagInputNoResult
+      options      = {}
+      getSelected  = $parse selectedExp

       element.attr "data-placeholder", placeholder

-      for tag in tagsList
-        element.append $("<option>").attr("value", tag).text tag
-
       options.no_results_text = noResult if noResult?

+      # initialize the element in compile
+      # as initializing in link will break other directives
       chosenElement = element.chosen(options)

       ($scope, element, attr) ->
         Object.defineProperty $scope, "selected",
           get:        -> getSelected $scope.$parent
           set: (list) -> getSelected.assign $scope.$parent, list
+
+        # Get an array from the parent scope
+        tagsList = $scope.$parent[tagsListName] or []
+        for tag in tagsList
+          element.append $("<option>").attr("value", tag).text tag
+
+        # Update tag input after adding new option DOM element
+        chosenElement.trigger "liszt:updated"

         chosenElement.change (event, object)->
           $scope.$apply ->


do not send retain 0

do not send retain 0

--- lib/y-richtext.coffee
+++ lib/y-richtext.coffee
@@ -194,7 +194,10 @@
     @_model.getContent("characters").observe (events) => @locker.try ()=>
       for event in events
         delta =
-          ops: [{retain: event.position}]
+          ops: []
+
+        if event.position > 0
+          delta.ops.push {retain: event.position}

         if event.type is "insert"
           delta.ops.push {insert: event.value}


Revert "Revert test changes for proxied headers when requesting pdfs from clsi"

This reverts commit ab31d2c3fdc00a38f6444248011a3871b83dbec2.

--- services/web/test/UnitTests/coffee/Compile/CompileControllerTests.coffee
+++ services/web/test/UnitTests/coffee/Compile/CompileControllerTests.coffee
@@ -137,7 +137,12 @@
 				statusCode: 204
 				headers: { "mock": "header" }
 			@req.method = "mock-method"
-
+			@req.headers = {
+				'Mock': 'Headers',
+				'Range': 'should be passed - Range'
+				'If-Range': 'should be passed - If-Range'
+				'If-Modified-Since': 'should be passed - If-Modified-Since'
+			}

 		describe "user with standard priority", ->

@@ -152,6 +157,11 @@
 						method: @req.method
 						url: "#{@settings.apis.clsi.url}#{@url}",
 						timeout: 60 * 1000
+						headers: {
+							'Range': 'should be passed - Range'
+							'If-Range': 'should be passed - If-Range'
+							'If-Modified-Since': 'should be passed - If-Modified-Since'
+						}
 					)
 					.should.equal true

@@ -175,6 +185,11 @@
 						method: @req.method
 						url: "#{@settings.apis.clsi_priority.url}#{@url}",
 						timeout: 60 * 1000
+						headers: {
+							'Range': 'should be passed - Range'
+							'If-Range': 'should be passed - If-Range'
+							'If-Modified-Since': 'should be passed - If-Modified-Since'
+						}
 					)
 					.should.equal true


Refactoring and added a hook to clear cache

--- src/typhoon/articleController.coffee
+++ src/typhoon/articleController.coffee
@@ -16,6 +16,9 @@
   # Default paging to 10
   configs.perPage ?= 10

+  # Default rebuild secret
+  configs.rebuildSecret ?= 'typhoon'
+
   # Setup base url and data paths
   Article.baseUrl configs.baseUrl
   exports.cache.build configs.articlesDir, configs.encoding || "utf8"
@@ -29,7 +32,7 @@
   articleView = new View '/article.haml', configs.encoding || "utf8"
   listView = new View '/list.haml', configs.encoding || "utf8"

-  # Setup article listing route
+  # Article listing
   return (app) ->
     app.get /^(?:(?:\/([0-9]{4})(?:\/([0-9]{2})(?:\/([0-9]{2}))?)?)?)(?:\/?page\/([0-9]+))?\/?$/, (req, res, next) ->
       locals =
@@ -61,7 +64,7 @@
         listView.render res, locals, (err) ->
           if err then throw new Error 500

-    # Setup article viewing route
+    # View article
     app.get /^(\/([0-9]{4})\/([0-9]{2})\/([0-9]{2})\/(.*)\/?)$/, (req, res, next) ->
       exports.cache.ready () ->
         article = exports.cache.getArticle req.params[0]
@@ -73,7 +76,7 @@
         articleView.render res, locals, (err) ->
           if err then throw new Error 500

-    # Setup RSS feed route
+    # RSS feed
     app.get '/feed.xml', (req, res, next) ->
       exports.cache.ready ->
         articles = []
@@ -107,14 +110,20 @@
         res.writeHead 200, 'content-type': 'text/xml'
         res.end haml.render(feed, options)

+    # Rebuild cache
+    app.get '/cache-rebuild/' + configs.rebuildSecret, (req, res, next) ->
+      exports.cache.build configs.articlesDir, configs.encoding || "utf8"
+      res.writeHead 200, 'content-type': 'text/html'
+      res.end 'OK'
+
 ###
 Cache object used by the controller
 ###

 class Cache
-  @building = false
   @cache = null
-  @lastBuild = new Date()
+  @lastBuildArticlesDir = null
+  @lastBuildEncoding = null

   getListing: (page = 1, perPage = 10, startDate = null, endDate = null) ->
     if !@ready() then return []
@@ -139,7 +148,6 @@
   constructor: ->
     @readyEmitter = new events.EventEmitter()
     @readyEmitter.once 'ready', () -> true # temp. fix for node issue #792
-    @readyEmitter.emit 'ready'
     @readyEmitter.setMaxListeners 0

   build: (articlesDir, encoding) ->
@@ -155,10 +163,12 @@
           articleFile = articlesDir + '/' + file
           Article.fromFile articleFile, encoding, (err, article) ->
             if !err
-              permalink = article.permalink true
-              cache.articles[permalink] = article
-              cache.listing.push permalink: permalink, date: article.date()
-            loadNext()
+              fs.stat articleFile, (err, stats) ->
+                if !err
+                  permalink = article.permalink true
+                  cache.articles[permalink] = article
+                  cache.listing.push permalink: permalink, date: article.date()
+                loadNext()
         else
           cache.listing.sort (a, b) ->
             if a.date < b.date
@@ -168,7 +178,6 @@
             else
               0
           that.cache = cache
-          that.lastBuild = new Date()
           that.readyEmitter.emit 'ready'
       loadNext()


LinkShell: skinny arrow for module level functions

--- coffee/src/shells/link.shell.coffee
+++ coffee/src/shells/link.shell.coffee
@@ -37,7 +37,7 @@
   # A LinkShell module matches a link whenever it conforms to
   # one or more  the patterns in that modules's top-level
   # `validLinkPatterns` array property.
-  matchingShells: (link) =>
+  matchingShells: (link) ->
     unless link?
       return LinkShell

@@ -61,7 +61,7 @@
   # From the set of shells returned by matchingShells(),
   # this function returns the most specific one in the
   # inheritence hierarchy.
-  bestMatchingShell: (link) =>
+  bestMatchingShell: (link) ->
     # obtain set of matching shells
     matchingShells = LinkShell.matchingShells(link)


fix: add rowHeight

fix: add rowHeight

--- src/views/labels/LabelRowView.coffee
+++ src/views/labels/LabelRowView.coffee
@@ -11,7 +11,7 @@
     @listenTo @g.vis,"change:labels", @drawR
     @listenTo @g.vis,"change:metacell", @drawR
     @listenTo @g.zoomer, "change:rowHeight", ->
-      @el.style.height = @g.zoomer.get "rowHeight"
+      @el.style.height = @g.zoomer.get("rowHeight") + "px"

   draw: ->
     @removeViews()
@@ -29,5 +29,5 @@
     @renderSubviews()

     @el.setAttribute "class", "biojs_msa_labelrow"
-    @el.style.height = @g.zoomer.get "rowHeight"
+    @el.style.height = @g.zoomer.get("rowHeight") + "px"
     @


shortcuts/modal: set restore button class

--- client/app/lib/shortcuts/views/modal.coffee
+++ client/app/lib/shortcuts/views/modal.coffee
@@ -24,7 +24,7 @@
       buttons:
         restore:
           title    : 'Restore Defaults'
-          style    : 'solid light-gray medium'
+          style    : 'solid light-gray medium restore'
           loader   : color: '#444444'
           #callback : -> modal.destroy()


Fix for rendering server errors in new Form mixin

--- client/source/views/base/mixins/form.coffee
+++ client/source/views/base/mixins/form.coffee
@@ -19,10 +19,10 @@
     promise.always(
       @$btn.ladda 'stop'
     ).fail(
-      @renderServerErrors
+      _.bind(@renderServerErrors, @)
     )

-  renderServerErrors: (res) =>
+  renderServerErrors: (res) ->

     # First let's get rid of the old ones
     @$('.help-block').remove()


New utils changed support

New utils changed support

--- file/render.coffee
+++ file/render.coffee
@@ -67,7 +67,8 @@
 				break

 		if proceed
-			utils.defProp clone, '_watchedFile', 'cw', null
+			desc = utils.ENUMERABLE | utils.WRITABLE
+			utils.defineProperty clone, '_watchedFile', desc, null

 			clone.updateStylesParent = @updateStylesParent.bind clone
 			clone.onReplacedByElem clone.updateStylesParent


stop only stoppable app

stop only stoppable app

--- config/initializers/socketio.coffee
+++ config/initializers/socketio.coffee
@@ -7,6 +7,17 @@
     app.errormsg = err.message
     app.save (saveErr) ->
         return send_error saveErr if saveErr
+
+stop_app = (app) ->
+    manager = new AppManager
+    manager.stop app, (err, result) =>
+        return mark_broken app, err if err
+        app.state = "stopped"
+        app.port = 0
+        app.save (err) =>
+            return send_error err if err
+            manager.resetProxy (err) =>
+                return mark_broken app, err if err

 applicationTimeout = []

@@ -53,13 +64,6 @@
                 Application.all (err, apps) ->
                     for app in apps
                         if app.name is name
-                            manager = new AppManager
-                            manager.stop app, (err, result) =>
-                                return mark_broken app, err if err
-                                app.state = "stopped"
-                                app.port = 0
-                                app.save (err) =>
-                                    return send_error err if err
-                                    manager.resetProxy (err) =>
-                                        return mark_broken app, err if err
+                            if app.isStoppable
+                                stop_app app
         , 15000


Minor change

Minor change

--- app/assets/javascripts/easy_app_bootstrap.js.coffee
+++ app/assets/javascripts/easy_app_bootstrap.js.coffee
@@ -35,15 +35,15 @@

 root.toggleBooleanIcon = (element) ->
   icon = $(element)
-  if icon.hasClass('fa-dot-circle-o')
-    icon.removeClass('fa-dot-circle-o')
+  if icon.hasClass('fa-times')
+    icon.removeClass('fa-times')
     icon.removeClass('fa-important')
     icon.addClass('fa-check')
     icon.addClass('fa-success')
   else
     icon.removeClass('fa-check')
     icon.removeClass('fa-success')
-    icon.addClass('fa-dot-circle-o')
+    icon.addClass('fa-times')
     icon.addClass('fa-important')


The place string ("4/11") now looks decent in all sizes

--- app/assets/javascripts/roofpig/DomHandler.js.coffee
+++ app/assets/javascripts/roofpig/DomHandler.js.coffee
@@ -1,7 +1,7 @@
 class @DomHandler

   constructor: (@display_id, @div, renderer) ->
-    @div.css(position:'relative')
+    @div.css(position:'relative', 'font-family':'"Lucida Sans Unicode", Lucida Grande, sans-serif')
     this.has_focus(false)
     @div.data('dpid', @display_id)

@@ -45,7 +45,7 @@
     @pause = this._make_button("||", "pause")
     @play  = this._make_button("▶",  "play")

-    @place = this._scale($("<div/>", { id: "place" }).css("text-align": 'right', 'float': 'right'))
+    @place = this._make_place_area()

     @buttons = [@reset, @prev, @next, @pause, @play]

@@ -63,4 +63,9 @@

   _scale: (button_area_element) ->
     @button_area.append(button_area_element)
-    button_area_element.height(40 * @scale).width(72 * @scale - 12).css("font-size", 32 * @scale)+    button_area_element.height(40 * @scale).width(72 * @scale - 12).css("font-size", 32 * @scale)
+
+  _make_place_area: ->
+    place_div = $("<div/>", { id: "place" }).css("text-align": 'right', 'float': 'right')
+    @button_area.append(place_div)
+    place_div.height(40 * @scale).width(80 * @scale).css("font-size", 24 * @scale)


fix(publish-nylas-build): return undefined to prevent grunt interpreting as failed build

--- build/tasks/publish-nylas-build-task.coffee
+++ build/tasks/publish-nylas-build-task.coffee
@@ -125,7 +125,7 @@
         uploadToS3(buildZipFilename, key).then(resolve).catch(reject)

   grunt.registerTask "publish-nylas-build", "Publish Nylas build", ->
-    return false if not shouldPublishBuild()
+    return unless shouldPublishBuild()

     awsKey = process.env.AWS_ACCESS_KEY_ID ? ""
     awsSecret = process.env.AWS_SECRET_ACCESS_KEY ? ""


Track computations from autoruns and ensure they're all stopped on publish stop

--- server.coffee
+++ server.coffee
@@ -162,10 +162,12 @@
       return

     handles = []
+    trackedComputations = []
     # This autorun is nothing special, just that it makes sure handles are stopped when publish stops,
     # and that you can return cursors from the function which would be automatically published.
     publish.autorun = (runFunc) ->
       handle = Tracker.autorun (computation) ->
+        trackedComputations.push computation
         result = runFunc.call publish, computation

         collectionNames = getCollectionNames result
@@ -194,6 +196,12 @@
       while handles.length
         handle = handles.shift()
         handle?.stop()
+      # Stop computations in case a subscription is stopped before ready on the client and
+      # the publish is using meteorhacks:unblock's "this.unblock()". Without this, observers
+      # created from cursors inside the autorun will exist forever.
+      while trackedComputations.length
+        computation = trackedComputations.shift()
+        computation?.stop()

     result = publishFunction.apply publish, args


variable name conflict

variable name conflict

--- server.coffee
+++ server.coffee
@@ -21,10 +21,10 @@

     if CHAT_OFF then return

-    url = "http://partychat-hooks.appspot.com/post/p_ngvimtvm?" + qs.stringify({ message }).replace(/\'/g, '%27')
+    chatURL = "http://partychat-hooks.appspot.com/post/p_ngvimtvm?" + qs.stringify({ message }).replace(/\'/g, '%27')

-    console.log "requesting #{url}"
-    request.get url, (err, response, body) ->
+    console.log "requesting #{chatURL}"
+    request.get chatURL, (err, response, body) ->
         if not err and response.statusCode is 200
             console.log "answer sent"
         else


Bug fix

Bug fix

--- server.coffee
+++ server.coffee
@@ -42,6 +42,7 @@

 console.info 'Compiling templates...'

+mkdirp.sync './#{templatesDir}'
 fs.writeFileSync "./#{templatesDir}/index.tpl.html", convert file: "#{preCompiledTemplatesDir}/index.tpl.html"

 # TODO: make this recursively support infinite depth


Hip, hip, array!

Hip, hip, array!

--- server.coffee
+++ server.coffee
@@ -201,8 +201,8 @@

             if rank
                 if self in [1..3]
-                    for i in [0..2]
-                        if results[self][1] is results[i][1]
+                    for i in [1..3]
+                        if results[self - 1][1] is results[i - 1][1]
                             diff = 0

                 if not diff?


Eventlist cleanup/fix

Eventlist cleanup/fix

--- server.coffee
+++ server.coffee
@@ -194,9 +194,10 @@
 		Db.shared.set 'game', 'teams', team.key(), 'neutralized', 0
 	updateTeamRankings()
 	Db.shared.set 'gameState', 1 # Set gameState at the end, because this triggers a repaint at the client so we want all data prepared before that
-	maxId = Db.shared.ref('game', 'eventlist').incr 'maxId'
-	Db.shared.set 'game', 'eventlist', maxId, 'timestamp', new Date()/1000
-	Db.shared.set 'game', 'eventlist', maxId, 'type', "start"
+	addEvent {
+		timestamp: new Date()/1000
+		type: "start"
+	}
 	Event.create
     	unit: 'startGame'
     	text: "The game has started!"
@@ -334,9 +335,10 @@
 		# End game and activate end game screen
 		Db.shared.set 'gameState', 2
 		log "[endGame()] The game ended! gameState: " + Db.shared.peek('gameState') + " args: " + args + " winningTeam: " + winningTeam + " Db: " + Db.shared.peek('game', 'firstTeam')
-		maxId = Db.shared.ref('game', 'eventlist').incr 'maxId'
-		Db.shared.set 'game', 'eventlist', maxId, 'timestamp', new Date()/1000
-		Db.shared.set 'game', 'eventlist', maxId, 'type', "end"
+		addEvent {
+			timestamp: new Date()/1000
+			type: "end"
+		}
 		# Pushbericht winnaar en verliezer
 		pushToTeam(winningTeam, "Congratulations! Your team won the game!")
 		pushToRest(winningTeam, "You lost the game!")
@@ -360,11 +362,12 @@
 	Timer.set global.pointsTime, 'overtimeScore', {beacon: beacon.key()}

 	# Add event log entrie(s)
-	maxId = Db.shared.ref('game', 'eventlist').incr 'maxId'
-	Db.shared.set 'game', 'eventlist', maxId, 'timestamp', new Date()/1000
-	Db.shared.set 'game', 'eventlist', maxId, 'type', "capture"
-	Db.shared.set 'game', 'eventlist', maxId, 'beacon', beacon.key()
-	Db.shared.set 'game', 'eventlist', maxId, 'conqueror', nextOwner
+	addEvent {
+		timestamp: new Date()/1000
+		type: "capture"
+		beacon: beacon.key()
+		conqueror: nextOwner
+	}

 	# The game will end in 1 hour if all the beacons are captured by one team
 	capOwner = Db.shared.peek('game', 'beacons', '0', 'owner')
@@ -617,16 +620,21 @@
 	# create score event
 	# To Do: personalize for team members or dubed players
 	if newLead
-		maxId = Db.shared.ref('game', 'eventlist').incr 'maxId'
-		Db.shared.set 'game', 'eventlist', maxId, 'timestamp', new Date()/1000
-		Db.shared.set 'game', 'eventlist', maxId, 'type', "score"
-		Db.shared.set 'game', 'eventlist', maxId, 'leading', teamMax
+		addEvent {
+			timestamp: new Date()/1000
+			type: "score"
+			leading: teamMax
+		}
 		Db.shared.set 'game', 'firstTeam', teamMax # store firstTeam for next new team calculation
 		pushToTeam(teamMax, "Your team took the lead!")
 		pushToRest(teamMax, "Team " + Db.shared.peek('colors', teamMax, 'name') + " took the lead!")
 	# Update rankings
 	updateTeamRankings()

+# Adds event to the eventlist
+addEvent = (eventArgs) ->
+	Db.shared.modify 'game', 'eventlist', 'maxId', (v) -> v + 1
+	Db.shared.set 'game', 'eventlist', Db.shared.peek('game', 'eventlist', 'maxId'), eventArgs

 # Sends a push notification, message, to all team members
 pushToTeam = (teamId, message) ->


Fixed you resource

Fixed you resource

--- server.coffee
+++ server.coffee
@@ -40,7 +40,7 @@
   subtitle = "- #{req.params.from}"
   dooutput(res, message, subtitle)

-app.get '/you/:name', (req, res) ->
+app.get '/you/:name/:from', (req, res) ->
   message = "Fuck you, #{req.params.name}."
   subtitle = "- #{req.params.from}"
   dooutput(res, message, subtitle)


Pending tests

Pending tests

--- test/collections/ordered_sets.coffee
+++ test/collections/ordered_sets.coffee
@@ -37,3 +37,8 @@
       @orderedSets.add [fabricate 'featured_link']
       @orderedSets.fetchSets()
       fetchSpy.calledTwice.should.be.ok
+
+  describe '#fetchAll', ->
+    it 'fetches everything all the way down'
+
+    it 'listens to sync:complete'


reseet current user when password is changed

--- server/controllers/authentication.coffee
+++ server/controllers/authentication.coffee
@@ -134,6 +134,7 @@
                             passwordKeys.resetKeys (err) ->
                                 if err? then next new Error err
                                 else
+                                    passport.currentUser = null
                                     res.send 204
                 else
                     error = new Error validationErrors


check for correct answer id before setting as correct or incorrect as well

--- src/components/breadcrumb/breadcrumb-mixin.cjsx
+++ src/components/breadcrumb/breadcrumb-mixin.cjsx
@@ -32,7 +32,7 @@
       bsStyle = 'primary'
       title ?= "Step Completed (#{crumbType}). Click to review"

-      if canReview
+      if canReview and step.correct_answer_id?
         if step.is_correct
           status = <i className='icon-lg icon-correct'></i>
           classes.push('status-correct')


rearranged lookupscache and identity authentication

--- lib/Context.coffee
+++ lib/Context.coffee
@@ -37,7 +37,7 @@

             @_status = []

-            @_hiddenKeys.push 'configure', 'boot', 'booting', 'booted', 'start', 'started', 'running', 'shutdown', 'stop', 'stopped', 'error', 'delegate', 'data', 'parent', 'children'
+            @_hiddenKeys.push 'data', 'parent', 'children', 'configure', 'boot', 'booting', 'booted', 'start', 'started', 'running', 'shutdown', 'stop', 'stopped', 'error', 'delegate'

         ##
@@ -46,28 +46,29 @@
         init: (config={}, done)->

             config = @configure config
+
+            @id = config.id
+
+            @ID = if !(@parent?.ID) then @id else @parent.ID+'.'+@id
+
+            @data = new floyd.data.SearchableMap config.data, @parent?.data
+
+            if typeof (@type = config.type) is 'function'
+                @type = @ID+'.'+(@type.name || 'DynContext')
+
+            @identity = @_createIdentity()
+
+            @logger = @_createLogger @ID
+
+            @_emitter = @_createEmitter config

             # --> EXPERIMENTAL identity based lookups cache -> nero

             if config.USELOOKUPSCACHE
                 USELOOKUPSCACHE = true
+                @logger.debug 'init lookups cache'

             # <-- EXPERIMENTAL
-
-            @id = config.id
-
-            @ID = if !(@parent?.ID) then @id else @parent.ID+'.'+@id
-
-            @data = new floyd.data.SearchableMap config.data, @parent?.data
-
-            if typeof (@type = config.type) is 'function'
-                @type = @ID+'.'+(@type.name || 'DynContext')
-
-            @identity = @_createIdentity()
-
-            @logger = @_createLogger @ID
-
-            @_emitter = @_createEmitter config

             @children = new floyd.data.MappedCollection()

@@ -177,9 +178,9 @@

             ##
-            ##
+            ##
             floyd.tools.objects.intercept @, 'destroy', (done, destroy)=>
-
+
                 if @stop && @_status.indexOf('stopped') is -1
                     @logger.warning 'context not stopped!'

@@ -197,6 +198,8 @@

                             done? err

+            ##
+            ##
             if manager = config.data.authManager

                 if config.ORIGIN
@@ -204,12 +207,18 @@

                 #console.log 'prepare _createAuthHandler', manager

-                __user = config.USER
+                if config.TOKEN
+                    floyd.tools.objects.intercept @, 'boot', (done, boot)=>
+
+                        @_getAuthManager().authorize config.TOKEN, (err)=>
+                            return done(err) if err
+
+                            boot done

                 ##
                 @_createAuthHandler = ()=>

-                    #console.log '_createAuthHandler', manager, __user
+                    #console.log '_createAuthHandler', manager

                     _auth = (fn)=>
                         # EXPERIMENTAL shortcut. use child if found
@@ -223,75 +232,31 @@

                     new floyd.auth.Handler

-                        #
+                        ##
                         authorize: (token, fn)=>
-
-                            #console.log 'autorizazion request', __user, @id
-
-                            if !@identity
-                                #console.log 'no identity', __user?.login
-
-                                fn null, __user
-
-                            else
-                                #console.log 'using manager for authorize'
-                                _auth (err, auth)=>
-                                    return fn(err) if err
-
-                                    #console.log 'delegate authorize', @identity.id
-                                    auth.authorize token, (err, user)=>
-
-                                        fn err, __user = user
+                            _auth (err, auth)=>
+                                return fn(err) if err
+                                auth.authorize token, fn

                         ##
                         authenticate: (identity, fn)=>
-                            #console.log 'using manager for authenticate', identity.id
-
                             _auth (err, auth)=>
-                                if err || !auth
-                                    @logger.warning 'authentication failed!\n\terror: %s\n\tfor: %s', \
-                                        (err?.message ? 'noauth'), identity.id
-
-                                    fn (err ? new Error 'authentication failed!')
-
-                                else
-                                    @logger.debug 'delegate authenticate to: %s for: %s', auth.ID, identity.id
-                                    auth.authenticate identity, fn
+                                return fn(err) if err
+                                auth.authenticate identity, fn

                         ##
                         login: (token, user, pass, fn)=>
-                            #console.log 'using manager for login', user
-
                             _auth (err, auth)=>
                                 return fn(err) if err
-
-                                #console.log 'delegate login', token
-
-                                auth.login token, user, pass, (err)=>
-
-                                    #console.log 'login granted', _user, @id
-
-                                    fn err
+                                auth.login token, user, pass, fn

                         ##
                         logout: (token, fn)=>
-
-                            #console.log 'using manager for logout'
                             _auth (err, auth)=>
                                 return fn(err) if err
-
-                                #console.log 'delegate logout', token
-                                auth.logout  token, (err)=>
-
-                                    __user = null
-
-                                    fn? err
-
-                ##
-                if config.TOKEN
-                    @_getAuthManager().authorize config.TOKEN
-
+                                auth.logout token, fn
+

             if typeof config?.configure is 'function'
                 config = config.configure.apply @, [config]


throw if people fail to pass a listener to KDEventEmitter#on

--- client/Framework/core/KDEventEmitter.coffee
+++ client/Framework/core/KDEventEmitter.coffee
@@ -30,6 +30,7 @@
       registry[eventName] = []

   _on = (registry, eventName, callback)->
+    throw new Error 'Try passing a listener, genius!'  unless callback?
     if Array.isArray eventName
       _registerEvent registry, name, callback for name in eventName
     else


Client: Show error if a battle is attempted without creating a team

--- client/app/js/helpers/challenge_pane.coffee
+++ client/app/js/helpers/challenge_pane.coffee
@@ -75,8 +75,12 @@
     format = $selectFormat.data('format')
     # Toggle state when you press the button.
     if !$button.hasClass('disabled')
+      team = getSelectedTeam()
+      unless team
+        alert("You need to create a team using the Teambuilder before you can battle.")
+        return
+
       disableButtons()
-      team = getSelectedTeam()
       teamJSON = team.toNonNullJSON().pokemon
       # Send the event
       if personId
@@ -93,8 +97,12 @@
   # Implement accept/reject buttons.
   $accept.on 'click.challenge', ->
     return  if $(this).hasClass('disabled')
+    team = getSelectedTeam()
+    unless team
+      alert("You need to create a team using the Teambuilder before you can battle.")
+      return
     disableButtons()
-    teamJSON = getSelectedTeam().toNonNullJSON().pokemon
+    teamJSON = team.toNonNullJSON().pokemon
     PokeBattle.socket.send(acceptEventName, personId, teamJSON, selectedAlt)

   $reject.on 'click.challenge', ->


Teambuilder: Better keypress behavior.

Teambuilder: Better keypress behavior.

--- client/app/js/views/teambuilder_view.coffee
+++ client/app/js/views/teambuilder_view.coffee
@@ -12,8 +12,8 @@
     'change .selected_item': 'changeItem'
     'change .iv-entry': 'changeIv'
     'change .ev-entry': 'changeEv'
-    'keyup .selected_moves input': 'keyupMoves'
-    'focus .selected_moves input': 'keyupMoves'
+    'keydown .selected_moves input': 'keydownMoves'
+    'focus .selected_moves input': 'keydownMoves'
     'click .table-moves tbody tr': 'selectMove'
     'click .move-button': 'deselectMove'

@@ -90,32 +90,30 @@
     pokemon.setEv(stat, value)
     @renderStats(pokemon)

-  keyupMoves: (e) =>
-    # If we're pressing Tab/Enter, we're selecting the active move.
+  keydownMoves: (e) =>
     $table = @$('.table-moves')
     $allMoves = $table.find('tbody tr')
     switch e.which
-      when 9, 13
+      when 9, 13  # [Tab]/[Enter]; we're selecting the active move.
         $activeMove = $allMoves.filter('.active').first()
         $activeMove.click()
-        return
-      when 38  # [Up arrow]
+      when 38  # [Up arrow]; selects move above
         $activeMove = $allMoves.filter('.active').first()
         $prevMove = $activeMove.prevAll(":visible").first()
-        $activeMove.removeClass('active')
-        $prevMove.addClass('active')
-        return
-      when 40  # [Down arrow]
+        if $prevMove.length > 0
+          $activeMove.removeClass('active')
+          $prevMove.addClass('active')
+      when 40  # [Down arrow]; selects move below
         $activeMove = $allMoves.filter('.active').first()
         $nextMove = $activeMove.nextAll(":visible").first()
-        $activeMove.removeClass('active')
-        $nextMove.addClass('active')
-        return
-
-    # Otherwise we're filtering moves
-    $this = $(e.currentTarget)
-    moveName = $this.val()
-    @filterMovesBy(moveName)
+        if $nextMove.length > 0
+          $activeMove.removeClass('active')
+          $nextMove.addClass('active')
+      else
+        # Otherwise we're filtering moves
+        $this = $(e.currentTarget)
+        moveName = $this.val()
+        @filterMovesBy(moveName)

   filterMovesBy: (moveName) =>
     $table = @$('.table-moves')


Make doesExist works

Make doesExist works

--- client/landing/app/MainApp/fs/fsitem.coffee
+++ client/landing/app/MainApp/fs/fsitem.coffee
@@ -29,19 +29,17 @@
   @getSafePath:(path, callback) ->

     KD.getSingleton('kiteController').run
-      method        : "fetchSafeFileName"
+      method      : "fetchSafeFileName"
       withArgs    :
         filePath  : path
     , callback

   @doesExist:(path, callback) ->
-
-    KD.getSingleton('kiteController').run "stat #{escapeFilePath path}", (err, stderr, stdout)=>
-      if err then callback err, null
-      else if stderr
+    KD.getSingleton('kiteController').run "test -d #{escapeFilePath path}", (err, stderr, stdout)=>
+      unless err isnt ""
         callback null, no
-      else if stdout
-        callback null, yes
+      else
+        callback err, yes

   @copy:(sourceItem, targetItem, callback)->


proxy id to model if given

proxy id to model if given

--- client/lanes/models/AssociationProxy.coffee
+++ client/lanes/models/AssociationProxy.coffee
@@ -119,6 +119,7 @@

         definedProps = {
             isProxy: { value: true, enumerable: true, writable: false }
+            id: { get: -> @getId() }
         }
         if klass::associations?
             definedProps.associations =
@@ -128,7 +129,7 @@
                 definedProps[name] = @associationDefinition(name, definition, config)

         if klass::_definition?
-            for name, definition of klass::_definition
+            for name, definition of klass::_definition when not definedProps[name]
                 definedProps[name] = @fieldDefinition(name, definition, config)

         if klass::_derived?


add finder to chooser

add finder to chooser

--- client/skr/components/GlAccountChooser.cjsx
+++ client/skr/components/GlAccountChooser.cjsx
@@ -9,12 +9,30 @@
     getDefaultProps: ->
         label: 'Account', name: 'gl_account'

+    dataObjects:
+        query: ->
+            new Lanes.Models.Query({
+                syncOptions: @props.syncOptions
+                src: Skr.Models.GlAccount.all, fields: [
+                    {id:'id', visible: false}
+                    {id: 'number', fixedWidth: 130 }
+                    'name', 'description'
+                ]
+            })
+
     render: ->
         props = _.clone(@props)
-        <LC.SelectField
-            queryModel={Skr.Models.GlAccount}
-            choices={Skr.Models.GlAccount.all.models}
-            labelField="combined_name"
-            model={@props.model}
-            {...props}
-        />
+
+        if props.finderField
+            <LC.RecordFinder ref="finder"
+                commands={@props.commands}
+                query={@query}
+                {...props} />
+        else
+            <LC.SelectField
+                queryModel={Skr.Models.GlAccount}
+                choices={Skr.Models.GlAccount.all.models}
+                labelField="combined_name"
+                model={@props.model}
+                {...props}
+            />


Allow overriding get/set from props

Allow overriding get/set from props

--- client/skr/components/PrintFormChooser.cjsx
+++ client/skr/components/PrintFormChooser.cjsx
@@ -1,18 +1,22 @@
 class Skr.Components.PrintFormChooser extends Lanes.React.Component

     propTypes:
-        label: React.PropTypes.string
+        label: React.PropTypes.string.isRequired
         model: Lanes.PropTypes.Model.isRequired
+        choices: React.PropTypes.array

     mixins: [
         Lanes.React.Mixins.ReadEditingState
     ]

-    onChange: ->
-        (f) => @invoice.form = f
+    onChange: (val) ->
+        if @props.onChange
+            @props.onChange?(val, @props)
+        else
+            @props.model[@props.name] = val

     renderEdit: (value) ->
-        choices = @props.model.constructor.Templates
+        choices = @props.choices || @props.model.constructor.Templates
         <Lanes.Vendor.ReactWidgets.DropdownList
             data={choices}
             value={value}
@@ -23,7 +27,7 @@
         value

     render: ->
-        value = @props.model[@props.name or 'form'] or 'default'
+        value = @props.value or @props.model[@props.name or 'form'] or 'default'
         props = _.omit(@props, 'choices', 'name')
         <LC.FormGroup editing={@isEditingRecord()}
             className="field" {...props}


Added navigation for choice questions

Added navigation for choice questions

--- jsapp/xlform/src/view.choices.coffee
+++ jsapp/xlform/src/view.choices.coffee
@@ -86,7 +86,7 @@
     render: ->
       @t = $("")
       @pw = $("
")
-      @p = $("<input class=\"js-cancel-select-row\">")
+      @p = $("<input placeholder=\"#{_t("This option has no name")}\" class=\"js-cancel-select-row option-view-input\">")
       @c = $("#{_t("XML value:")} <input type=\"text\" placeholder=\"AUTOMATIC\"  class=\"js-cancel-select-row\"></input>")
       @d = $('
')
       if @model
@@ -138,6 +138,20 @@
       @
     keyupinput: (evt)->
       ifield = @$("input.inplace_field")
+      if evt.keyCode is 13
+        evt.preventDefault()
+
+        localListViewIndex = $('ul.ui-sortable').index($(this.el).parent())
+        localOptionView = $('ul.ui-sortable').eq(localListViewIndex).children().find('input.option-view-input')
+
+        index = localOptionView.index(document.activeElement) + 1
+
+        if index >= localOptionView.length
+          $(this.el).parent().siblings().trigger('click')
+          localOptionView = $('ul.ui-sortable').eq(localListViewIndex).children().find('input.option-view-input')
+        localOptionView.eq(index).focus()
+        localOptionView.eq(index).select()
+
       if evt.keyCode is 8 and ifield.hasClass("empty")
         ifield.blur()


small fix to: let the userArea fall back to the group entryPoint.slug

--- client/landing/app/Applications/Groups.kdapplication/AppController.coffee
+++ client/landing/app/Applications/Groups.kdapplication/AppController.coffee
@@ -90,7 +90,7 @@
   getUserArea:->
     @userArea ?
       if KD.config.entryPoint?.type is 'group'
-      then KD.config.entryPoint.slug
+      then {group: KD.config.entryPoint.slug}

   setUserArea:(userArea)->
     @emit 'UserAreaChanged', userArea  if not _.isEqual userArea, @userArea


improved success message of request access / invitation

--- client/landing/app/Applications/Groups.kdapplication/AppController.coffee
+++ client/landing/app/Applications/Groups.kdapplication/AppController.coffee
@@ -267,11 +267,11 @@
     if isApproval
       title   = 'Request Access'
       content = 'Membership to this group requires administrative approval.'
-      success = "Thanks! You'll receive an email when group's admin accepts you."
+      success = "Thanks! You'll be notified when group's admin accepts you."
     else
       title   = 'Request an Invite'
       content = 'Membership to this group requires an invitation.'
-      success = "Invitation has been sent to the group's admin."
+      success = "Your request has been sent to the group's admin."

     modal = new KDModalView
       title          : title


Slug is singular.

Slug is singular.

--- client/landing/app/Applications/Groups.kdapplication/AppController.coffee
+++ client/landing/app/Applications/Groups.kdapplication/AppController.coffee
@@ -391,7 +391,7 @@
       if userSlug.length > 0
         queryDB userSlug, (newSlug)->
           slugField.setTooltip
-            title     : "Suggestions:
 #{newSlug}"
+            title     : "Suggestion: #{newSlug}"
             placement : 'right'
       else
         delete slugField.tooltip


return proper

return proper

--- lib/esl.coffee
+++ lib/esl.coffee
@@ -404,6 +404,7 @@
     res = new eslResponse socket
     if intercept_response?
       res.intercept_response = intercept_response
+    return res

   socket.setEncoding('ascii')
   parser = new eslParser socket


Fix filter delete.

Fix filter delete.

--- lib/esl.coffee
+++ lib/esl.coffee
@@ -296,9 +296,9 @@

   filter_delete: (header,value,cb) ->
     if value?
-      @send "filter #{header} #{value}", cb
+      @send "filter delete #{header} #{value}", cb
     else
-      @send "filter #{header}", cb
+      @send "filter delete #{header}", cb

   # Send an event into the FreeSwitch event queue.
   sendevent: (event_name,args,cb) ->


made some logic in Shaharit schedule happen even on hidden rows, in preparation for making those rows not hidden

--- js/schedule.coffee
+++ js/schedule.coffee
@@ -13,12 +13,13 @@
     $(".#{day}").removeClass('hidden')
     $(".#{day} .selihot").addClass('hidden').html('')
     $(".#{day} .placeholder").addClass('hidden')
+    $(".#{day} .date").html(day_iterator.format("D MMM"))
     date = day_iterator.toDate()
     hebrew_date = new HebrewDate(date)
+    show_event(day, event, hebrew_date) for event in events
     if hebrew_date.isYomTov() || hebrew_date.isYomKippur()
       $(".#{day}").addClass('hidden')
     else
-      $(".#{day} .date").html(day_iterator.format("D MMM"))
       sunrise = moment(SunCalc.getTimes(date, window.config.latitude, window.config.longitude).sunrise)
       $(".#{day} .amidah").html(time_format(sunrise))
       $(".#{day} .yishtabach").html(time_format(sunrise.subtract('minutes', 8)))
@@ -28,7 +29,6 @@
         $(".#{day} .selihot").removeClass('hidden').html(time_format(sunrise.subtract('minutes', 56)))
       if hebrew_date.isElul() && !hebrew_date.isRoshChodesh()
         $(".#{day} .selihot").removeClass('hidden').html(time_format(sunrise.subtract('minutes', 50)))
-      show_event(day, event, hebrew_date) for event in events
     day_iterator.add('days', 1)
   $(".header .event")[show_if($('.one_day .event').not('.hidden').length > 0)]('hidden')
   ($(".#{day} .placeholder")[show_if(has_no_event(day))]('hidden') for day in moment.weekdays()[0,6]) unless $(".header .event").hasClass('hidden')


Remove testing artifacts

Remove testing artifacts

--- library/membrane/duplex.coffee
+++ library/membrane/duplex.coffee
@@ -148,4 +148,3 @@
             assert _.isFunction(value), internal
             context.removeAllListeners "connection"
         return next()
-        util.inspect next


Minor fix in the remote

Minor fix in the remote

--- library/membrane/remote.coffee
+++ library/membrane/remote.coffee
@@ -47,7 +47,7 @@
     @symbol = symbol unless _.isEmpty symbol
     assert not _.isEmpty(@symbol), noSymbol
     f = => "var #{@symbol} = (#{@source})()"
-    return d() unless _.isObject @compiled
+    return f() unless _.isObject @compiled
     hierarchy = try @compiled.hierarchy?()
     assert _.isArray(hierarchy), "no hierarchy"
     hasRemote = (x) ->_.isObject x.remote


Check in the refactored, generic augment

--- library/nucleus/augment.coffee
+++ library/nucleus/augment.coffee
@@ -70,6 +70,7 @@
             logger.debug(msg.grey, method.toUpperCase())
             namespace[method] = (resource, implementation) =>
                 forResource = Augment.augmentForResource
+                forResource = forResource.bind Augment
                 augment = forResource resource, foundation
                 augment.service::[method] = implementation
                 implementation.service = augment.service
@@ -87,7 +88,9 @@
             msg = "Installing service method proxy for %s"
             logger.debug(msg.grey, method.toUpperCase())
             namespace[method] = (resource, parameters...) =>
-                augment = Augment.augmentForResource resource
+                forResource = Augment.augmentForResource
+                forResource = forResource.bind Augment
+                augment = forResource resource, foundation
                 method = augment.service[method]
                 bound = method.bind augment.service
                 bound parameters...


Minor phrasing correction

Minor phrasing correction

--- library/nucleus/scoping.coffee
+++ library/nucleus/scoping.coffee
@@ -82,7 +82,7 @@
         throw new Error notFound unless found.length > 0
         assert.ok _.isObject scope = _.head(found); scope

-    # Get a concatenated path to the unique file designed by the
+    # Get a concatenated path to the unique path designed by the
     # combination of prefix and a unique identificator generated by
     # employing the UUID v4 format. If unique param is set to false
     # than the path will be set to prefix without the unique part.


Teamwork: Removed hiding Playgrounds button for Facebook Teamwork.

--- client/app/Applications/Teamwork.kdapplication/Views/facebookteamwork.coffee
+++ client/app/Applications/Teamwork.kdapplication/Views/facebookteamwork.coffee
@@ -95,7 +95,6 @@
       @emit "ContentImportDone"

   createRunButton: (panel) ->
-    panel.headerButtons.Playgrounds.hide()
     panel.header.addSubView @runButton = new KDButtonViewWithMenu
       title               : "Run"
       menu                :


topics search: fix for typo in method name

--- client/activity/lib/sidebar/topicsearchmodal.coffee
+++ client/activity/lib/sidebar/topicsearchmodal.coffee
@@ -14,7 +14,7 @@
     options.emptySearchText or= 'Sorry, your search did not have any results'
     options.endpoints        ?=
       fetch                   : kd.singletons.socialapi.channel.list
-      search                  : kd.singletons.socialapi.channel.searchTopicyous
+      search                  : kd.singletons.socialapi.channel.searchTopics

     super options, data