comment typo

comment typo

--- jsapp/xlform/src/model.inputParser.coffee
+++ jsapp/xlform/src/model.inputParser.coffee
@@ -108,7 +108,7 @@
       to introduce potential code-breaking refactor in old code, so we store
       first language, then replace with null and reverse this just before saving
       NOTE: when importing assets from Library into form, we need to make sure
-      the default language is the same (or force baseSurve default language)
+      the default language is the same (or force baseSurvey default language)
       ###
       if baseSurvey
         formDefaultLang = baseSurvey._initialParams.translations_0


edge case of saving when cursor table not initialized

--- src/smc-webapp/syncdoc.coffee
+++ src/smc-webapp/syncdoc.coffee
@@ -692,7 +692,7 @@
         cm = @focused_codemirror()
         if @editor.opts.delete_trailing_whitespace
             omit_lines = {}
-            @_syncstring.get_cursors().map (x, _) =>
+            @_syncstring.get_cursors()?.map (x, _) =>
                 x.get('locs')?.map (loc) =>
                     y = loc.get('y')
                     if y?


Changing call to deprecated File.lastModifiedDate

The new property is File.lastModified; Safari 10.0 is the first to
fully deprecate support.


remove console.log

remove console.log

--- src/factory.coffee
+++ src/factory.coffee
@@ -50,7 +50,6 @@
             process.nextTick ->
                 cb.apply null, instances
         onReject = (rejection) ->
-            console.log 'REJECTION', rejection
             emitError rejection

         promise = getOrCreateManyInstances containers, ids


Capitalize ASCII for consistency

Capitalize ASCII for consistency

--- src/helpers.coffee
+++ src/helpers.coffee
@@ -86,7 +86,7 @@
 exports.keystrokeForKeyboardEvent = (event) ->
   unless KeyboardEventModifiers.has(event.keyIdentifier)
     keyIdentifierIsHexCharCode = event.keyIdentifier.indexOf('U+') is 0
-    if isAscii(event.keyCode) and keyIdentifierIsHexCharCode
+    if isASCII(event.keyCode) and keyIdentifierIsHexCharCode
       key = keyFromCharCode(event.keyCode)
     else if keyIdentifierIsHexCharCode
       hexCharCode = event.keyIdentifier[2..]
@@ -148,7 +148,7 @@
   which ?= keyCode
   keyCode ?= which
   if keyCode? or event.keyCode is 0
-    # 0 is the default, and it's valid Ascii, but it's wrong.
+    # 0 is the default, and it's valid ASCII, but it's wrong.
     Object.defineProperty(event, 'which', get: -> which)
     Object.defineProperty(event, 'keyCode', get: -> keyCode)
   event
@@ -223,5 +223,5 @@
     when 127 then 'delete'
     else String.fromCharCode(charCode)

-isAscii = (charCode) ->
+isASCII = (charCode) ->
   0 <= charCode <= 127


Make rename detection case-insensitive

Make rename detection case-insensitive

--- src/install.coffee
+++ src/install.coffee
@@ -355,7 +355,7 @@
             @installNode (error) -> next(error, packagePath)
         commands.push (packagePath, next) =>
           @installModule(options, pack, packagePath, next)
-        if installGlobally and packageName isnt pack.name
+        if installGlobally and (packageName.localeCompare(pack.name, 'en', {sensitivity: 'accent'}) isnt 0)
           commands.push (newPack, next) => # package was renamed; delete old package folder
             fs.removeSync(path.join(@atomPackagesDirectory, packageName))
             next(null, newPack)


First stab at RandomAccessFile.

First stab at RandomAccessFile.

It's probably wrong somewhere. Trying to do this for javac.

--- src/methods.coffee
+++ src/methods.coffee
@@ -496,8 +496,15 @@
             # TODO make this an object so we can write back
             fname = rs.jvm2js_str(name)
             error "Attempting to use #{fname} as a RandomAccessFile -- may not be correct!"
-            _this.fields.$file = fs.readFileSync fname
-        o 'length()J', (rs, _this) -> _this.fields.$file.length
+            _this.fields.$file = fs.readFileSync fname, 'binary'
+        o 'length()J', (rs, _this) -> gLong.fromNumber _this.fields.$file.length
+        o 'seek(J)V', (rs, _this, pos) -> _this.fields.$pos = pos
+        o 'readBytes([BII)I', (rs, _this, bytes_arr, offset, len) ->
+            pos = (_this.fields.$pos ?= 0)
+            data = _this.fields.$file.slice(pos, len)
+            bytes_arr.array[offset...offset+data.length] = (data.charCodeAt(i) for i in [0...data.length])
+            _this.fields.$pos += data.length
+            return if data.length == 0 and len isnt 0 then -1 else data.length
         o 'close0()V', (rs) ->
       ]
       UnixFileSystem: [


more native code, reflection support

more native code, reflection support

--- src/methods.coffee
+++ src/methods.coffee
@@ -32,6 +32,17 @@
     @type = str2type raw_descriptor
     if @access_flags.static
       @static_value = null  # loaded in when getstatic is called
+
+  reflector: (rs) ->
+    rs.set_obj 'java/lang/reflect/Field', {
+      # XXX this leaves out 'slot' and 'annotations'
+      clazz: rs.init_class_object c2t @class_name
+      name: rs.init_string @name, true
+      type: rs.init_class_object @type
+      modifiers: @access_byte
+      slot: parseInt((i for i,v of rs.class_lookup(@class_name).fields when v is @)[0])
+      signature: rs.init_string @raw_descriptor
+    }

 getBundle = (rs) ->
   # load in the default ResourceBundle (ignores locale)
@@ -171,17 +182,6 @@
   rs.push oref unless m.access_flags.static
   m.run(rs,m.access_flags.virtual)
   rs.pop()
-
-make_field = (rs,f) ->
-  rs.set_obj 'java/lang/reflect/Field', {
-    # XXX this leaves out 'slot' and 'annotations'
-    clazz: rs.init_class_object c2t f.class_name
-    name: rs.init_string f.name, true
-    type: rs.init_class_object f.type
-    modifiers: f.access_byte
-    slot: parseInt((i for i,v of rs.class_lookup(f.class_name).fields when v is f)[0])
-    signature: rs.init_string f.raw_descriptor
-  }

 native_methods =
   java:
@@ -223,7 +223,13 @@
             fields = rs.class_lookup(_this.fields.$type.toClassString()).fields
             fields = (f for f in fields when f.access_flags.public) if public_only
             rs.class_lookup 'java/lang/reflect/Field'
-            rs.set_obj('[Ljava/lang/reflect/Field;',(make_field(rs,f) for f in fields))
+            rs.set_obj('[Ljava/lang/reflect/Field;',(f.reflector(rs) for f in fields))
+        o 'getDeclaredMethods0(Z)[Ljava/lang/reflect/Method;', (rs, _this, public_only) ->
+            methods = rs.class_lookup(_this.fields.$type.toClassString()).methods
+            methods = (m for m in methods when m.access_flags.public) if public_only
+            rs.class_lookup 'java/lang/reflect/Method'
+            rs.set_obj('[Ljava/lang/reflect/Method;',(m.reflector(rs) for m in methods))
+        o 'getModifiers()I', (rs, _this) -> rs.class_lookup(_this.fields.$type.toClassString()).access_byte
       ],
       Float: [
         o 'floatToRawIntBits(F)I', (rs, f_val) ->  #note: not tested for weird values
@@ -422,13 +428,27 @@
   get_code: ->
     return _.find(@attrs, (a) -> a.constructor.name == "Code")

-  parse_descriptor: (raw_descriptor) ->
-    [__,param_str,return_str] = /\(([^)]*)\)(.*)/.exec(raw_descriptor)
+  parse_descriptor: (@raw_descriptor) ->
+    [__,param_str,return_str] = /\(([^)]*)\)(.*)/.exec(@raw_descriptor)
     param_carr = param_str.split ''
     @param_types = (field while (field = carr2type param_carr))
     @num_args = @param_types.length
     @num_args++ unless @access_flags.static # nonstatic methods get 'this'
     @return_type = str2type return_str
+
+  reflector: (rs) ->
+    rv = rs.set_obj 'java/lang/reflect/Method', {
+      # XXX: missing checkedExceptions, annotations, parameterAnnotations, annotationDefault
+      clazz: rs.init_class_object c2t @class_name
+      name: rs.init_string @name, true
+      parameter_types: rs.set_obj "[Ljava/lang/Class;", (rs.init_class_object f.type for f in @param_types)
+      returnType: rs.init_class_object @return_type
+      modifiers: @access_byte
+      slot: parseInt((i for i,v of rs.class_lookup(@class_name).methods when v is @)[0])
+      signature: rs.init_string @raw_descriptor
+    }
+    console.log '>>>', @name, @raw_descriptor, rs.get_obj(rv).fields
+    rv

   param_bytes: () ->
     type_size = (t) -> (if t.toString() in ['D','J'] then 2 else 1)


use $validators instead of $parsers/$formatters

--- src/ng-iban.coffee
+++ src/ng-iban.coffee
@@ -17,25 +17,7 @@
         iban = parseIban(value)
         IBAN.isValid iban

-      ctrl.$parsers.unshift (viewValue) ->
-        if viewValue?
-          valid = isValidIban viewValue
-          ctrl.$setValidity 'iban', valid
-          if valid
-            parsed = parseIban viewValue
-            if parsed isnt viewValue
-              ctrl.$setViewValue parsed
-              ctrl.$render()
-            parsed
-          else undefined
+      ctrl.$validators.ngIban = (modelValue) ->
+        isValidIban modelValue

-      ctrl.$formatters.unshift (modelValue) ->
-        if modelValue?
-          valid = isValidIban modelValue
-          ctrl.$setValidity 'iban', valid
-          if valid
-            parsed = parseIban modelValue
-            if parsed isnt modelValue
-              scope[attrs.ngModel] = parsed
-            parsed
-          else modelValue
+      return


Fix options

Fix options

--- src/options.coffee
+++ src/options.coffee
@@ -9,7 +9,7 @@
     chrome.extension.sendMessage action: 'optionsSaved'

   @loadOptions: (defaults, callback)->
-    chrome.storage.local.get DEFAULTS, @setOptions
+    chrome.storage.local.get defaults, callback

 class Options

@@ -19,7 +19,8 @@

   constructor: ->

-    @loadOptions DEFAULTS, => @setOptions()
+    Extension.loadOptions DEFAULTS, (options)=>
+      @setOptions options

     $('#save').click => @saveOptions 'Options saved.'


dont test what you cant test

dont test what you cant test

--- lineman/spec-e2e/subscription_spec.coffee
+++ lineman/spec-e2e/subscription_spec.coffee
@@ -30,15 +30,15 @@
       page.loadPath('setup_group_with_expired_legacy_trial')
       page.expectNoElement('.legacy-trial-expired-modal')

-  describe 'group with expired trial', ->
-
-    it 'displays a trial card telling coordinators their trial has expired', ->
-      page.loadPath('setup_group_with_expired_trial')
-      page.expectText('.trial-card', "you'll need to pick a pricing plan that suits." )
-
-    it 'displays the nag modal when trial expired more than 15 days ago', ->
-      page.loadPath('setup_group_with_overdue_trial')
-      page.expectText('.choose-plan-modal', 'please choose a payment plan')
+  # describe 'group with expired trial', ->
+  #
+  #   it 'displays a trial card telling coordinators their trial has expired', ->
+  #     page.loadPath('setup_group_with_expired_trial')
+  #     page.expectText('.trial-card', "you'll need to pick a pricing plan that suits." )
+  #
+  #   it 'displays the nag modal when trial expired more than 15 days ago', ->
+  #     page.loadPath('setup_group_with_overdue_trial')
+  #     page.expectText('.choose-plan-modal', 'please choose a payment plan')

   describe 'group on paid plan', ->


Transaction::finalize greentests

Transaction::finalize greentests

#8 QueryHandlers should also handle query transmission

--- test/unit/transactions/Transaction.spec.coffee
+++ test/unit/transactions/Transaction.spec.coffee
@@ -11,13 +11,74 @@
       jasmine.clock().install()
       @address = '127.0.0.1:1337'
       @id = 0
+      @transaction = new Transaction @address, @id
+
+    afterEach ()->
+      jasmine.clock().uninstall()

     it 'should timeout', ()->
       toBeCalled = jasmine.createSpy('timerCallback')

-      t = new Transaction @address, @id
-      t.on 'timeout', toBeCalled
+      @transaction.on 'timeout', toBeCalled

       expect(toBeCalled).not.toHaveBeenCalled()
       jasmine.clock().tick(constants.SEND_TIMEOUT+1)
       expect(toBeCalled).toHaveBeenCalledWith @address, @id
+
+  describe 'finalize', ()->
+
+    commonBeforeEach = ()->
+      @address = '127.0.0.1:1337'
+      @id = 0
+      @transaction = new Transaction @address, @id
+      @finalCb = jasmine.createSpy 'finalize'
+      @tDebug = jasmine.createSpy 'debug'
+      @transaction._debug = @tDebug
+
+    describe 'unfinalized', ()->
+
+      beforeEach commonBeforeEach
+
+      it 'should be finalized without a prefix callback', ()->
+        @transaction.on 'finalize', @finalCb
+        expect(@finalCb).not.toHaveBeenCalled()
+        @transaction.finalize()
+        expect(@finalCb).toHaveBeenCalled()
+        expect(@transaction.finalized).toBe true
+
+      it 'should be finalized with a prefix callback', ()->
+        prefixCb = jasmine.createSpy 'prefix'
+        @transaction.on 'finalize', @finalCb
+        expect(@finalCb).not.toHaveBeenCalled()
+        expect(prefixCb).not.toHaveBeenCalled()
+
+        @transaction.finalize prefixCb
+
+        expect(@finalCb).toHaveBeenCalled()
+        expect(prefixCb).toHaveBeenCalled()
+        expect(@transaction.finalized).toBe true
+
+    describe 'already finalized', ()->
+
+      beforeEach ()->
+        commonBeforeEach.call @
+        @transaction.finalize()
+
+      it 'should not be finalized again', ()->
+        @transaction.on 'finalize', @finalCb
+        expect(@finalCb).not.toHaveBeenCalled()
+        expect(@tDebug).not.toHaveBeenCalled()
+
+        # Second call
+        @transaction.finalize()
+        expect(@finalCb).not.toHaveBeenCalled()
+        expect(@tDebug).toHaveBeenCalledWith 'Already finalized'
+        expect(@transaction.finalized).toBe true
+
+      it 'should log custom debug second time', ()->
+        expect(@tDebug).not.toHaveBeenCalled()
+
+        customMessage = 'Customs already finalized'
+        # Second
+        @transaction.finalize null, customMessage
+        expect(@tDebug).toHaveBeenCalledWith customMessage


refactored

refactored

--- testApp/app/controllers/modalController.coffee
+++ testApp/app/controllers/modalController.coffee
@@ -27,17 +27,12 @@

   @testShowPreloaded: () ->
-    receiveMessage = (message) =>
-      if message.data == "okay to show modal"
-        steroids.modal.show(preloadedView)

-    window.addEventListener "message", receiveMessage
+    window.addEventListener "message", (message) =>
+      steroids.modal.show(preloadedView) if message.data == "okay to show modal"

-    preloadedView = new steroids.views.WebView {
-      location: "/views/modal/preload.html"
-    }
-
+    preloadedView = new steroids.views.WebView "/views/modal/preload.html"
     preloadedView.preload()


Allow controller test to run standalone

Allow controller test to run standalone

--- tests/batman/controller/controller_test.coffee
+++ tests/batman/controller/controller_test.coffee
@@ -1,3 +1,5 @@
+helpers = if typeof require is 'undefined' then window.viewHelpers else require '../view/view_helper'
+
 class TestController extends Batman.Controller
   show: ->


not actually doing anything

not actually doing anything

--- src/require.coffee
+++ src/require.coffee
@@ -25,7 +25,7 @@
   defines.push ->
     exports = {}
     module = exports: exports
-    cb.call exports, require, exports, module, window
+    cb.call exports, require, exports, module
     module.exports or exports

 exts =
@@ -34,7 +34,7 @@

     if not /define\(/.test code
       code = """
-        define(function(require, exports, module, window) {
+        define(function(require, exports, module) {
           #{code};
         });
       """


Fix error message.

Fix error message.

--- src/runWith.coffee
+++ src/runWith.coffee
@@ -8,9 +8,10 @@
 module.exports = runWith = ({cwd, env, containingDir, inputs, resolveValues, log}) ->
   templateName = inputs[1]
   templateDirs = ("#{path}/jumpstart-#{templateName}/template" for path in [cwd,containingDir])
+  configDirs = ("#{dir}/.jumpstart.json" for dir in [cwd,env.HOME])
   Memoblock.do([
-    -> @configFilePath = detectSeries ("#{dir}/.jumpstart.json" for dir in [cwd,env.HOME]), fsExists
-    -> log "Did not find config file in #{searchPaths.join ", "}." unless @configFilePath
+    -> @configFilePath = detectSeries configDirs, fsExists
+    -> log "No config file in #{configDirs.join ", or "}. Please read README.md." unless @configFilePath
     -> log "Using config file #{@configFilePath}." if @configFilePath
     -> throw new Error "Usage: jumpstart [project-name] [template-name]" if inputs.length isnt 2
     -> @targetDir = "#{cwd}/#{inputs[0]}"


TabHandleView: Code style refactoring.

TabHandleView: Code style refactoring.

--- src/components/tabs/tabhandleview.coffee
+++ src/components/tabs/tabhandleview.coffee
@@ -23,7 +23,7 @@
       @handleDragStart event, dragState

     @on "DragInAction", (x, y) =>
-      @dragIsAllowed = no if @startedDragFromCloseElement
+      @dragIsAllowed = no  if @startedDragFromCloseElement
       @handleDragInAction x, y

     @on "DragFinished", (event) =>
@@ -61,17 +61,12 @@
   getWidth:-> @$().outerWidth(no) or 0

   cloneElement: (x) ->
-    return if @$cloned
-
     {pane}   = @getOptions()
     tabView  = pane.getDelegate()
     holder   = tabView.tabHandleContainer.tabs
     @$cloned = @$().clone()
     holder.$().append @$cloned
     @$cloned.css marginLeft: -(tabView.handles.length - @index) * @getWidth()
-
-  updateClonedElementPosition: (x) ->
-    @$cloned.css left: x

   reorderTabHandles: (x) ->
     dragDir = @dragState.direction
@@ -98,12 +93,11 @@

   handleDragInAction: (x, y) ->
     return unless @dragIsAllowed
-    return @$().css 'left': 0 if -(@draggedItemIndex * @getWidth()) > x
+    return @$().css 'left': 0  if -(@draggedItemIndex * @getWidth()) > x

-    @unsetClass 'first'
-    @cloneElement x
-    @$().css opacity: 0
-    @updateClonedElementPosition x
+    @cloneElement x  unless @$cloned
+    @$().css     opacity: 0
+    @$cloned.css left   : x
     @reorderTabHandles x

   handleDragFinished: (event) ->
@@ -111,6 +105,7 @@

     @$cloned.remove()
     @$().css { left: '', opacity: 1, marginLeft: '' }
-    @$().css left: 0 if not @targetTabHandle and @draggedItemIndex is 0
+    @$().css left: 0  if not @targetTabHandle and @draggedItemIndex is 0
+
     @targetTabHandle = null
-    @$cloned   = null+    @$cloned         = null


Detect module format on demand, instead of relying on module.format, since module.format is undefined in production build.

--- src/client/module_loader.coffee
+++ src/client/module_loader.coffee
@@ -130,8 +130,6 @@

 # Load a module
 load = (path, callback) ->
-  format = moduleFormatFromPath(path)
-
   # Skip if the module is already loaded
   if modules[path]
     callback(modules[path])
@@ -144,7 +142,7 @@
     return

   # Otherwise, fetch the module from its path
-  inProgressModules[path] = {path, format, callbacks: [callback]}
+  inProgressModules[path] = {path, callbacks: [callback]}

   if /\.(html|htm|json|css)$/.test(path)
     fetchText path, (text) ->
@@ -179,7 +177,7 @@
   path = module.path

   # If it's a traditional script, evaluate it here.
-  if module.format is 'script'
+  if moduleFormatFromPath(path) is 'script'
     module.factory.call(window)
     delete module.factory
     if config.exports[path]
@@ -223,7 +221,7 @@
     for own prop, value of require
       localRequire[prop] = value

-    if module.format is 'module'
+    if moduleFormatFromPath(path) is 'module'
       module.factory.call(window, localRequire, module.exports, module)
     else
       module.factory.call(window)


superficial comment

superficial comment

--- src/context.coffee
+++ src/context.coffee
@@ -29,7 +29,7 @@
   .method 'in'
   .method 'once'
   .method 'on'
-  .access 'content'
+  .access 'content' # read/write
   .getter 'schema'
   .getter 'container'
   .getter 'parent'


nested helper

nested helper

--- src/context.coffee
+++ src/context.coffee
@@ -87,15 +87,21 @@
       vars: vars

       render: (o) ->
-        $item = $ '
'
+        @nested 'renderable', handle_renderable, o
+        # TODO warn if not renderable
+
+      nested: (className, fn, args...) ->
+        $item = $ "
"
+        @nested_item $item, fn, args...
+
+      nested_item: ($item, fn, args...) ->
         @output $item

         nested_context = _.extend {}, run_context,
           output: output $item

         nested_context.cli = bind_cli nested_context, cli
-        handle_renderable.call nested_context, o
-        # TODO warn if not renderable
+        fn.apply nested_context, args

       handle_exception: (e, compiled) ->
         console.error e.stack
@@ -117,7 +123,6 @@
       async: (fn) ->
         $item = $ '
'
         $item.attr 'data-async-status', 'loading'
-        @output $item

         start_time = new Date

@@ -129,11 +134,7 @@
           else
             "#{ms} ms"

-        nested_context = _.extend {}, run_context,
-          output: output $item
-
-        nested_context.cli = bind_cli nested_context, ops
-        promise = fn.call(nested_context)
+        promise = @nested_item $item, fn
         promise.done ->
           $item.attr 'data-async-status', "loaded in #{duration()}"
           scroll_to_top()


Added pubnub uuid

Added pubnub uuid

--- src/coffee/control/login.coffee
+++ src/coffee/control/login.coffee
@@ -1,10 +1,13 @@
 angular.module 'app.control'

 .controller 'app.control.login',
-  ['$scope', '$kinvey', '$facebook', '$moment', '$state',
-    ($scope, $kinvey, $facebook, $moment, $state) ->
+  ['$scope', '$kinvey', '$facebook', '$moment', '$state', 'PubNub',
+    ($scope, $kinvey, $facebook, $moment, $state, PubNub) ->

       loginSuccess = (user) ->
+        PubNub.uuid (uuid)->
+          console.log(uuid)
+          return uuid
         $state.go 'index'

       loginFailure = (error) ->


Fix conflicting 'path' variable names.

Fix conflicting 'path' variable names.

--- src/timbits.coffee
+++ src/timbits.coffee
@@ -66,12 +66,12 @@
 			res.end master

 	# automagically load timbits found in the ./timbits folder
-	path = "#{config.home}/timbits"
-	fs.readdir path, (err, files) =>
+	timbit_path = "#{config.home}/timbits"
+	fs.readdir timbit_path, (err, files) =>
 		throw err if err
 		for file in files
 			if file.match(/\.(coffee|js)$/)?
-				@add file.substring(0, file.lastIndexOf(".")), require("#{path}/#{file}")
+				@add file.substring(0, file.lastIndexOf(".")), require("#{timbit_path}/#{file}")

 	# starts the server
 	try


Move 'disabled-datepicker' into classnames

--- src/components/tutor-input.cjsx
+++ src/components/tutor-input.cjsx
@@ -148,9 +148,12 @@
     classes = classnames 'form-control',
       empty: (not @props.value and not @state.hasFocus)

+    isDatePickerDisabled = @props.disabled and value
+
     wrapperClasses = classnames 'form-control-wrapper', 'tutor-input', '-tutor-date-input', @props.className,
       'is-required': @props.required
       'has-error': @state.errors?.length
+      'disabled-datepicker':  isDatePickerDisabled

     now = TimeStore.getNow()
     value = @props.value
@@ -176,9 +179,8 @@
           selected={value}
           weekStart={@props.currentLocale.week.dow}
         />
-    else if @props.disabled and value
+    else if isDatePickerDisabled
       displayValue = value.format(TutorDateFormat)
-      wrapperClasses += ' disabled-datepicker'

     <div className={wrapperClasses}>
       <input type='text' disabled className={classes} value={displayValue}/>


initial code to auto expand calendar

initial code to auto expand calendar

--- src/components/tutor-input.cjsx
+++ src/components/tutor-input.cjsx
@@ -1,5 +1,6 @@
 React = require 'react'
 BS = require 'react-bootstrap'
+_ = require 'underscore'
 {DateTimePicker} = require 'react-widgets'

 TutorInput = React.createClass
@@ -30,13 +31,40 @@

 TutorDateInput = React.createClass

+  getInitialState: ->
+    {expandCalendar: false}
+
+  expandCalendar: ->
+    @setState({expandCalendar: true})
+
+  dateSelected: (value) ->
+    @setState({expandCalendar: false})
+    @props.onChange(value)
+
+  onToggle: (open) ->
+    console.log(open)
+
   render: ->
     classes = ['form-control']
     unless @props.value then classes.push('empty')
-

-      <input type='text' disabled className={classes.join(' ')} />
+    if @state.expandCalendar
+      @props.open = 'calendar'
+      @props.onToggle = @onToggle
+    else
+      @props.open = false
+
+    dateProps = _.map(@props, _.clone)
+    dateProps.onChange = @dateSelected
+
+    if (dateProps.onChange is @props.onChange)
+      console.log('same')
+    else
+      console.log('different')
+
+

+      <input type='text' onFocus={@expandCalendar} disabled className={classes.join(' ')} />

{@props.label}

-      <DateTimePicker {...@props}/>
+      <DateTimePicker {...dateProps}/>

 TutorTextArea = React.createClass


ensure attach method streams recent logs first

--- src/decking.coffee
+++ src/decking.coffee
@@ -142,6 +142,7 @@
       stream: true
       stdout: true
       stderr: true
+      logs: true
       tty: false

     iterator = (details, callback) ->


Prefer idiomatic '_.has' for testing existence of key

--- src/fs-plus.coffee
+++ src/fs-plus.coffee
@@ -455,11 +455,11 @@

   # Public: Returns true for extensions associated with compressed files.
   isCompressedExtension: (ext) ->
-    COMPRESSED_EXTENSIONS[ext] == true
+    _.has(COMPRESSED_EXTENSIONS, ext)

   # Public: Returns true for extensions associated with image files.
   isImageExtension: (ext) ->
-    IMAGE_EXTENSIONS[ext] == true
+    _.has(IMAGE_EXTENSIONS, ext)

   # Public: Returns true for extensions associated with pdf files.
   isPdfExtension: (ext) ->
@@ -467,7 +467,7 @@

   # Public: Returns true for extensions associated with binary files.
   isBinaryExtension: (ext) ->
-    BINARY_EXTENSIONS[ext] == true
+    _.has(BINARY_EXTENSIONS, ext)

   # Public: Returns true for files named similarily to 'README'
   isReadmePath: (readmePath) ->
@@ -477,7 +477,7 @@

   # Public: Returns true for extensions associated with Markdown files.
   isMarkdownExtension: (ext) ->
-    MARKDOWN_EXTENSIONS[ext] == true
+    _.has(MARKDOWN_EXTENSIONS, ext)

   # Public: Is the filesystem case insensitive?
   #


:memo: doc multiple package name support

--- src/install.coffee
+++ src/install.coffee
@@ -26,7 +26,7 @@
     options = optimist(argv)
     options.usage """

-      Usage: apm install [<package_name>]
+      Usage: apm install [<package_name>...]

       Install the given Atom package to ~/.atom/packages/<package_name>.


Check for gitPackageInfo before accessing properties

Signed-off-by: Michelle Tilley <19f7a7eb6786def4c39d6d86c40af5dbc6589663@github.com>

--- src/install.coffee
+++ src/install.coffee
@@ -530,9 +530,9 @@

     installPackage = (name, callback) =>
       gitPackageInfo = @getHostedGitInfo(name)
-      targetDir = path.join(@atomGitPackagesDirectory, gitPackageInfo.project)

       if gitPackageInfo
+        targetDir = path.join(@atomGitPackagesDirectory, gitPackageInfo.project)
         @installGitPackage gitPackageInfo, targetDir, (error) =>
           return callback(error) if error?
           pack =


Modified in browser at pixie.strd6.com

Modified in browser at pixie.strd6.com

--- src/metered.coffee
+++ src/metered.coffee
@@ -30,8 +30,6 @@
 # Since neither turbo maxTurbo were provided, they are both set to 100.

 </pre></code>
-
-@see GameObject

 Bounded module
 @name Bounded


Modified in browser at pixie.strd6.com

Modified in browser at pixie.strd6.com

--- src/metered.coffee
+++ src/metered.coffee
@@ -135,7 +135,7 @@
     height - Height of the meter
     position - An x, y object representing the position of the meter
     radius - Border radius of the meter
-    showName - Boolean to toggle whether or not to show
+    showName - Boolean to toggle whether or not to show the
   ###
   meter: (options={}) ->
     Object.reverseMerge options,


misc cleanups

misc cleanups

--- src/methods.coffee
+++ src/methods.coffee
@@ -93,9 +93,9 @@
     if not @access_flags.static
       converted_params.push params.shift()
     param_idx = 0
-    for p, idx in @param_types
+    for p in @param_types
       converted_params.push params[param_idx]
-      param_idx += if (@param_types[idx].toString() in ['J', 'D']) then 2 else 1
+      param_idx += if (p.toString() in ['J', 'D']) then 2 else 1
     try
       rv = func rs, converted_params...
     catch e
@@ -109,32 +109,34 @@
         trace "yielding from #{@class_type.toClassString()}::#{@name}#{@raw_descriptor}"
       throw e
     rs.meta_stack().pop()
-    unless @return_type.toString() == 'V'
-      if @return_type.toString() == 'Z' then rs.push rv + 0 # cast booleans to a Number
+    ret_type = @return_type.toString()
+    unless ret_type == 'V'
+      if ret_type == 'Z' then rs.push rv + 0 # cast booleans to a Number
       else rs.push rv
-      rs.push null if @return_type.toString() in [ 'J', 'D' ]
+      rs.push null if ret_type in [ 'J', 'D' ]

   run_bytecode: (rs, padding) ->
     # main eval loop: execute each opcode, using the pc to iterate through
     code = @code.opcodes
+    cf = rs.curr_frame()
     while true
       try
-        pc = rs.curr_pc()
+        pc = cf.pc
         op = code[pc]
         unless RELEASE? or util.log_level < util.STRACE
           throw "#{@name}:#{pc} => (null)" unless op
-          cf = rs.curr_frame()
           vtrace "#{padding}stack: [#{pa cf.stack}], local: [#{pa cf.locals}]"
           annotation =
             util.call_handler(opcode_annotators, op, pc, rs.class_lookup(@class_type).constant_pool) or ""
           vtrace "#{padding}#{@class_type.toClassString()}::#{@name}:#{pc} => #{op.name}" + annotation
         op.execute rs
-        rs.inc_pc(1 + op.byte_count)  # move to the next opcode
+        cf.pc += 1 + op.byte_count  # move to the next opcode
       catch e
         if e instanceof util.BranchException
-          rs.goto_pc e.dst_pc
+          cf.pc = e.dst_pc
           continue
         else if e instanceof util.ReturnException
+          vtrace "#{padding}stack: [#{pa cf.stack}], local: [#{pa cf.locals}] (method end)"
           rs.meta_stack().pop()
           rs.push e.values...
           break
@@ -148,9 +150,9 @@
               (eh.catch_type == "<any>" or types.is_castable rs, e.exception.type, c2t(eh.catch_type))
           if handler?
             trace "caught exception as subclass of #{handler.catch_type}"
-            rs.curr_frame().stack = []  # clear out anything on the stack; it was made during the try block
+            cf.stack = []  # clear out anything on the stack; it was made during the try block
             rs.push e.exception
-            rs.goto_pc handler.handler_pc
+            cf.pc = handler.handler_pc
             continue
           else # abrupt method invocation completion
             trace "exception not caught, terminating #{@name}"
@@ -215,5 +217,3 @@
     else
       trace "#{padding}entering method #{sig}"
       @run_bytecode runtime_state, padding
-    cf = runtime_state.curr_frame()
-    vtrace "#{padding}stack: [#{pa cf.stack}], local: [#{pa cf.locals}] (method end)"


Fix yield exception handling for natives. javac works!

--- src/methods.coffee
+++ src/methods.coffee
@@ -762,10 +762,14 @@
       param_idx += if (@param_types[idx].toString() in ['J', 'D']) then 2 else 1
     try
       rv = func rs, converted_params...
-    finally
-      # func may throw a JavaException (if it cannot handle it internally).
-      # In this case, pop the stack anyway but don't push a return value.
-      rs.meta_stack.pop()
+    catch e
+      # func may throw a JavaException (if it cannot handle it internally).  In
+      # this case, pop the stack anyway but don't push a return value.
+      # YieldExceptions should just terminate the function without popping the
+      # stack.
+      throw e unless e instanceof util.JavaException
+      return rs.meta_stack.pop()
+    rs.meta_stack.pop()
     unless @return_type instanceof types.VoidType
       if @return_type.toString() == 'J' then rs.push rv # longs are stored as objects
       else rs.push rv + 0 # cast booleans, etc to a Number


Update Atom disabled packages

Update Atom disabled packages

--- atom/config.cson
+++ atom/config.cson
@@ -10,12 +10,13 @@
     audioBeep: false
     disabledPackages: [
       "exception-reporting"
-      "linter"
+      "language-haml"
+      "linter-write-good"
       "language-rspec"
       "rails-snippets"
       "rails-transporter"
+      "react"
       "ruby-test"
-      "language-haml"
     ]
     ignoredNames: [
       ".bundle"


Make alt-cmd-n trigger new file when Tree View is focused

--- atom/keymap.cson
+++ atom/keymap.cson
@@ -176,6 +176,7 @@
   # Add a new file or folder (these are commands already invocable via the 'a'
   # and 'shift-a' keys, respectively, but these are alternative key bindings)
   'n': 'tree-view:add-file'
+  'alt-cmd-n': 'tree-view:add-file'
   'shift-N': 'tree-view:add-folder'

   # Remove the selected file or directory


implement dload, aload

implement dload, aload

--- src/opcodes.coffee
+++ src/opcodes.coffee
@@ -119,9 +119,6 @@
     rs.push null if @name.match /[ld]load/

 class root.LoadVarOpcode extends root.LoadOpcode
-  constructor: (name, params) ->
-    super name, params
-
   take_args: (code_array, constant_pool, @wide=false) ->
     if @wide
       @name += "_w"
@@ -228,6 +225,7 @@
     array = rs.get_obj(rs.pop()).array
     java_throw rs, 'java/lang/ArrayIndexOutOfBoundsException', "#{idx} not in [0,#{array.length})" unless 0 <= idx < array.length
     rs.push array[idx]
+    rs.push null if @name.match /[ld]aload/

 towards_zero = (a) ->
   Math[if a > 0 then 'floor' else 'ceil'](a)
@@ -299,7 +297,7 @@
   18: new root.LoadConstantOpcode 'ldc', { byte_count: 1 }
   19: new root.LoadConstantOpcode 'ldc_w', { byte_count: 2 }
   20: new root.LoadConstantOpcode 'ldc2_w', { byte_count: 2 }
-  21: new root.LoadVarOpcode 'iload', { execute: (rs) -> rs.push rs.cl(@var_num) }
+  21: new root.LoadVarOpcode 'iload'
   22: new root.LoadVarOpcode 'lload'
   23: new root.LoadVarOpcode 'fload'
   24: new root.LoadVarOpcode 'dload'
@@ -325,9 +323,9 @@
   44: new root.LoadOpcode 'aload_2'
   45: new root.LoadOpcode 'aload_3'
   46: new root.ArrayLoadOpcode 'iaload'
-  47: new root.Opcode 'laload'
+  47: new root.ArrayLoadOpcode 'laload'
   48: new root.ArrayLoadOpcode 'faload'
-  49: new root.Opcode 'daload'
+  49: new root.ArrayLoadOpcode 'daload'
   50: new root.ArrayLoadOpcode 'aaload'
   51: new root.ArrayLoadOpcode 'baload'
   52: new root.ArrayLoadOpcode 'caload'


removed console log

removed console log

--- apps/user/client/view.coffee
+++ apps/user/client/view.coffee
@@ -32,7 +32,6 @@
     receive_emails = if $(event.target).is ':checked' then true else false
     $('#settings-email-preferences input').not(event.target).prop('disabled', !receive_emails)
     opacity = if receive_emails then 1 else 0.3
-    console.log(opacity)
     $('#settings-email-preferences label').not("label[for=#{event.target.id}]").fadeTo("slow", opacity)


Remove Rivets.KeypathParser (there is a new tokenizer in Sightglass for this).

--- src/parsers.coffee
+++ src/parsers.coffee
@@ -1,24 +1,3 @@
-# Rivets.KeypathParser
-# --------------------
-
-# Parser and tokenizer for keypaths in binding declarations.
-class Rivets.KeypathParser
-  # Parses the keypath and returns a set of adapter interface + path tokens.
-  @parse: (keypath, interfaces, root) ->
-    tokens = []
-    current = {interface: root, path: ''}
-
-    for index in [0...keypath.length] by 1
-      chr = keypath.charAt index
-      if chr in interfaces
-        tokens.push current
-        current = {interface: chr, path: ''}
-      else
-        current.path += chr
-
-    tokens.push current
-    tokens
-
 # Rivets.ArgumentParser
 # ---------------------


Handle git add failing

Handle git add failing

--- src/publish.coffee
+++ src/publish.coffee
@@ -261,8 +261,10 @@
       process.stdout.write("#{message}\n")
       @setPackageName pack, name, =>
         @spawn 'git', ['add', 'package.json'], (addCode) =>
+          return callback('`git add package.json` failed') unless addCode is 0
+
           @spawn 'git', ['commit', '-m', "#{message}"], (code, stderr='', stdout='') =>
-            if code is 0 or addCode is 0
+            if code is 0
               callback()
             else
               callback('Failed to commit package.json')


comment code

comment code

--- src/service.coffee
+++ src/service.coffee
@@ -100,7 +100,7 @@
             .header('Referer', 'http://s.web2.qq.com/proxy.html?v=20110412001&callback=1&id=3')
             .header('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8')
             .post(data)((err, resp, body) =>
-                cb body
+                cb err, body
         )

     groupList: (cb)->
@@ -215,7 +215,7 @@
             .header('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8')
             .post(QueryString.stringify(params))((err, resp, body) ->
                 console.log 'send friend message', err, body
-                callback body
+                callback && callback body
             )

     sendToGroup: (msg, callback) ->
@@ -273,7 +273,7 @@
                 console.log 'send discussion group message', err, body
             )

-    online: ->
+    online: (callback)->
         rValue =
             status: 'online',
             ptwebqq: @authInfo.ptwebqq,
@@ -300,19 +300,18 @@
                     @emit 'error', 'online fail'

                 ret = JSON.parse(body)
-                if ret.retcode == 0
+                if ret.retcode is 0
                     console.log 'success'
                     @authInfo.psessionid = ret.result.psessionid
                     @authInfo.uin = ret.result.uin
                     @authInfo.vfwebqq = ret.result.vfwebqq
-                    @emit 'online'
-                else
-                    @emit 'error', 'online failed'
+
+                callback && callback(err, ret)
             )

     # discussionGroupMember: ->

-    poll:()->
+    poll: ->
         console.log "polling..."
         rValue =
             clientid: @authInfo.clientid
@@ -331,8 +330,17 @@
             .post(QueryString.stringify(params))((err, resp, body) =>
                 console.log 'poll return', body
                 @emit 'poll', err, body
-                #todo retcode 102 redo online
-        )
+                ret = JSON.parse body
+                if ret.retcode is 116
+                    console.log 'need refrsh ptweb'
+
+                if ret.retcode is 121
+                    @online()
+                    return
+        )
+
+    handleMessage: ->
+

     logout: ->
         @stop()
@@ -346,8 +354,7 @@
             .path('channel/logout2')
             .header('Cookie', @cookie())
             .post(QueryString.stringify(params))((err, resp, body) =>
-                console.log 'poll return', body
-                @emit 'poll', err, body
+                console.log 'logout return', body
         )

     stop: ->
@@ -370,7 +377,12 @@
             @friendInfo((data)->
                 console.log 'friendInfo', data
             )
-            @friendList((data)->
+            @friendList((err, data)->
+                if err is not null
+                    @emit 'error', err
+                    return
+                ret = JSON.parse(data)
+
                 console.log 'friendList', data
             )
             @groupList((data)->
@@ -383,19 +395,22 @@
             #     console.log 'groupMember',data
             # )

-            msg = Message.create('hi', {uin:})
-            @sendToFriend(msg, (data)->
-                console.log 'send msg', data
-            )
-            msg = Message.create('hiqun', {uin:})
-            @sendToGroup(msg, (data)->
-                console.log 'send group msg', data
-            )
-            msg = Message.create('hiqun', {uin:})
-            @sendToDiscussionGroup(msg, (data)->
-                console.log 'send discus group msg', data
-            )
-
-        @online()
+            # msg = Message.create('hi', {uin:})
+            # @sendToFriend(msg, (data)->
+            #     console.log 'send msg', data
+            # )
+            # msg = Message.create('hiqun', {uin:})
+            # @sendToGroup(msg, (data)->
+            #     console.log 'send group msg', data
+            # )
+            # msg = Message.create('hiqun', {uin:})
+            # @sendToDiscussionGroup(msg, (data)->
+            #     console.log 'send discus group msg', data
+            # )
+
+        @online((err, ret)=>
+            if err is null and ret.retcode is 0
+                @emit 'online'
+        )

 module.exports = Service


[logger] format date before each log

[logger] format date before each log

--- src/startup.coffee
+++ src/startup.coffee
@@ -18,7 +18,12 @@
 {spawn} = require 'child_process'
 Path    = require 'path'
 Fs      = require 'fs'
+Moment  = require 'moment'
 Config  = require './common/config'
+
+WriteLog  = (fd, data) =>
+    toLog = '[' + ((do Moment).format 'YYYY MMM DD hh:mm:ssa') + '] ' + data
+    Fs.writeSync fd, toLog, 0, toLog.length

 processes = []

@@ -28,10 +33,10 @@
     voicious          = spawn 'node', [(Path.join Config.Paths.Approot, 'lib', 'core', 'voicious.js')]
     voicious.stdout.on 'data', (data) =>
         process.stdout.write "#{data}"
-        Fs.writeSync voiciousAccessLog, data, 0, data.length
+        WriteLog voiciousAccessLog, data
     voicious.stderr.on 'data', (data) =>
         process.stderr.write "#{data}"
-        Fs.writeSync voiciousErrorLog, data, 0, data.length
+        WriteLog voiciousErrorLog, data
     processes.push voicious

 if Config.Restapi.Enabled
@@ -40,10 +45,10 @@
     rest          = spawn 'node', [(Path.join Config.Paths.Approot, 'lib', 'rest', 'api.js')]
     rest.stdout.on 'data', (data) =>
         process.stdout.write "#{data}"
-        Fs.writeSync restAccessLog, data, 0, data.length
+        WriteLog restAccessLog, data
     rest.stderr.on 'data', (data) =>
         process.stderr.write "#{data}"
-        Fs.writeSync restErrorLog, data, 0, data.length
+        WriteLog restErrorLog, data
     processes.push voicious

 if Config.Websocket.Enabled
@@ -52,10 +57,10 @@
     voicious    = spawn 'node', [(Path.join Config.Paths.Approot, 'lib', 'ws', 'websocket.js')]
     voicious.stdout.on 'data', (data) =>
         process.stdout.write "#{data}"
-        Fs.writeSync wsAccessLog, data, 0, data.length
+        WriteLog wsAccessLog, data
     voicious.stderr.on 'data', (data) =>
         process.stderr.write "#{data}"
-        Fs.writeSync wsErrorLog, data, 0, data.length
+        WriteLog wsErrorLog, data
     processes.push voicious

 process.on 'SIGINT', () =>


Changes to Calculations. fixes #6

Changes to Calculations. fixes #6

--- views/application.coffee
+++ views/application.coffee
@@ -248,7 +248,7 @@

   return sum

-table_change= (selector, german_name, columns, specialization=false, type="costs") ->
+table_change= (selector, german_name, columns, specialization=false, type="costs", costs_per_point = 1, extra_costs_for_maximum = false) ->
   unoccupated_rows = 0
   cost = 0
   $("##{selector} tbody tr").each ->
@@ -275,7 +275,10 @@
       if cost_cell.attr("value") == ""
         unoccupated_rows += 1
       else
-        cost += parseFloat(cost_cell.attr("value"))
+        cost_cell_value = parseFloat(cost_cell.attr("value"))
+        cost += (cost_cell_value * costs_per_point)
+        if extra_costs_for_maximum and cost_cell_value == 6
+          cost += 2
   if unoccupated_rows == 1
     row = $("<tr/>").append($("<th/>").append($("<input/>", {'type' : "text"})))

@@ -433,9 +436,11 @@
         if absolute_value < 0
           relative_value = 0
           absolute_value = 0
-        else if absolute_value > 6
+        else if absolute_value >= 6
           relative_value = 6 - group_value
           absolute_value = group_value + relative_value
+          # Points for maximum
+          cost += 2
         $(".relative", this).attr("value", relative_value)
         $(".absolute", this).attr("value", absolute_value)

@@ -449,12 +454,12 @@
       add_line_to_costs("skill_groups", "Fertigkeitengruppen", cost)

   $("#single_skills").delegate("input", "change", ->
-    table_change("single_skills", "Einzelne Fertigkeiten", 2, true)
+    table_change("single_skills", "Einzelne Fertigkeiten", 2, true, "costs", 4, true)
     table_change("single_skills", "Einzelne Fertigkeiten (Spez.)", 2, true, "specialize")
   )

   $("#spells").delegate("input", "change", ->
-    table_change("spells", "Zauber", 2)
+    table_change("spells", "Zauber", 2, false, "costs", 3)
   )

   $("#knowledge").delegate("input", "change", ->


indention

indention

--- public/Gruntfile.coffee
+++ public/Gruntfile.coffee
@@ -28,8 +28,9 @@
           config: 'config.rb'

     watch:
-      files: [ 'ts/*.ts' ]
-      tasks: [ 'compile' ]
+      ts:
+        files: [ 'ts/*.ts' ]
+        tasks: [ 'compile' ]

       sass:
         files: [ 'sass/style.scss' ]


Fixed wrong DOM nesting warning

Fixed wrong DOM nesting warning

--- views/services/welcome.cjsx
+++ views/services/welcome.cjsx
@@ -11,12 +11,14 @@

诶嘿！欢迎使用 poi v{POI_VERSION}！使用之前看看下面！

poi 不会修改任何游戏内的发包与收包，但是请使用可信的 poi 版本和可信的插件！

-
poi 默认不使用代理。更改代理的设置在设置面板中可以找到。
-

-
使用岛风go的选择HTTP代理，地址是127.0.0.1，端口8099。（默认情况下）

-
使用自己本地的Shadowsocks或者Socks5代理的选择Socks5代理。

-
使用VPN的选择不使用代理就好了。

-

+
poi 默认不使用代理。更改代理的设置在设置面板中可以找到。

+

+

+
使用岛风go的选择HTTP代理，地址是127.0.0.1，端口8099。（默认情况下）

+
使用自己本地的Shadowsocks或者Socks5代理的选择Socks5代理。

+
使用VPN的选择不使用代理就好了。

+

+

poi 如果有显示错误，可以手动调整一下内容大小，布局会自动适配。

如果 poi 的运行不流畅，可以在设置中关闭一部分插件，对插件的操作重启后生效。

更多帮助参考 poi wiki - https://github.com/poooi/poi/wiki


workaround strange MATH error

workaround strange MATH error

--- src/uapanfw.coffee
+++ src/uapanfw.coffee
@@ -200,8 +200,8 @@
     robot.logger.info logmsg

     for un in fwdata.notify
-      usermsg = usermsg.replace /^You/, un
-      usermsg = usermsg.replace /  Change will be applied in < 5 minutes./, ''
+      usermsg = usermsg.replace(/^You/, un)
+      #usermsg = usermsg.replace(/  Change will be applied in \< 5 minutes\./, '')
       robot.send { room: un }, usermsg unless un == who

     return
@@ -263,8 +263,8 @@
     robot.logger.info logmsg

     for un in fwdata.notify
-      usermsg = usermsg.replace /^You/, un
-      usermsg = usermsg.replace /  Change will be applied in < 5 minutes./, ''
+      usermsg = usermsg.replace(/^You/,un)
+      #usermsg = usermsg.replace(/  Change will be applied in \< 5 minutes\./, '')
       robot.send { room: un }, usermsg unless un == who or deltaN < 1

     return


Minor ui update.

Minor ui update.

--- src/ui/main.coffee
+++ src/ui/main.coffee
@@ -53,12 +53,8 @@
   delayedCompile =
     _.debounce (-> compile(inputFetcher, outputter)), 300

-  # Trigger the change event when a key is let go.
-  $input.on 'keyup', ->
-    $(@).trigger 'change'
-
   # Compile the input on change.
-  $input.on 'change', ->
+  $input.on 'keyup copy cut paste change', ->
     delayedCompile()

   # Compile the input for the first time.


Remove some whitespace

Remove some whitespace

--- atom.symlink/config.cson
+++ atom.symlink/config.cson
@@ -43,4 +43,3 @@
     'showOnStartup': false
   'metrics':
     'userId': 'b2c40195cf78d3ea68294861905eb853d111080e'
-


Update Atom settings

Update Atom settings

--- atom.symlink/config.cson
+++ atom.symlink/config.cson
@@ -8,7 +8,6 @@
     disabledPackages: [
       "Atom-Syntax-highlighting-for-Sass"
       "autocomplete-php"
-      "autoflow"
       "symbols-view"
       "regex-railroad-diagram"
       "busy"
@@ -16,8 +15,13 @@
       "linter-eslint"
       "php-integrator-call-tips-legacy-php56"
       "php-integrator-tooltips-legacy-php56"
-      "emmet"
       "whitespace"
+      "hard-wrap"
+      "linter-phpcs"
+      "php-integrator-annotations"
+      "php-integrator-navigation"
+      "php-integrator-tooltips"
+      "php-integrator-call-tips"
     ]
     ignoredNames: [
       ".git"
@@ -31,8 +35,8 @@
     openEmptyEditorOnStart: false
     telemetryConsent: "limited"
     themes: [
-      "seti-ui"
-      "seti-syntax"
+      "one-light-ui"
+      "solarized-light-syntax"
     ]
   editor:
     backUpBeforeSaving: true
@@ -59,10 +63,12 @@
       "scss-lint"
     ]
   "linter-phpcs":
+    autoConfigSearch: false
+    codeStandardOrConfigFile: "/Users/montchr/dev/spiritedmedia.dev/public/phpcs.ruleset.xml"
     executablePath: "/Users/montchr/dev/spiritedmedia.dev/public/vendor/bin/phpcs"
   "linter-phpmd": {}
   "linter-ui-default":
-    panelHeight: 195
+    panelHeight: 300
   marked: {}
   metrics:
     userId: "8d53384b4cba39680a039773c474de6a35e4e6a6"
@@ -70,13 +76,21 @@
     plugins:
       "find-and-replace": true
       "find-and-replaceDecorationsZIndex": 0
+  "package-sync":
+    createOnChange: true
   "php-integrator-autocomplete-plus":
     automaticallyAddUseStatements: false
   "php-integrator-base":
     core:
       phpCommand: "/usr/local/opt/php71/bin/php"
     linting:
+      enable: false
+      showMissingDocs: false
+      showUnknownClasses: false
       showUnknownGlobalConstants: false
+      showUnknownGlobalFunctions: false
+      showUnusedUseStatements: false
+      validateDocblockCorrectness: false
     phpCommand: "/usr/local/opt/php71/bin/php"
   "php-integrator-base:confirmed-upgrade-message": true
   "release-notes":


Atom configs

Atom configs

--- atom.symlink/config.cson
+++ atom.symlink/config.cson
@@ -1,4 +1,5 @@
 "*":
+  "advanced-new-file": {}
   "advanced-open-file":
     createDirectories: true
     createFileInstantly: true


atom config bump

atom config bump

--- atom.symlink/config.cson
+++ atom.symlink/config.cson
@@ -3,6 +3,7 @@
     'showIndentGuide': true
     'fontFamily': 'Menlo'
     'fontSize': 15
+    'invisibles': {}
   'core':
     'ignoredNames': [
       '.bundle'
@@ -32,4 +33,3 @@
     'showOnStartup': false
   'release-notes':
     'viewedVersion': '0.89.0'
-  'go-plus': {}


refactoring using more specific methods to later handle projects as well

--- scripts/asana-info.coffee
+++ scripts/asana-info.coffee
@@ -19,50 +19,64 @@
 #   mxlje

 asana_api_key = process.env.HUBOT_ASANA_API_KEY
+asana_auth    = 'Basic ' + new Buffer("#{asana_api_key}:").toString('base64')

-# template for response
-response = (task) ->
+asana_task_endpoint = (task_id) ->
+  "https://app.asana.com/api/1.0/tasks/#{task_id}"
+
+asana_project_endpoint = (project_id) ->
+  "https://app.asana.com/api/1.0/projects/#{project_id}"
+
+# templates for response
+task_response = (task) ->
   """
   > **#{task.status} #{task.title} (#{task.assignee})**
   > #{task.notes}
   """

+
+
+get_task = (task_id, robot, msg) ->
+  robot.http(asana_task_endpoint task_id)
+    .header("Authorization", asana_auth)
+    .get() (err, res, body) ->
+
+      # basic error handling
+      if err
+       msg.send "Something went wrong: #{err}"
+       return
+
+      if res.statusCode != 200
+       msg.send "Asana returned HTTP #{res.statusCode}: #{JSON.parse(body).errors[0].message}"
+       return
+
+      # parse the response body
+      data = JSON.parse(body).data
+
+      # extract and reformat data from response
+      task =
+       title:    data.name
+       status:   if data.completed then "[✓]" else "[ ]"
+       assignee: if data.assignee then "#{data.assignee.name}" else "unassigned"
+
+      # clip notes at first paragraph
+      if data.notes.length > 0
+       split = data.notes.split("\n")
+       task.notes = if split.length > 1 then "#{split[0]} …" else data.notes
+      else
+       task.notes = "(no description)"
+
+      # send the finished markdown down the pipe
+      msg.send task_response(task)
+
+
+
+# listen for Asana deeplinks
 module.exports = (robot) ->
   robot.hear /app\.asana\.com\/\d{1}\/\d+\/(\d+)/i, (msg) ->

     # extract task ID from URL
     task_id = msg.match[1]
-    req_uri = "https://app.asana.com/api/1.0/tasks/#{task_id}"
-    auth    = 'Basic ' + new Buffer("#{asana_api_key}:").toString('base64')
+    req_uri = asana_task_endpoint task_id

-    robot.http(req_uri)
-      .header("Authorization", auth)
-      .get() (err, res, body) ->
-
-        # basic error handling
-        if err
-          msg.send "Something went wrong: #{err}"
-          return
-
-        if res.statusCode != 200
-          msg.send "Asana returned HTTP #{res.statusCode}: #{JSON.parse(body).errors[0].message}"
-          return
-
-        # parse the response body
-        data = JSON.parse(body).data
-
-        # extract and reformat data from response
-        task =
-          title:    data.name
-          status:   if data.completed then "[✓]" else "[ ]"
-          assignee: if data.assignee then "#{data.assignee.name}" else "unassigned"
-
-        # clip notes at first paragraph
-        if data.notes.length > 0
-          split = data.notes.split("\n")
-          task.notes = if split.length > 1 then "#{split[0]} …" else data.notes
-        else
-          task.notes = "(no description)"
-
-        # send the finished markdown down the pipe
-        msg.send response(task)
+    get_task task_id, robot, msg


Revert "Make window.FACTLINK equal to the Factlink object in the iframe, no funny proxy methods. Use other explicit names for the other things window.FACTLINK was used for"

This reverts commit 669fbd077e18f2122d1552b60cbab09cf97183b7.

--- js-library/app/js/loader.coffee
+++ js-library/app/js/loader.coffee
@@ -1,5 +1,4 @@
-return if window.FACTLINK_LOADED?
-window.FACTLINK_LOADED = true
+return if window.FACTLINK?

 #### Create iframe

@@ -45,12 +44,23 @@

   coreScriptTag.onload = coreScriptTag.onreadystatechange = null

-  window.FACTLINK = iframe.contentWindow.Factlink
+  proxy = (func) ->
+    window.FACTLINK[func] = ->
+      iframe.contentWindow.Factlink[func].apply iframe.contentWindow.Factlink, arguments
+
+  proxy 'on'
+  proxy 'off'
+  proxy 'hideDimmer'
+  proxy 'triggerClick'
+  proxy 'stopAnnotating'
+  proxy 'getSelectionInfo'
+
   jQuery?(window).trigger 'factlink.libraryLoaded'

 #### Load iframe with script tag

-window.FACTLINK_ON_IFRAME_LOAD = ->
+window.FACTLINK = {}
+window.FACTLINK.iframeLoaded = ->
   iframe.contentWindow.document.head.appendChild coreScriptTag

 iframeDoc = iframe.contentWindow.document
@@ -59,7 +69,7 @@
   <!DOCTYPE html>

 """


double quote -> single quote

double quote -> single quote

--- app.coffee
+++ app.coffee
@@ -51,7 +51,7 @@
   dest:path.join(__dirname, 'public')
   force:true # WARN: only for debug
   preprocess: path: (p) -> p.replace /stylesheets/, 'less'
-  postprocess: css: (css) -> "/* DO NOT EDIT THIS FILE. Look for `/less` directory instead! */\n" + css
+  postprocess: css: (css) -> '/* DO NOT EDIT THIS FILE. Look for `/less` directory instead! */\n' + css

 app.use favicon path.join process.cwd(), 'public/favicon.ico'
 app.use express.static path.join(__dirname, 'public'), maxAge:300
@@ -62,14 +62,14 @@

 attachGithubRepo = (repoName) ->
-  fullRepoName = app.get("github name") + "/" + repoName
+  fullRepoName = app.get('github name') + '/' + repoName
   getGithub = (type, callback) ->
     request
       headers: 'User-Agent': 'node.js'
       url: app.get('github ' + type + ' url').replace /%s/g, fullRepoName
     , callback

-  camelCaseName = repoName.replace(/-/g, "")
+  camelCaseName = repoName.replace(/-/g, '')
   localPath = '/' + camelCaseName

   app.get localPath, (req, res) ->
@@ -95,12 +95,12 @@
   name: camelCaseName.replace /([a-z])([A-Z])/g, '$1 $2'

 app.locals.repos = [
-  attachGithubRepo "Pretty-Binary-Clock"
-  attachGithubRepo "BitcoinMonitor"
-  attachGithubRepo "Tabs-Butcher"
-  attachGithubRepo "Weather-Happy"
-  attachGithubRepo "Dvorak-Programmer"
-  attachGithubRepo "Chrome-Bitcoin-Monitor"
+  attachGithubRepo 'Pretty-Binary-Clock'
+  attachGithubRepo 'BitcoinMonitor'
+  attachGithubRepo 'Tabs-Butcher'
+  attachGithubRepo 'Weather-Happy'
+  attachGithubRepo 'Dvorak-Programmer'
+  attachGithubRepo 'Chrome-Bitcoin-Monitor'
 ]

 # prefix relative picture urls and support youtube links
@@ -118,10 +118,10 @@
       ) + '
'

     else
-      href = "/post-content/" + href unless href.startsWithAny [ "http", "/images" ]
+      href = "/post-content/" + href unless href.startsWithAny [ 'http', '/images' ]
       new Renderer().image href, title, text

-  ) + ""
+  ) + ''

 marked.setOptions
@@ -129,7 +129,7 @@
   gfm: true
   sanitize: true
   smartypants: true
-  highlightClass: "hljs"
+  highlightClass: 'hljs'
   highlight: (code, lang) ->
     if lang?
       hljs.highlight(lang, code).value
@@ -163,5 +163,5 @@
     res.render 'rss', posts: posts

 app.listen app.get('port'), ->
-  console.log "Express server listening on port " + app.get 'port'
+  console.log 'Express server listening on port ' + app.get 'port'


Extended Content-Security-Policy permission for css in Safari

--- app.coffee
+++ app.coffee
@@ -43,7 +43,7 @@

 # load all resources only from current origin (but not its sub-domains)
 app.use (req, res, next) ->
-  res.setHeader("Content-Security-Policy", "default-src 'self'")
+  res.setHeader("Content-Security-Policy", "default-src 'self'; style-src 'self' 'unsafe-inline'")
   res.setHeader("X-Frame-Options", "sameorigin")
   next()


Properly handle missing callback in readPackages

--- app.coffee
+++ app.coffee
@@ -175,11 +175,11 @@
 		if err?
 			debug "Update failed:", err
 			auth = packageList = undefined
-			callback err
+			callback? err
 		else
 			debug "Finished update"
 			[ auth, packageList ] = results
-			callback null
+			callback? null

 askForCredentials = (req, res) ->
 	res.type 'txt'


install now button menu fixed

install now button menu fixed

--- client/landing/app/Applications/Apps.kdapplication/Views/appview.coffee
+++ client/landing/app/Applications/Apps.kdapplication/Views/appview.coffee
@@ -97,15 +97,10 @@

     if app.versions?.length > 1
-      menu =
-        type : "contextmenu"
-        items : []
+      menu = {}

       for version,i in app.versions
-        menu.items.push
-          id       : i
-          title    : "Install version #{version}"
-          parentId : null
+        menu["Install version #{version}"] =
           callback : (item)=>
             appsController.installApp app, app.versions[item.data.id], (err)=>
               if err then warn err
@@ -118,7 +113,7 @@
           diameter: 30
           color   : "#ffffff"
         delegate      : @
-        menu          : [menu]
+        menu          : menu
         callback      : ->
           appsController.installApp app, 'latest', (err)=>
             @hideLoader()


adding crucial module.exports

adding crucial module.exports

--- src/watcher.coffee
+++ src/watcher.coffee
@@ -169,3 +169,5 @@
 # rl.question 'Press enter to exit', (answer) ->
 #   rl.close()
 #   return
+
+module.exports = Watcher;


cleaning up

cleaning up

--- static/main.coffee
+++ static/main.coffee
@@ -377,9 +377,6 @@
       # has this cell already been run and we're switching it to idle
       if @cells[cell_id]['last_msg_id'] and state is @idle_state
         state = @ran_state
-      # console.log @cells[cell_id]
-      # if state is @interrupt
-        # @cells[cell_id]["output_area"].clear_output(true)
       $(".thebe_controls[data-cell-id=#{cell_id}]").html @controls_html(state)


only pass collections to renderEmpty()

only pass collections to renderEmpty()

--- lib/sensu-dashboard/assets/javascripts/views/list.coffee
+++ lib/sensu-dashboard/assets/javascripts/views/list.coffee
@@ -14,13 +14,16 @@
       view = new kls(model: model, name: @itemName)

     initialize: ->
-      @listenTo(@collection, "remove", @renderEmpty)
+      @listenTo(@collection, "remove", @removeItem)
       @listenTo(@collection, "reset", @render)
       @listenTo(@collection, "add", @render)

     addItem: (item) ->
       @renderItem(item)
       @collection.sort()
+
+    removeItem: (item, collection = @collection) ->
+      @renderEmpty(collection)

     renderItem: (item) ->
       item_view = @itemView(item)


add a connection ack

add a connection ack


minor change of code

minor change of code


optimize tests

optimize tests

--- test/common.coffee
+++ test/common.coffee
@@ -1,5 +1,5 @@
-assert = require('assert')
 DoLater = require('..')
+mongoPool = require('mongo-pool2')

 config =
   host: 'localhost'
@@ -14,9 +14,9 @@
     new DoLater config

   beforeEach: (done) ->
-    mongoPool = require('mongo-pool2')

     mongoPool.connect config, (err, db) ->
       if err
         return done err
-      db.collection(config.collection).remove {}, done+      db.collection(config.collection).remove {}, done
+    , true


Modified in browser at pixie.strd6.com

Modified in browser at pixie.strd6.com

--- test/engine.coffee
+++ test/engine.coffee
@@ -181,6 +181,6 @@
   engine.collides(Rectangle(0, 0, 10, 10), null)

 test "#setState", ->
-  engine
+  engine = E

 module()


Modified in browser at pixie.strd6.com

Modified in browser at pixie.strd6.com

--- test/engine.coffee
+++ test/engine.coffee
@@ -183,6 +183,7 @@
 test "Integration", ->
   engine = Engine()

+
 test "#setState", 3, ->
   engine = Engine()


Follow mixin

Follow mixin

--- test/follow.coffee
+++ test/follow.coffee
@@ -16,7 +16,7 @@
   enemy.include(Follow)
   enemy.follow(player)

-  ok enemy.I.velocity.equal(Point(1, 0)), 'enem'
+  ok enemy.I.velocity.equal(Point(1, 0)), 'enemy should '

   fastEnemy = GameObject
     x: 50


Follow mixin

Follow mixin

--- test/follow.coffee
+++ test/follow.coffee
@@ -39,6 +39,6 @@
   rightEnemy.include(Follow)
   rightEnemy.follow(player)

-  ok rightEnemy.I.velocity.equal(Point())
+  ok rightEnemy.I.velocity.equal(Point(-1, 0))

 module()


Rollback version when update fails

Rollback version when update fails

--- server/lib/applications.coffee
+++ server/lib/applications.coffee
@@ -118,6 +118,7 @@
     update: (app, callback) ->
         data = {}
         manifest = new Manifest()
+        previousVersion = app.version

         # Get updated manifest.
         manifest.download app, (err) ->
@@ -154,7 +155,12 @@
                 data.iconType = iconInfos?.extension or null

                 # Run the application process based on collected data.
-                appHelpers._runUpdate app, data, iconInfos, access, callback
+                appHelpers._runUpdate app, data, iconInfos, access, (err) ->
+                    if err
+                        app.updateAttributes version: previousVersion, ->
+                            callback err
+                    else
+                        callback()

     # Check if an update is required then returns an object with two flags


FIX: lastUpdate handling

FIX: lastUpdate handling

--- client/app/components/compose.coffee
+++ client/app/components/compose.coffee
@@ -119,6 +119,11 @@
         # Focus Element
         @handleFocus()

+        # Each state:change do not send data to server
+        # update date for client modifications
+        @state.date = new Date().toISOString() unless @state.date
+        @state.lastUpdate = @state.date unless @state.lastUpdate
+
     componentDidUpdate: ->
         # Initialize @state
         # with values from server
@@ -127,14 +132,15 @@
         # Focus Element
         @handleFocus()

-        # Save client changes
+        # Each state:change do not send data to server
+        # update date for client modifications
         @state.lastUpdate = new Date().toISOString()

     hasChanged: (props, state) ->
         @state.lastUpdate isnt @state.date

     resetChange: ->
-        @state.lastUpdate isnt @state.date
+        @state.lastUpdate = @state.date

     componentWillUnmount: ->
         MessageStore.removeListener 'change', @_setStateFromStores
@@ -188,9 +194,9 @@
             editor.removeEventListener 'click', @saveFocus

     closeSaveDraft: ->
-        fetch = (message) =>
+        fetch = =>
             # reload conversation to update its length
-            if (cid = message.conversationID)
+            if (cid = @state.conversationID)
                 MessageActionCreator.fetchConversation cid

         save = =>
@@ -200,11 +206,11 @@
                     LayoutActionCreator.alertError msg
                     return

-                fetch message
+                fetch()

         # Fetch
         unless @hasChanged()
-            fetch @state
+            fetch()
             return

         # Do not ask for save
@@ -329,6 +335,7 @@
     # conversation ID and message ID. These infor are collected via current
     # selection and message information.
     finalRedirect: ->
+
         if @props.inReplyTo? and not _.isString @props.inReplyTo
             conversationID = @state.conversationID
             accountID = @props.selectedAccountID
@@ -372,7 +379,7 @@

         doDelete = =>
             # Do not try to save client changes
-            # when componentWillUnmount
+            # After deleting message
             @resetChange()

             messageID = @state.id
@@ -398,7 +405,12 @@
     sendMessage: (event) ->
         event.preventDefault() if event?
         @state.isDraft = false
+
         @sendActionMessage (error, message) =>
+            # Do not try to save client changes
+            # after Sending message
+            @resetChange()
+
             if error
                 msgKo = t "message action sent ko"
                 LayoutActionCreator.alertError "#{msgKo} #{error}"
@@ -437,7 +449,6 @@

             # Check for Updates
             @state.mailboxIDs = message.mailboxIDs
-            @props.lastUpdate = message.date

             # Refresh URL
             # to save temporary info


Welcome: simplify and clear the check flow

--- client/home/lib/welcome/index.coffee
+++ client/home/lib/welcome/index.coffee
@@ -27,20 +27,14 @@
       cssClass : 'bullets clearfix'

     { groupsController, computeController } = kd.singletons
-    { stacks }                              = computeController

-    view  = this
+    computeController.ready =>
+      if groupsController.canEditGroup()
+      then @putAdminBullets()
+      else @putUserBullets()

-    groupsController.ready -> computeController.ready ->

-      { providers, variables } = collectCredentials()

-      groupsController.getCurrentGroup().fetchMyRoles (err, roles) ->
-        return  kd.warn err  if err
-        isAdmin = 'admin' in (roles ? [])
-        if isAdmin
-        then view.putAdminBullets()
-        else view.putUserBullets()

   putAdminBullets: ->


Edit basic javascript for posting suggestions

--- js/script.coffee
+++ js/script.coffee
@@ -22,6 +22,8 @@
 getSectionTitle = () -> getDateString() + "-" + getGoogleAnalyticsId()

 settings = (text) ->
+  action: "edit"
+  format: "json"
   pageid: 9
   section: "new"
   sectiontitle: getSectionTitle()


Fix tests

Fix tests

--- spec/react-grammar-spec.coffee
+++ spec/react-grammar-spec.coffee
@@ -95,7 +95,7 @@
   describe "operators", ->
     it "tokenizes void correctly", ->
       {tokens} = grammar.tokenizeLine('void')
-      expect(tokens[0]).toEqual value: 'void', scopes: ['source.js.jsx', 'keyword.operator.js']
+      expect(tokens[0]).toEqual value: 'void', scopes: ['source.js.jsx', 'keyword.operator.void.js']

     it "tokenizes the / arithmetic operator when separated by newlines", ->
       lines = grammar.tokenizeLines """


Add regexp escape to search

Add regexp escape to search

--- src/controllers/torrents.coffee
+++ src/controllers/torrents.coffee
@@ -5,7 +5,7 @@
 Categories = require('../models/categories')

 Torrent = require('../models/torrents')
-
+regex_escape = (str) -> str.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&")

 exports.list = (req, res) ->
   query = {}
@@ -15,7 +15,7 @@
     searchtext = req.query.searchtext
     searchterms = searchtext.split(' ')
     searchterms = searchterms.map (t) ->
-      new RegExp t, 'i'
+      new RegExp regex_escape(t), 'i'

     query['title'] = {'$all' : searchterms}


Fix dumb getImage bug

Fix dumb getImage bug

--- src/core/LiterallyCanvas.coffee
+++ src/core/LiterallyCanvas.coffee
@@ -395,7 +395,7 @@
       if @width == INFINITE then 0 else @width,
       if @height == INFINITE then 0 else @height)

-  getImage: (opts) ->
+  getImage: (opts={}) ->
     opts.includeWatermark ?= true
     opts.scaleDownRetina ?= true
     opts.scale ?= 1


added options.this as *this* for call

added options.this as *this* for call

--- lib/chain-builder.coffee
+++ lib/chain-builder.coffee
@@ -33,8 +33,9 @@
       return (context={}) ->                  # return new function, the chain
         for fn in array                       # loop over provided functions
           okay = do (fn) ->                   # run in own scope, hold return result
+            itsThis = fn?.options?.this ? context
             try                               # grab errors in chain calls
-              return fn.call context, context # calls function with context=this
+              return fn.call itsThis, context # calls function with context=itsThis
             catch e
               console.log 'chain: error', e   # report to console. TODO: remove?
               context.chainError = e          # store error in context
@@ -73,8 +74,9 @@
       i = 0                                   # start with first fn in array
       caller = (next, context) ->             # new fn calls their fn
         fn = array[i]                         # get next function
+        itsThis = fn?.options?.this ? context
         try                                   # catch errors from call
-          return fn.call context, next, context # call: context=this
+          return fn.call itsThis, next, context # call: context=itsThis
         catch e
           console.log 'pipeline: error', e    # report to console. TODO: remove?
           context.chainError = e              # store error in context


exec: fix after latest paramaters

exec: fix after latest paramaters

--- lib/commands/exec.coffee
+++ lib/commands/exec.coffee
@@ -22,7 +22,7 @@
       @system.execute
         relax: true
         sudo: not isRoot
-        cmd: params.subcommand
+        cmd: params.subcommand.map((c) -> "\"#{c}\"").join ' '
       , (err, {stdout, stderr}) ->
         write if err
         then "\x1b[31m#{node.fqdn} (exit code #{err.code})\x1b[39m\n"


fbp-protocol: Add missing .graph values

fbp-protocol: Add missing .graph values

--- lib/commandstream.coffee
+++ lib/commandstream.coffee
@@ -307,27 +307,30 @@

 responses = {}
 # Must be named the same as defined in the commands
-responses.NetworkStopped = () ->
+responses.NetworkStopped = (componentLib, graph) ->
   m =
       protocol: "network"
       command: "stopped"
       payload:
+          graph: graph.name
           running: false
           started: false
   return m
-responses.NetworkStarted = () ->
+responses.NetworkStarted = (componentLib, graph) ->
   m =
     protocol: "network"
     command: "started"
     payload:
+      graph: graph.name
       running: true
       started: true
   return m
-responses.NodesCleared = () ->
+responses.NodesCleared = (componentLib, graph) ->
   m =
     protocol: "graph"
     command: "clear"
-    payload: {}
+    payload:
+      id: graph.name
   return m
 responses.NetworkStatus = (componentLib, graph, cmdData) ->
   running = cmdData.readUInt8(0) == 1
@@ -348,6 +351,7 @@
     payload:
       id: nodeName
       component: component
+      graph: graph.name
   return m
 responses.NodeRemoved = (componentLib, graph, cmdData) ->
   nodeName = nodeNameById(graph.nodeMap, cmdData.readUInt8(1))
@@ -356,6 +360,7 @@
     command: 'removenode'
     payload:
       id: nodeName
+      graph: graph.name
   return m

 responses.NodesConnected = (componentLib, graph, cmdData) ->
@@ -364,6 +369,7 @@
     protocol: 'graph'
     command: 'addedge'
     payload:
+      graph: graph.name
       src:
         node: null
         port: null
@@ -377,6 +383,7 @@
     protocol: 'graph'
     command: 'removeedge'
     payload:
+      graph: graph.name
       src:
         node: null
         port: null


correct copy+paste typo, use context

correct copy+paste typo, use context

--- lib/create-server.coffee
+++ lib/create-server.coffee
@@ -10,7 +10,7 @@
     creator = net
     which = 'connection'

-  @server = creator.createServer options
+  @server = creator.createServer context

   if @onConnect? then @server.on 'connection', @onConnect
   if @onSecureConnect? then @server.on 'secureConnection', @onSecureConnect


Allow street lights to be not connected

Allow street lights to be not connected

--- components/ConvertStreetLight.coffee
+++ components/ConvertStreetLight.coffee
@@ -28,6 +28,7 @@

   convertLight: (light, colors) ->
     for color, idx in colors
+      continue unless @outPorts.ports["street#{light}"].isAttached idx
       @outPorts.ports["street#{light}"].send color, idx

   convert: (data) ->


fix embedded map

fix embedded map

--- components/embedded_map/index.coffee
+++ components/embedded_map/index.coffee
@@ -1,10 +1,10 @@
 sd = require('sharify').data
-return unless sd.GOOGLE_MAPS_API_KEY
 mapapi = require('google-maps-api')(sd.GOOGLE_MAPS_API_KEY)
 geocode = require('google-maps-api/geocode')

 module.exports =
   init: ({ location, id }) ->
+    return unless sd.GOOGLE_MAPS_API_KEY

     mapapi().then ->
       if location.get('coordinates')


modals default height fixed

modals default height fixed

--- components/modals/KDModalView.coffee
+++ components/modals/KDModalView.coffee
@@ -3,7 +3,7 @@
     options = $.extend
       overlay        : no            # a Boolean
       overlayClick   : yes           # a Boolean
-      height         : 300           # a Number for pixel value or a String e.g. "100px" or "20%"
+      height         : "auto"        # a Number for pixel value or a String e.g. "100px" or "20%" or "auto"
       width          : 400           # a Number for pixel value or a String e.g. "100px" or "20%"
       position       : {}            # an Object holding top and left values
       title          : null          # a String of text or HTML
@@ -60,9 +60,12 @@
     </div>"

   setButtons:(buttonDataSet)->
+
+    @buttons or= {}
     @setClass "with-buttons"
-    for own buttonTitle,buttonOptions of buttonDataSet
-      button = @createButton buttonTitle,buttonOptions
+    for own buttonTitle, buttonOptions of buttonDataSet
+      button = @createButton buttonTitle, buttonOptions
+      @buttons[buttonTitle] = button
       if buttonOptions.focus
         focused = yes
         button.$().trigger "focus"
@@ -116,10 +119,12 @@
         @destroy()

   createButton:(title,buttonOptions)->
-    @buttonHolder.addSubView button = new KDButtonView
-      title       : title
-      style       : buttonOptions.style     if buttonOptions.style?
-      callback    : buttonOptions.callback  if buttonOptions.callback?
+
+    buttonOptions.title = title
+    @buttonHolder.addSubView button = new KDButtonView buttonOptions
+      # title       : title
+      # style       : buttonOptions.style     if buttonOptions.style?
+      # callback    : buttonOptions.callback  if buttonOptions.callback?
     button.registerListener KDEventTypes:'KDModalShouldClose', listener:@, callback:->
       @propagateEvent KDEventType:'KDModalShouldClose'
     button


Localized the FF CORS patch to solve jQuery loading dependency and a bunch of IE7 bugs

--- lib/assets/javascripts/firehose/long_poll.js.coffee
+++ lib/assets/javascripts/firehose/long_poll.js.coffee
@@ -42,12 +42,34 @@
     data.last_message_sequence = @_lastMessageSequence
     # TODO: Some of these options will be deprecated in jQurey 1.8
     #       See: http://api.jquery.com/jQuery.ajax/#jqXHR
+
     $.ajax @config.longPoll.url,
       crossDomain: true
       data: data
       timeout: @_timeout
       success: @_success
       error: @_error
+      xhr: ->
+        # TODO - This while `xrh` attr is a stupid hack to deal with CORS short-comings in jQuery in Firefox.
+        # This ticket can be viewed at http://bugs.jquery.com/ticket/10338. Once jQuery is
+        # upgraded to this version, we can probably remove this, but be sure you test the
+        # crap out of Firefox!
+        #
+        # Its also worth noting that I had to localize this monkey-patch to the Firehose.LongPoll
+        # consumer because a previous global patch on jQuery.ajaxSettings.xhr was breaking regular IE7
+        # loading. I figured its better to localize this anyway to solve that problem and loading order issues.
+        xhr = jQuery.ajaxSettings.xhr()
+        getAllResponseHeaders = xhr.getAllResponseHeaders
+        xhr.getAllResponseHeaders = ->
+          allHeaders = getAllResponseHeaders.call(xhr)
+          return allHeaders if allHeaders
+          allHeaders = ""
+          for headerName in [ "Cache-Control", "Content-Language", "Content-Type", "Expires", "Last-Modified", "Pragma" ]
+            do (headerName) ->
+              allHeaders += headerName + ": " + xhr.getResponseHeader(headerName) + "\n"  if xhr.getResponseHeader(headerName)
+          allHeaders
+        xhr
+
       complete: (jqXhr) =>
         # Get the last sequence from the server if specified.
         if jqXhr.status == 200


improve reliability LongPoll transport's connected/disconnected events

--- lib/assets/javascripts/firehose/long_poll.js.coffee
+++ lib/assets/javascripts/firehose/long_poll.js.coffee
@@ -26,14 +26,7 @@
     @_lagTime         = 5000
     @_timeout         = @config.longPoll.timeout + @_lagTime
     @_okInterval      = 0
-    @_isConnected     = false
     @_stopRequestLoop = false
-
-  connect: (delay = 0) =>
-    unless @_isConnected
-      @_isConnected = true
-      @config.connected()
-    super(delay)

   getLastMessageSequence: =>
     @_lastMessageSequence or 0
@@ -60,7 +53,9 @@
     @_stopRequestLoop = true

   _success: (data, status, jqXhr) =>
-    @_open data unless @_succeeded
+    if @_needToNotifyOfReconnect or not @_succeeded
+      @_needToNotifyOfReconnect = false
+      @_open data
     return if @_stopRequestLoop
     if jqXhr.status is 200
       # Of course, IE's XDomainRequest doesn't support non-200 success codes.
@@ -76,17 +71,21 @@
     # jQuery CORS doesn't support timeouts and there is no way to access xhr2 object
     # directly so we can't manually set a timeout.
     $.ajax
-      url: @config.longPoll.url
-      method: 'HEAD'
-      crossDomain: true
-      data: @config.params
-      success: @config.connected
+      url:          @config.longPoll.url
+      method:       'HEAD'
+      crossDomain:  true
+      data:         @config.params
+      success:      =>
+        if @_needToNotifyOfReconnect
+          @_needToNotifyOfReconnect = false
+          @config.connected @

   # We need this custom handler to have the connection status
   # properly displayed
   _error: (jqXhr, status, error) =>
-    @_isConnected = false
-    @config.disconnected()
+    unless @_needToNotifyOfReconnect
+      @_needToNotifyOfReconnect = true
+      @config.disconnected()
     unless @_stopRequestLoop
       # Ping the server to make sure this isn't a network connectivity error
       setTimeout @_ping, @_retryDelay + @_lagTime


dynamise fixed client title in finish panel

--- src/coffee/finish_panel.coffee
+++ src/coffee/finish_panel.coffee
@@ -32,7 +32,7 @@
         or

-          Install Instacast from the App Store
+          Install {{title}} from the App Store


Corrige bug de exibição devido ao hideAll de preço

--- src/coffee/portal-price.coffee
+++ src/coffee/portal-price.coffee
@@ -72,8 +72,15 @@
 				@element.html out
 				@update()

+	hideAllPrice: =>
+		@hideBestPrice()
+		@hideListPrice()
+		@hideSavings()
+		@hideCashPrice()
+		@hideInstallments()
+
 	update: =>
-		@hideAll()
+		@hideAllPrice()
 		sku = @getSku()

 		if sku.available
@@ -86,13 +93,6 @@
 			if sku.installments? and sku.installments > 1
 				@showInstallments()
 				@showCashPrice()
-
-	hideAll: =>
-		@hideBestPrice()
-		@hideListPrice()
-		@hideSavings()
-		@hideCashPrice()
-		@hideInstallments()

 	bindEvents: =>
 		@bindProductEvent 'vtex.sku.selected', @skuSelected


Attempt to preserve selection using the best data available

--- src/trix/models/selection_manager.coffee
+++ src/trix/models/selection_manager.coffee
@@ -69,12 +69,22 @@
       @setLocationRange(lockedLocationRange) if lockedLocationRange?

   preserveSelection: (block) ->
-    return block() unless endPoints = @getSelectionEndPoints()
-    point = endPoints[0]
+    endPoints = @getSelectionEndPoints()
     locationRange = @getLocationRange()
     block()
-    locationRangeAtPoint = @getLocationRangeAtPoint(point)
-    @setLocationRange(locationRangeAtPoint ? locationRange)
+
+    if endPoints
+      start = @getLocationRangeAtPoint(endPoints[0])
+      end = @getLocationRangeAtPoint(endPoints[1])
+
+    if start and end
+      @setLocationRange(start, end)
+    else if start
+      @setLocationRange(start)
+    else if end
+      @setLocationRange(end)
+    else if locationRange
+      @setLocationRange(locationRange)

   clearSelection: ->
     getDOMSelection()?.removeAllRanges()


Add Atom React package

Add Atom React package

--- atom/packages.cson
+++ atom/packages.cson
@@ -22,6 +22,7 @@
   "pane-layout-plus"
   "rails-snippets"
   "rails-transporter"
+  "react"
   "ruby-test"
   "split-diff"
 ]


Add PHP snippet for non-negated call to empty()

--- atom/snippets.cson
+++ atom/snippets.cson
@@ -378,6 +378,10 @@
     'prefix': 'else'
     'body': 'else {\n\t$1\n}'

+  'empty':
+    'prefix': 'em'
+    'body': 'empty( $1 )'
+
   'not empty':
     'prefix': 'nem'
     'body': '! empty( $1 )'


 Merge branch 'master.groups.fetchVocabularies' into 'master'

Groups: removed obsolete vocabulary removal.

--- workers/social/lib/social/models/group/index.coffee
+++ workers/social/lib/social/models/group/index.coffee
@@ -1263,10 +1263,6 @@
           JInvitation = require '../invitation'
           removeHelperMany JInvitation, requests, err, callback, queue

-        => @fetchVocabularies (err, vocabularies)->
-          JVocabulary = require '../vocabulary'
-          removeHelperMany JVocabulary, vocabularies, err, callback, queue
-
         => @fetchTags (err, tags)->
           JTag = require '../tag'
           removeHelperMany JTag, tags, err, callback, queue


JGroup:modify: use `Validators.group.admin` permission and use superadmin flag for koding admins

--- workers/social/lib/social/models/group/index.coffee
+++ workers/social/lib/social/models/group/index.coffee
@@ -968,8 +968,8 @@

   modify: permit
     advanced : [
-      { permission: 'edit own groups', validateWith: Validators.own }
-      { permission: 'edit groups' }
+      { permission: 'edit own groups', validateWith : Validators.group.admin }
+      { permission: 'edit groups',     superadmin   : yes }
     ]
     success : (client, formData, callback) ->
       # do not allow people to change there slugs


scriptblock: for fetching related JUser use JAccount.fetchUser method

--- workers/social/lib/social/render/scriptblock.coffee
+++ workers/social/lib/social/render/scriptblock.coffee
@@ -119,8 +119,7 @@
         userEnvironmentData = data
         queue.fin()
     ->
-      {nickname} = client.connection.delegate.profile
-      bongoModels.JUser.one username: nickname, (err, user) ->
+      client.connection.delegate.fetchUser (err, user) ->
         if err
           console.error '[scriptblock] user not found', err
           return queue.fin()


Social: fix profile page not rendering problem

--- workers/social/lib/social/render/scriptblock.coffee
+++ workers/social/lib/social/render/scriptblock.coffee
@@ -90,8 +90,7 @@
         socialapidata = data
         queue.fin()
     ->
-      {groupName} = session.data
-      groupName or= 'koding'
+      groupName = session?.groupName or= 'koding'

       # due to some reason, I suspect JSON.stringify somewhere, undefined
       # is stringified as 'undefined', this check makes sure, it defaults


Add a unit test on event.forEachSubscribers

--- tests/event.coffee
+++ tests/event.coffee
@@ -70,7 +70,8 @@
                     unhandledSubscribers[subscriber.id].should.be.true
                     delete unhandledSubscribers[subscriber.id]
                     done()
-                , =>
+                , (total) =>
+                    total.should.equal totalSubscribers
                     (i for i of unhandledSubscribers).length.should.equal 0
                     async.whilst =>
                         subscribers.length > 0


removing unused view context data from home view coffee file

--- js/outer/home.coffee
+++ js/outer/home.coffee
@@ -4,31 +4,4 @@
     _kmq.push(['trackClickOnOutboundLink', '#join', 'hero join link clicked'])
     _kmq.push(['trackClickOnOutboundLink', '.kissAuthGithub', 'join link clicked'])
     _kmq.push(['trackClickOnOutboundLink', '#second-join', 'footer join link clicked'])
-    _gaq.push(['_trackPageview', '/homepage'])
-
-  viewContext: =>
-    features: [
-      icon: "icon-magic"
-      headline: "Quick setup"
-      teaser: "Set up your CI server in 20 seconds, not two days. We detect test settings for a wide range of web apps, and set them up automatically on our servers."
-    ,
-      icon: "icon-bolt"
-      headline: "Crazy fast tests"
-      teaser: "Your productivity relies on fast test results, and CircleCI runs your tests faster than your Macbook Pro, EC2, your local server, or any other service."
-    ,
-      icon: "icon-bullhorn"
-      headline: "Smart notifications"
-      teaser: "CircleCI intelligently notifies you about just the pushes you care about, not all pushes, and does it over email, Hipchat, Campfire and more."
-    ,
-      icon: "icon-beaker"
-      headline: "Deep customization"
-      teaser: "Real applications often deviate slightly from standard configurations, so CircleCI does too. Our configuration is so flexible that it's easy to tweak almost anything you need."
-    ,
-      icon: "icon-cog"
-      headline: "Debug with ease"
-      teaser: "When your tests are broken, we help you get them fixed. We auto-detect errors, have great support, and even allow you to SSH into our machines to test manually."
-    ,
-      icon: "icon-comments"
-      headline: "Incredible support"
-      teaser: "We respond to support requests immediately, every day. Most requests are responded to within an hour. No-one ever waits more than 12 hours for a response."
-    ]
+    _gaq.push(['_trackPageview', '/homepage'])


customize test utils

customize test utils

--- test/_utils.coffee
+++ test/_utils.coffee
@@ -1,6 +1,12 @@
+fs = require 'fs'
 _ = require 'lodash'
 chai = require 'chai'
 chai.Assertion.includeStack = true

-exports.should = chai.should()
-exports._ = _
+module.exports = {
+  should: chai.should()
+  _
+}
+
+if fs.existsSync './_utils2.coffee'
+  _.merge module.exports, require './utils2'


Follow mixin

Follow mixin

--- test/follow.coffee
+++ test/follow.coffee
@@ -11,6 +11,6 @@
     x: 0
     y: 50
     widht: 10
-
+    height:

 module()


Follow mixin

Follow mixin

--- test/follow.coffee
+++ test/follow.coffee
@@ -23,7 +23,7 @@
     y: 100
     width: 10
     height: 10
-
+    fol

   fastEnemy.include(Follow)
   fastEnemy.follow(player)


:art: change condition format

:art: change condition format


install app fixed

install app fixed

--- kites/sharedHosting/api.coffee
+++ kites/sharedHosting/api.coffee
@@ -158,7 +158,7 @@
       if err then console.error err
       else callback? null

-    mkdirp versionedPath, (err)->
+    mkdirp version4edPath, (err)->
       if err then cb err
       else
         fs.readFile userAppPath, (err, appScript)->
@@ -183,7 +183,7 @@
     {username, owner, appName} = options

     kpmAppPath  = "/opt/Apps/#{owner}/#{appName}/latest"
-    userAppPath = "/Users/#{username}/Applications/#{appName}/latest"
+    userAppPath = "/Users/#{username}/Applications/#{appName}.kdapp"

     cb = (err)->
       if err then console.error err
@@ -192,15 +192,25 @@
     mkdirp userAppPath, (err)->
       if err then cb err
       else
-        fs.chown userAppPath, username, username, (err)->
-          if err then cb err
+        exec "cp #{kpmAppPath}/index.js #{userAppPath}/index.js", (err, stdout, stderr)->
+          if err or stderr.length
+            cb err or new KodingError "stderr: #{stderr}"
           else
-            targetStream = fs.createWriteStream("#{userAppPath}/index.js")
-            targetStream.on "error", cb
-            targetStream.on "end", -> cb null
-            sourceStream = fs.createReadStream("#{kpmAppPath}/index.js")
-            sourceStream.on "error", cb
-            sourceStream.pipe targetStream
+            exec "chown -R #{username}:#{username} #{userAppPath}", (err, stdout, stderr)->
+              if err or stderr.length
+                cb err or new KodingError "stderr : #{stderr}"
+              else
+                cb null
+
+        #fs.chown userAppPath, username, username, (err)->
+        #  if err then cb err
+        #  else
+        #    targetStream = fs.createWriteStream("#{userAppPath}/index.js")
+        #    targetStream.on "error", cb
+        #    targetStream.on "end", -> cb null
+        #    sourceStream = fs.createReadStream("#{kpmAppPath}/index.js")
+        #    sourceStream.on "error", cb
+        #    sourceStream.pipe targetStream


Try to create Applications folder incase of not exists

--- kites/sharedHosting/api.coffee
+++ kites/sharedHosting/api.coffee
@@ -17,6 +17,13 @@
 console.log "new sharedhosting api."

 escapePath = (name)-> return name.replace(/\'/g, '\\\'').replace(/\"/g, '\\"').replace(/\s/g, '\\ ')
+
+makedirp = (path, user, cb)->
+  exec "mkdir -p #{path} && chown #{user}: #{path}", cb
+
+createAppsDir = (user, cb)->
+  path = escapePath "/Users/#{user}/Applications"
+  makedirp path, user, cb

 module.exports = new Kite 'sharedHosting'

@@ -215,18 +222,19 @@
     kpmAppPath = escapePath "/opt/Apps/#{owner}/#{appName}/latest"
     appPath    = escapePath appPath

-    mkdirp appPath, (err)->
-      if err then cb err
-      else
-        exec "cp #{kpmAppPath}/index.js #{appPath} && cp #{kpmAppPath}/.manifest #{appPath}", (err, stdout, stderr)->
-          if err or stderr.length
-            cb err or "[ERROR] #{stderr}"
-          else
-            exec "chown -R #{username}: #{appPath}", (err, stdout, stderr)->
-              if err or stderr.length
-                cb err or "[ERROR] #{stderr}"
-              else
-                cb null
+    createAppsDir username, (err)->
+      makedirp appPath, username, (err)->
+        if err then cb err
+        else
+          exec "cp #{kpmAppPath}/index.js #{appPath} && cp #{kpmAppPath}/.manifest #{appPath}", (err, stdout, stderr)->
+            if err or stderr.length
+              cb err or "[ERROR] #{stderr}"
+            else
+              exec "chown -R #{username}: #{appPath}", (err, stdout, stderr)->
+                if err or stderr.length
+                  cb err or "[ERROR] #{stderr}"
+                else
+                  cb null

   createSystemUser : (options,callback)->
     #


Clean up settings management & test it

Clean up settings management & test it

--- tests/index.coffee
+++ tests/index.coffee
@@ -75,10 +75,10 @@
         delete global.client

     # SERVER TESTS
-    # require './00_index'
-    # require './01_account_creation'
-    # require './02_account_synchro'
-    # require './03_mailbox_operations'
-    # require './04_message_operations'
-    # require './05_mailbox_deletion'
+    require './00_index'
+    require './01_account_creation'
+    require './02_account_synchro'
+    require './03_mailbox_operations'
+    require './04_message_operations'
+    require './05_mailbox_deletion'
     require './06_settings'


Set up some environmental variables to be used exclusively within a development environment. Also now creating a folder before writing SSH keys.

--- util/migrateBoxToServer.coffee
+++ util/migrateBoxToServer.coffee
@@ -7,6 +7,7 @@
 mongoose = require 'mongoose'
 async = require 'async'
 request = require 'request'
+mkdirp = require 'mkdirp'

 {User} = require 'model/user'
 {Box} = require 'model/box'
@@ -75,6 +76,8 @@
         transferCrontab box, user, ->
           disableOldCrontab box, user, ->
             box.server = NEW_BOX_SERVER
+            process.env.CU_BOX_SERVER = NEW_BOX_SERVER
+            mkdirp.sync "/opt/cobalt/etc/sshkeys/#{box.name}"
             box.save (err) ->
               box.distributeSSHKeys (err, res, body) ->
                 console.log 'distributeSSHKeys', err, body


Backslash->ENTER will result in a new line

--- lib/autocomplete/command.coffee
+++ lib/autocomplete/command.coffee
@@ -35,6 +35,12 @@
     suggestions.sort((a, b) ->
       return -1 if a.displayText < b.displayText
       return 1)
+    suggestions.unshift(
+      text: '\n'
+      displayText: 'Press ENTER for new line.'
+      chainComplete: false
+      replacementPrefix: ''
+      latexType: 'command')
     return suggestions

   predefinedCommands: (prefix) ->


fix #100 de-offset when not cursor.isAtBeginningOfLine()

When cursor is not isAtBeginingOfLine() in linewise selection, it means
cursor is at last buffer row which row is not end with newline char.

--- lib/cursor-style-manager.coffee
+++ lib/cursor-style-manager.coffee
@@ -9,14 +9,15 @@
   cursorsComponent = editorElement.component.linesComponent.cursorsComponent
   cursorsComponent.cursorNodesById[cursor.id]

-# Return cursor style top, left offset for **sowft-wrapped** line
-# -------------------------
+# Return cursor style offset(top, left)
+# ---------------------------------------
 getOffset = (submode, selection) ->
   {top, left} = {}
+  {cursor} = selection
   switch submode
     when 'characterwise', 'blockwise'
       unless selection.isReversed()
-        if selection.cursor.isAtBeginningOfLine()
+        if cursor.isAtBeginningOfLine()
           top = -RowHeightInEm
         else
           left = -1
@@ -34,8 +35,20 @@
         top = rows * RowHeightInEm
         left = screenPoint.column
       else
-        top = -RowHeightInEm unless selection.isReversed()
-        left = bufferPoint.column
+        # In linwise selection, cursor isAtBeginningOfLine of next row of selected row.
+        # But there is one exception.
+        # When very last line is not end with newline("\n").
+        # select linewise by `V` put cursor at last char(=end of line).
+        # In this case, we minus(-) cursor's column to reset offset to column 0.
+        # But when `V` selection.isReversed() cursor is at column 0, so we don't have to reset offset.
+        left = 0
+        unless selection.isReversed()
+          if cursor.isAtBeginningOfLine()
+            top = -RowHeightInEm
+          else
+            # This is very special case when very last line is not end with newline("\n")
+            left -= cursor.getBufferColumn()
+        left += bufferPoint.column
   {top, left}

 setStyleOffset = (cursor, {submode, editor, editorElement}) ->
@@ -51,7 +64,6 @@
   new Disposable ->
     style.removeProperty('top')
     style.removeProperty('left')
-

 # Display cursor in visual mode.
 # ----------------------------------


Fix Y specs with correct keydown call

Fix Y specs with correct keydown call

--- spec/vim-mode-spec.coffee
+++ spec/vim-mode-spec.coffee
@@ -385,7 +385,7 @@
         editor.setCursorScreenPosition [0, 4]

       it "saves the line to the default register", ->
-        keydown('Y', element: editor[0])
+        keydown('Y', shift: true, element: editor[0])

         expect(vimState.getRegister('"').text).toBe "012 345\n"
         expect(editor.getCursorScreenPosition()).toEqual([0,4])
@@ -393,14 +393,14 @@
       describe "when prefixed by a count", ->
         it "copies n lines, starting from the current", ->
           keydown('2', element: editor[0])
-          keydown('Y', element: editor[0])
+          keydown('Y', shift: true, element: editor[0])

           expect(vimState.getRegister('"').text).toBe "012 345\nabc\n"

       it "saves the line to the a register", ->
         keydown('"', element: editor[0])
         keydown('a', element: editor[0])
-        keydown('Y', element: editor[0])
+        keydown('Y', shift: true, element: editor[0])

         expect(vimState.getRegister('a').text).toBe "012 345\n"


Fix alternative upload gui [ci travis]

Fix alternative upload gui
[ci travis]

--- BackofficeBundle/Resources/public/coffee/mediatheque/SuperboxView.coffee
+++ BackofficeBundle/Resources/public/coffee/mediatheque/SuperboxView.coffee
@@ -159,6 +159,7 @@
   refreshImages: ->
     $('.media_crop_preview img').each ->
       $(this).attr 'src', $(this).attr('src') + '?' + Math.random()
+    $(".media-override-format-form").hide()

   addSelect2OnForm: ->
     if $(".select2", @$el).length > 0
@@ -184,12 +185,11 @@
   addEventOnOverrideForm: ->
     currentView = this
     $(".media-override-format-form form", @$el).on "submit", (e) ->
-      displayLoader('.media_override_format_form')
+      displayLoader('.media-override-format-form')
       e.preventDefault() # prevent native submit
       $(this).ajaxSubmit
         statusCode:
           200: (response) ->
-            $('.media-override-format-form').html response
             currentView.refreshImages()
             currentView.addEventOnOverrideForm()
     return