use sentence case

use sentence case

--- client/landing/app/Applications/Account.kdapplication/AppController.coffee
+++ client/landing/app/Applications/Account.kdapplication/AppController.coffee
@@ -17,28 +17,28 @@
       title : "Personal"
       items : [
         { title : "Login & Email",        listHeader: "Email & username",           listType: "username",       id : 10,      parentId : null }
-        { title : "Password & Security",  listHeader: "Password & Security",        listType: "security",       id : 20,      parentId : null }
-        { title : "E-mail Notifications", listHeader: "E-mail Notifications",       listType: "emailNotifications", id : 22,  parentId : null }
-        { title : "Linked accounts",      listHeader: "Your Linked Accounts",       listType: "linkedAccounts", id : 30,      parentId : null }
+        { title : "Password & Security",  listHeader: "Password & security",        listType: "security",       id : 20,      parentId : null }
+        { title : "E-mail Notifications", listHeader: "E-mail notifications",       listType: "emailNotifications", id : 22,  parentId : null }
+        { title : "Linked accounts",      listHeader: "Your linked accounts",       listType: "linkedAccounts", id : 30,      parentId : null }
         { title : "Referrals",            listHeader: "Referrals ",                 listType: "referralSystem", id : 40,      parentId : null }
       ]
     billing :
       title : "Billing"
       items : [
-        { title : "Payment methods",      listHeader: "Your Payment Methods",       listType: "methods",        id : 10,      parentId : null }
-        { title : "Your subscriptions",   listHeader: "Your Active Subscriptions",  listType: "subscriptions",  id : 20,      parentId : null }
-        { title : "Billing history",      listHeader: "Billing History",            listType: "history",        id : 30,      parentId : null }
+        { title : "Payment methods",      listHeader: "Your payment methods",       listType: "methods",        id : 10,      parentId : null }
+        { title : "Your subscriptions",   listHeader: "Your active subscriptions",  listType: "subscriptions",  id : 20,      parentId : null }
+        { title : "Billing history",      listHeader: "Billing history",            listType: "history",        id : 30,      parentId : null }
       ]
     develop :
       title : "Develop"
       items : [
-        { title : "SSH keys",             listHeader: "Your SSH Keys",              listType: "keys",           id : 5,       parentId : null }
-        { title : "Koding Keys",          listHeader: "Your Koding Keys",           listType: "kodingKeys",     id : 10,      parentId : null }
+        { title : "SSH keys",             listHeader: "Your SSH keys",              listType: "keys",           id : 5,       parentId : null }
+        { title : "Koding keys",          listHeader: "Your Koding keys",           listType: "kodingKeys",     id : 10,      parentId : null }
       ]
     danger  :
       title : "Danger"
       items : [
-        { title : "Delete Account",       listHeader: "Danger Zone",                listType: "delete",         id : 5,       parentId : null }
+        { title : "Delete account",       listHeader: "Danger zone",                listType: "delete",         id : 5,       parentId : null }
       ]
       # kites :
       #   title : "Kites"


[Email Confirmation] added default callback for displayEmailConfirmModal function

--- client/landing/app/Applications/Account.kdapplication/AppController.coffee
+++ client/landing/app/Applications/Account.kdapplication/AppController.coffee
@@ -164,7 +164,7 @@
   indexOfItem:(item)->
     @itemsOrdered.indexOf item

-  displayConfirmEmailModal:(name, username, callback)->
+  displayConfirmEmailModal:(name, username, callback=->)->
     name or= KD.whoami().profile.firstName
     message =
       """


cache_override hook using redis

cache_override hook using redis

--- lib/application/hooks/PageCache.coffee
+++ lib/application/hooks/PageCache.coffee
@@ -15,16 +15,29 @@
 #

 fs = require('fs')
-try
-  redis = require('redis')
-  $url = process.env.REDISCLOUD_URL || process.env.REDISTOGO_URL || 'redis://localhost:6379'
-  client = redis.createClient(parse_url($url).port, parse_url($url).host, no_ready_check: true)
-  client.auth parse_url($url).pass
+#
+# Initialize the redis client
+#
+client = do ->
+  try
+    redis = require('redis')
+    $url = process.env.REDISCLOUD_URL || process.env.REDISTOGO_URL || 'redis://localhost:6379'
+    client = redis.createClient(parse_url($url).port, parse_url($url).host, no_ready_check: true)
+    client.auth parse_url($url).pass
+    client

-catch $ex
-  client = false
+  catch $e
+    log_message 'error', 'Unable to connect to REDIS'
+    false

-_write_cache = ($output) ->
+#
+# Override Output Write Cache
+#
+# @param  [String]  output  HTML to cache
+# @return [Void]
+#
+system.core.Output::_write_cache = ($output) ->
+
   # when should this cache expire?
   $cache_rules = @config.item('cache_rules')
   $ttl = @_cache_expiration * 60000
@@ -43,14 +56,18 @@

 module.exports =

+  #
+  # Display a Cached Page
+  #
+  # @param  [Object]  config  params from hook config
+  # @param  [Object]  output  the output object
+  # @param  [Function]  next  the async callback
+  # @return [Void]
+  #
   displayCache: ($config, $output, $next) ->

-    log_message 'debug', 'HOOK displayCache -- REDIS'
-    $output._write_cache = _write_cache
-
-    if client is false
-      log_message 'error', 'Unable to connect to REDIS'
-      return $next(null, false)
+    log_message 'debug', 'cache_override Hook Initialized'
+    return $next(null, false) if client is false

     $cache_path = if ($output.config.item('cache_path') is '') then APPPATH + 'cache/' else $output.config.item('cache_path')


Fixed ',' escaping in form params

Fixed ',' escaping in form params

--- lib/assets/javascripts/_form.js.coffee
+++ lib/assets/javascripts/_form.js.coffee
@@ -60,7 +60,7 @@
       # http://stackoverflow.com/questions/75980/best-practice-escape-or-encodeuri-encodeuricomponent
       #
       for key, value of this._params()
-        params.push("#{key}=#{encodeURIComponent(value)}")
+        params.push("#{key}=#{encodeURIComponent(value).replace(/%2C/g, ',')}")

       params.join('&')
     else


removed log

removed log

--- tests/unit/plugins.coffee
+++ tests/unit/plugins.coffee
@@ -47,7 +47,6 @@

         return window.pluginTest

-      @.echo updated

       updated.should.equal true


Use UI Hash for search list

Use UI Hash for search list

--- core/app/backbone/views/channels/auto_complete_search_channels_view.coffee
+++ core/app/backbone/views/channels/auto_complete_search_channels_view.coffee
@@ -28,6 +28,9 @@
     all_row: '.js-row-all'
     new_row: '.js-row-new'

+    search_list_both:  '.auto-complete-search-list-last-rounded-both'
+    search_list_right: '.auto-complete-search-list-last-rounded-right'
+
   onRender: -> @updateRows()

   appendHtml: (collectionView, itemView, index) ->
@@ -42,7 +45,7 @@
     @updateRows()

   updateRows: ->
-    myFilled = @$('.js-list-my li').length > 0
+    myFilled  = @$('.js-list-my li').length > 0
     allFilled = @$('.js-list-all li').length > 0
     newFilled = @$('.js-list-new li').length > 0

@@ -50,8 +53,8 @@
     @ui.all_row.toggleClass 'auto-complete-search-list-active', allFilled
     @ui.new_row.toggleClass 'auto-complete-search-list-active', newFilled

-    @$('.auto-complete-search-list-last-rounded-both').removeClass 'auto-complete-search-list-last-rounded-both'
-    @$('.auto-complete-search-list-last-rounded-right').removeClass 'auto-complete-search-list-last-rounded-right'
+    @ui.search_list_both.removeClass  'auto-complete-search-list-last-rounded-both'
+    @ui.search_list_right.removeClass 'auto-complete-search-list-last-rounded-right'

     if newFilled
       @ui.new_row.addClass 'auto-complete-search-list-last-rounded-both'


Remove unused test spec

Remove unused test spec

--- SingularityUI/test/spec.coffee
+++ SingularityUI/test/spec.coffee
@@ -1 +0,0 @@
-# Write your [mocha](http://visionmedia.github.com/mocha/) specs here.


Code review tweaks.

Code review tweaks.

--- rewriter.coffee
+++ rewriter.coffee
@@ -213,7 +213,7 @@
       if tag in SINGLE_LINERS and @tag(i + 1) isnt 'INDENT' and
          not (tag is 'ELSE' and @tag(i + 1) is 'IF')
         starter = tag
-        [indent, outdent] = @indentation token, implicit=true
+        [indent, outdent] = @indentation token, yes
         indent.fromThen   = true if starter is 'THEN'
         tokens.splice i + 1, 0, indent
         @detectEnd i + 2, condition, action
@@ -240,7 +240,7 @@
       1

   # Generate the indentation tokens, based on another token on the same line.
-  indentation: (token, implicit=false) ->
+  indentation: (token, implicit = false) ->
     tokens = [['INDENT', 2, token[2]], ['OUTDENT', 2, token[2]]]
     if implicit then (@generated(t) for t in tokens) else tokens


Fix for @yetti4 code in node.spec.coffee that broke Remote.Peer tests

--- src/tests/spec/public/models/remote.peer.spec.coffee
+++ src/tests/spec/public/models/remote.peer.spec.coffee
@@ -3,7 +3,7 @@
 		'public': '../../public'

 require [
-	'public/library/models/remote.peer'
+	'public/library/../library/models/remote.peer'
 	], ( Peer ) ->

 	describe 'Remote.Peer', ->
@@ -19,7 +19,6 @@
 			onopen: ->
 			onclose: ->
 			onmessage: ->
-

 		class global.FakeRTCPeerConnection
 			@iceConnectionState: null
@@ -55,7 +54,6 @@
 		beforeEach ->

 			fakeController = new FakeController()
-

 		describe 'when initialized', ->
 			it 'should create a new RTCPeerConnection object with default configurations', ->


Cleanup

Cleanup

--- desktop/apps/editorial_features/components/venice_2017/client/video.coffee
+++ desktop/apps/editorial_features/components/venice_2017/client/video.coffee
@@ -10,7 +10,6 @@

   initialize: (options) ->
     @video = options.video
-    console.log "Using video: " + @video
     @$playButton = $('#toggleplay')
     @setupVideo()
     @on 'swapVideo', @swapVideo


Fix lint issue

Fix lint issue

--- ui/scripts/adapters/password.coffee
+++ ui/scripts/adapters/password.coffee
@@ -41,8 +41,9 @@
             @form = new FormView({fields: @getFields(state)})
         else
             @form = new View({
-                template: -> return "Check your inbox. " +
-                                    "If not, check your spam folder."
+                template: ->
+                    return "Check your inbox. " +
+                           "If not, check your spam folder."
             })
         @form.render()
         @view.render({


Correct warning message.

Correct warning message.

--- client/landing/app/MainApp/paymentcontroller.coffee
+++ client/landing/app/MainApp/paymentcontroller.coffee
@@ -284,7 +284,7 @@
     content = @paymentWarning balance, amount, subscription, type

     if type is 'expensed' and needBilling and 'admin' not in KD.config.roles
-      content = "Group admins have not defined a payment for this group."
+      content = "Group admins have not defined a payment method for this group."

     modal           = new KDModalView
       title         : "Confirm VM Creation"


Added support for short year format.

Added support for short year format.

--- app/assets/javascripts/app/lib/app_post/i18n.coffee
+++ app/assets/javascripts/app/lib/app_post/i18n.coffee
@@ -337,18 +337,20 @@
     if offset
       timeObject = new Date(timeObject.getTime() + (timeObject.getTimezoneOffset() * 60000))

-    d = timeObject.getDate()
-    m = timeObject.getMonth() + 1
-    y = timeObject.getFullYear()
-    S = timeObject.getSeconds()
-    M = timeObject.getMinutes()
-    H = timeObject.getHours()
+    d      = timeObject.getDate()
+    m      = timeObject.getMonth() + 1
+    yfull  = timeObject.getFullYear()
+    yshort = timeObject.getYear()-100
+    S      = timeObject.getSeconds()
+    M      = timeObject.getMinutes()
+    H      = timeObject.getHours()
     format = format
       .replace(/dd/, s(d, 2))
       .replace(/d/, d)
       .replace(/mm/, s(m, 2))
       .replace(/m/, m)
-      .replace(/yyyy/, y)
+      .replace(/yyyy/, yfull)
+      .replace(/yy/, yshort)
       .replace(/SS/, s(S, 2))
       .replace(/MM/, s(M, 2))
       .replace(/HH/, s(H, 2))


inputview: implement autogrow for single line inputs

--- lib/components/inputs/inputview.coffee
+++ lib/components/inputs/inputview.coffee
@@ -92,6 +92,7 @@
     @valid = yes
     @inputCallback = null
     @previousHeight = null
+    @previousWidth = null
     @setName options.name
     @setLabel()
     @setCallback()
@@ -130,6 +131,7 @@
     if o.autogrow
       @once "focus", =>
         @initialHeight = @$().height()  unless @initialHeight
+        @initialWidth = @$().width()  unless @initialWidth

   setDomElement:(cssClass = "")->
     name = "name='#{@options.name}'"
@@ -451,12 +453,16 @@
     # element to get calculated height
     @_clone = $ '<div/>', { class: 'invisible' }

+    { type } = @getOptions()
+    isVertical = type.toLowerCase() is 'textarea'
+
+
     @on 'focus', =>
       @_clone.appendTo 'body'
       @_clone.css
-        height        : 'auto'
+        height        : if isVertical then 'auto' else $input.css 'height'
         zIndex        : 100000
-        width         : $input.css 'width'
+        width         : if isVertical then $input.css 'width' else 'auto'
         boxSizing     : $input.css 'box-sizing'
         borderTop     : $input.css 'border-top'
         borderRight   : $input.css 'border-right'
@@ -472,29 +478,56 @@
         fontSize      : $input.css 'fontSize'
         fontWeight    : $input.css 'fontWeight'
         lineHeight    : $input.css 'lineHeight'
-        whiteSpace    : 'pre-line'
+        whiteSpace    : if isVertical then 'pre-line' else 'pre'

     @on 'blur', => @_clone.detach()
-
-    @on 'input', (event) => KD.utils.defer => @resize event
+    @on 'input', @bound 'resize'

   resize: (event) ->
-
-    return  unless @_clone

     @_clone.appendTo 'body' unless document.body.contains @_clone[0]
     val = @getElement().value.replace(/\n/g,'\n ')
     safeValue = Encoder.XSSEncode val
     @_clone.html safeValue

+    { type } = @getOptions()
+
+    if type.toLowerCase() is 'textarea'
+    then return @_resizeVertically event
+    else return @_resizeHorizontally event
+
+  _getValue = (el, rule) -> parseInt el.css(rule), 10
+
+  _resizeHorizontally: (event) ->
+
+    return  unless @_clone
+
+    width = @_clone.width()
+
+    if @$().css('boxSizing') is 'border-box'
+      padding = _getValue(@_clone, 'paddingLeft') + _getValue(@_clone, 'paddingRight')
+      border  = _getValue(@_clone, 'borderLeftWidth') + _getValue(@_clone, 'borderRightWidth')
+      width   = width + border + padding
+
+    newWidth = if @initialWidth then Math.max @initialWidth, width else width
+
+    if @previousWidth isnt newWidth
+      @setWidth newWidth
+      @emit 'InputWidthChanged'
+
+    @previousWidth = newWidth
+
+
+  _resizeVertically: (event) ->
+
+    return  unless @_clone
+
     height = @_clone.height()

-    getValue = (rule) => parseInt @_clone.css(rule), 10
-
     if @$().css('boxSizing') is 'border-box'
-      padding = getValue('paddingTop')     + getValue('paddingBottom')
-      border  = getValue('borderTopWidth') + getValue('borderBottomWidth')
+      padding = _getValue(@_clone, 'paddingTop') + _getValue(@_clone, 'paddingBottom')
+      border  = _getValue(@_clone, 'borderTopWidth') + _getValue(@_clone, 'borderBottomWidth')
       height  = height + border + padding

     newHeight = if @initialHeight then Math.max @initialHeight, height else height


update expansions test

update expansions test

--- tests/test_expansions.coffee
+++ tests/test_expansions.coffee
@@ -33,6 +33,8 @@
         "TIE Interceptor Expansion Pack"
         "TIE Phantom Expansion Pack"
         "TIE Punisher Expansion Pack"
+        "TIE/fo Fighter Expansion Pack"
+        "T-70 X-Wing Expansion Pack"
         "VT-49 Decimator Expansion Pack"
         "X-Wing Expansion Pack"
         "YT-2400 Freighter Expansion Pack"


removed redundant conditional check

removed redundant conditional check

--- community/browser/app/scripts/services/Frame.coffee
+++ community/browser/app/scripts/services/Frame.coffee
@@ -77,7 +77,7 @@
                 @response = null
                 @errorText = "Unknown error"
                 if result.length > 0 and result[0].code
-                  @errorText = result[0].code if result[0].code
+                  @errorText = result[0].code
                   @detailedErrorText = result[0].message if result[0].message
                 @runTime = timer.stop().time()
             )


Remove periodic polling of document for labels

--- services/web/public/coffee/ide/labels/LabelsManager.coffee
+++ services/web/public/coffee/ide/labels/LabelsManager.coffee
@@ -1,7 +1,5 @@
 define [
 ], () ->
-
-	AUTOMATIC_REFRESH_PERIOD = 1000 * 60 * 10

 	class LabelsManager
 		constructor: (@ide, @$scope) ->
@@ -11,26 +9,15 @@
 				documents: {} # map of DocId => List[Label]

 			@loadLabelsTimeout = null
-			@periodicLoadInterval = null

 			setTimeout(
 				() =>
-					# set up a regular re-load
-					setTimeout(
-						() =>
-							@periodicLoadInterval = setInterval(
-								() =>
-									@loadLabelsFromOpenDoc()
-								, AUTOMATIC_REFRESH_PERIOD
-							)
-						, AUTOMATIC_REFRESH_PERIOD
-					)
 					# listen for document open
 					@$scope.$on 'document:opened', (e, doc) =>
 						setTimeout(
 							() =>
 								@scheduleLoadLabelsFromOpenDoc()
-							, 1000
+							, 0
 						)
 				, 0
 			)


fix chot, and DIE

fix chot, and DIE

--- scripts/senpai.coffee
+++ scripts/senpai.coffee
@@ -114,7 +114,7 @@
 # }}}

 class History # {{{
-  constructor: (@robot, @msg, @cache, @keep = 10) ->
+  constructor: (@robot, @msg, @cache, @keep = 5000) ->
     @cache ||= []

   add: (message) ->
@@ -127,6 +127,7 @@
     if (lines > @cache.length)
       lines = @cache.length
 #    reply = 'Showing ' + lines + ' lines of history:\n'
+    reply = ''
     reply = reply + @entryToString(message) + '\n' for message in @cache[-lines..]
     return reply

@@ -230,11 +231,11 @@
     if name is user
       msg.send "#{name} は #{name} だろ。大丈夫か？"
     else
-      msg.send "#{name} は #{user} だのことだ。"
-    checkKeigo robot, msg
-# }}}
-
-  robot.respond /([^ ]+)[ ]*のアダ名は?(何|なん|なに)/, (msg) -># {{{
+      msg.send "#{name} は #{user} のことだ。"
+    checkKeigo robot, msg
+# }}}
+
+  robot.respond /([^ ]+)[ ]*の(あだ|アダ)名は?(何|なん|なに)/, (msg) -># {{{
     realname = msg.match[1]
     unless existsUser robot, msg, realname
       msg.send "#{realname} って誰？"
@@ -424,3 +425,7 @@
     checkKeigo robot, msg
 # }}}

+  robot.respond /DIE$/i, (msg) ->
+    msg.send "どうやら俺の人生もここまでだ。みん元気でな"
+    process.exit 0
+


Add `\u2028` character (line separator space)

This space crashes the new Symfony Yaml Parser (2.8.19).

Thanks @wengerk

--- lib/highlight-bad-chars.coffee
+++ lib/highlight-bad-chars.coffee
@@ -43,6 +43,7 @@
   '\u200D', # zero width joiner
   '\u2013',  # en dash
   '\u2014',  # em dash
+  '\u2028',  # line separator space
   '\u202F', # narrow no-break space
   '\u205F', # medium mathematical space
   '\u3000', # ideographic space


Delete fields general and specific in coffeescript

--- app/assets/javascripts/incident_reports/edit.coffee
+++ app/assets/javascripts/incident_reports/edit.coffee
@@ -33,6 +33,17 @@
 addInjuredPassengerFields = (event) ->
   event.preventDefault()
   addFields '.pax-fields'
+
+deleteFields = (fieldsSelector) ->
+  $(fieldsSelector).last().destroy()
+
+deleteWitnessFields = (event) ->
+  event.preventDefault()
+  deleteFields '.witness-fields'
+
+deleteInjuredPassengerFields = (event) ->
+  event.preventDefault()
+  deleteFields '.pax-fields'

 toggleReasonsForTesting = ->
   reason = $('#incident_report_reason_test_completed').val()


added customAccount to subscription model

--- services/web/app/coffee/models/Subscription.coffee
+++ services/web/app/coffee/models/Subscription.coffee
@@ -11,6 +11,7 @@
 	planCode 	 : {type: String}
 	groupPlan	 : {type: Boolean, default: false}
 	membersLimit: {type:Number, default:0}
+	customAccount: Boolean
 	freeTrial:
 		expiresAt: Date
 		downgraded: Boolean


Use document.body.scrollHeight, it's more correct

--- js/libs/browser.coffee
+++ js/libs/browser.coffee
@@ -1,11 +1,10 @@
 CI.Browser or= {}

 CI.Browser.scroll_to = (position) =>
-  element = if jQuery.browser.webkit then "body" else "html"
-  offset = if position == "top" then 0 else document.body.offsetHeight
+  offset = if position == "top" then 0 else document.body.scrollHeight
   # Scrolling instantly is actually a smoother experience than
   # incorporating a delay. When the animation takes some time to run the
   # page jumps unpleasantly when new content is added.
   # Delays also fight the user if they try to scroll up at the same time
   # the animation is scrolling down.
-  $(element).animate({scrollTop: offset}, 0)
+  $("html, body").animate({scrollTop: offset}, 0)


 Merge branch 'master.groups.inviteerror' into 'master.groups'

Master.Groups.Inviteerror

One liner check.

--- client/Dashboard/views/groupsinvitationview.coffee
+++ client/Dashboard/views/groupsinvitationview.coffee
@@ -12,7 +12,7 @@
         tabHandleContainer
       }, data

-      unless @policy.communications?.inviteApprovedMessage
+      unless @policy?.communications?.inviteApprovedMessage
         @saveInviteMessage 'inviteApprovedMessage', @getDefaultInvitationMessage()

     @on 'SearchInputChanged', (value)=>


moved preventDefault()

moved preventDefault()

--- vendor/assets/javascripts/nested-form.js.coffee
+++ vendor/assets/javascripts/nested-form.js.coffee
@@ -82,6 +82,7 @@
   bind_add_button: () ->
     nested_form = this
     this.j_el.parent().find('.add_fields').bind('click', (event) ->
+      event.preventDefault()
       time = new Date().getTime()
       regexp = new RegExp($(this).data('id'), 'g')

@@ -96,7 +97,6 @@
       nested_form.set_order_num(fields_wrapper)
       nested_form.bind_remove_buttons()
       window.bind_datepicker('.datepicker')
-      event.preventDefault()
     )

 $(document).ready(


Reimplement parsing auth header

Reimplement parsing auth header

Resolves #257

--- lib/auth.coffee
+++ lib/auth.coffee
@@ -21,10 +21,30 @@

 exports.parseAuthHeader = (authHeader) ->
-  res = {method: authHeader.slice(0, authHeader.indexOf(' '))}
-  re = /([a-z0-9_-]+)=(?:"([^"]+)"|([a-z0-9_-]+))/gi
-  while match = re.exec(authHeader)
-    res[match[1]] = match[2] or match[3]
+  authHeader = authHeader.trim()
+  method = authHeader.split(' ', 1)[0]
+  res = {method: method}
+  parts = authHeader.slice(method.length + 1).split(',')
+
+  while (part = parts.shift())?
+    name = part.split('=', 1)[0]
+    throw new Error('Unable to parse auth header') if name.length == part.length
+    value = part.slice(name.length + 1)
+    if not /^\s*"/.test(value)
+      value = value.trim()
+    else
+      while not /[^\\]"\s*$/.test(value)
+        p = parts.shift()
+        throw new Error('Unable to parse auth header') if not p?
+        value += ',' + p
+
+      try
+        value = JSON.parse(value)
+      catch
+        throw new Error('Unable to parse auth header')
+
+    res[name.trim()] = value
+
   return res


Better confirmation modal for VMs.

Better confirmation modal for VMs.

--- client/app/MainApp/VirtualizationController.coffee
+++ client/app/MainApp/VirtualizationController.coffee
@@ -217,8 +217,8 @@
           forms                     :
             "Create VM"             :
               callback              : (formData)=>
-                paymentController.makePaymentModal formData.type, @paymentPlans[formData.host], ->
-                  modal.destroy()
+                modal.destroy()
+                @confirmPayment formData.type, @paymentPlans[formData.host]
               buttons               :
                 user                :
                   title             : "Create a Personal VM"
@@ -286,31 +286,6 @@
                 type                :
                   name              : "type"
                   type              : "hidden"
-                "userVM"            :
-                  itemClass         : KDCustomHTMLView
-                  partial           : "

-                                        You already have a subscription for personal VM. You
-                                        won't be charged.
-
"
-                "userCredits"       :
-                  itemClass         : KDCustomHTMLView
-                  partial           : "

-                                        You have $0 credited to your personal account. You won't
-                                        be charged until you consume that amount.
-
"
-                "groupVM"           :
-                  itemClass         : KDCustomHTMLView
-                  partial           : "

-                                        You already have a subscription for group VM. You
-                                        won't be charged.
-
"
-                "groupCredits"      :
-                  itemClass         : KDCustomHTMLView
-                  partial           : "

-                                        You have $0 credited to your group account. You won't
-                                        be charged until you consume that amount.
-
"
-

       if canCreateSharedVM
         modal.modalTabs.forms["Create VM"].buttons.group.show()
@@ -319,8 +294,6 @@
       modal.once 'KDModalViewDestroyed', => @dialogIsOpen = no

       form = modal.modalTabs.forms["Create VM"]
-
-      @showPaymentNotices form

       hideLoaders = ->
         {group, user, expensed} = form.buttons
@@ -331,46 +304,84 @@
       vmController.on "PaymentModalDestroyed", hideLoaders
       form.on "FormValidationFailed", hideLoaders

-  showPaymentNotices: (form)->
-    group = KD.getSingleton("groupsController").getCurrentGroup()
+  confirmPayment: (type, plan, callback=->)->
+    paymentController = KD.getSingleton('paymentController')
+    group             = KD.getSingleton("groupsController").getCurrentGroup()
+
+    getBalance = (type, cb)->
+      if type is 'user'
+        KD.remote.api.JRecurlyPlan.getUserBalance cb
+      else
+        KD.remote.api.JRecurlyPlan.getGroupBalance group, cb
+
+    buildModal = (content, cb)->
+      modal           = new KDModalView
+        title         : "Confirm VM Creation"
+        content       : "
#{content}
"
+        overlay       : yes
+        buttons       :
+          No          :
+            title     : "Cancel"
+            cssClass  : "modal-clean-gray"
+            callback  : =>
+              modal.destroy()
+              cb()
+          Yes         :
+            title     : "OK, create the VM"
+            cssClass  : "modal-clean-green"
+            callback  : =>
+              modal.destroy()
+              cb()
+              paymentController.makePaymentModal type, plan, ->
+                console.log "I'm done."

-    # Show user account balance, if necessary
-    {userCredits, userVM} = form.fields
-    userCredits.setClass "hidden"
-    userVM.setClass "hidden"
-
     group.canCreateVM
-      type    : "user"
-      planCode: "group_vm_1xs_1"
+      type     : type
+      planCode : plan.code
     , (err, status)->
       if not err and status
-        userVM.unsetClass "hidden"
+        content = """

+                       You already subscribed for an additional
+                       #{type} VM.
+

+

+                       You won't be charged. Do you want to
+                       continue?.
+

+                  """
+        buildModal content, callback
       else
-        KD.remote.api.JRecurlyPlan.getUserBalance (err, balance)->
-          if err or balance <= 0
-            userCredits.setClass "hidden"
+        getBalance type, (err, balance)->
+          if not err and balance > 0
+            charge = (plan.feeMonthly - balance) / 100
+            balance = balance / 100
+
+            content = """

+                           You have $#{balance.toFixed(2)} credited to your
+                           #{type} account.
+

+                      """
+
+            if charge > 0
+              content += """

+                              You will be charged for $#{charge.toFixed(2)}.
+                              Do you want to continue?
+

+                         """
+            else
+              content += """

+                              You won't be charged. Do you
+                              want to continue?
+

+                         """
           else
-            userCredits.$('p span.price').text (balance / 100).toFixed(2)
-            userCredits.unsetClass "hidden"
-
-    # Show group account balance, if necessary
-    {groupCredits, groupVM} = form.fields
-    groupCredits.setClass "hidden"
-    groupVM.setClass "hidden"
-
-    group.canCreateVM
-      type    : "group"
-      planCode: "group_vm_1xs_1"
-    , (err, status)->
-      if not err and status
-        groupVM.unsetClass "hidden"
-      else
-        KD.remote.api.JRecurlyPlan.getGroupBalance group, (err, balance)->
-          if err or balance <= 0
-            groupCredits.setClass "hidden"
-          else
-            groupCredits.$('p span.price').text (balance / 100).toFixed(2)
-            groupCredits.unsetClass "hidden"
+            charge = plan.feeMonthly / 100
+            content = """

+                           You will be charged for $#{charge.toFixed(2)}. Do
+                           you want to continue?
+

+                      """
+          buildModal content, callback

   askForApprove:(command, callback)->


#200 compact

#200 compact

--- lib/base.coffee
+++ lib/base.coffee
@@ -206,12 +206,9 @@

   registries = {Base}
   @extend: (@command=true) ->
-    if @hasClassInRegistries(@name) and (not @suppressWarning)
+    if (name of registries) and (not @suppressWarning)
       console.warn "Duplicate constructor #{@name}"
     registries[@name] = this
-
-  @hasClassInRegistries: (name) ->
-    name of registries

   @getClass: (name) ->
     if klass = registries[name]


remove old unused directive

remove old unused directive

--- app/directives/expandable-bucket-description.coffee
+++ app/directives/expandable-bucket-description.coffee
@@ -1,16 +0,0 @@
-null
-
-### @ngInject ###
-global.cobudgetApp.directive 'expandableBucketDescription', ($timeout) ->
-  link: (scope, element, attr) ->
-
-    doShit = ->
-      height = element[0].offsetHeight
-      if height == 200
-        console.log('overflow')
-        element.css('overflow', 'hidden')
-      else
-        console.log('no overflow')
-      scope.height = height
-
-    $timeout(doShit)


fix resize handler mixin to namespace resize event to prevent removal of all handlers when one view is destroyed

--- packages/emberella/lib/mixins/resize_handler.coffee
+++ packages/emberella/lib/mixins/resize_handler.coffee
@@ -50,8 +50,8 @@

   didInsertElement: ->
     @_super()
-    $(window).bind 'resize', @get("resizeHandler")
+    $(window).on 'resize.' + Ember.guidFor(@), @get("resizeHandler")

   willDestroy: ->
-    $(window).unbind 'resize', @get("resizeHandler")
+    $(window).off 'resize.' + Ember.guidFor(@), @get("resizeHandler")
     @_super()


CADS-621 : Feedback ui. Whoops left console.log in coffee script.

--- c3/app/assets/javascripts/feedback/feedback.coffee
+++ c3/app/assets/javascripts/feedback/feedback.coffee
@@ -1,5 +1,4 @@
 window.initEvents = (answerY, answerN, text1, text2, wrap1, wrap2) ->
-  console.log("passed text1:"+text1+" and text2:"+text2)
   $("#" + text1).trigger("blur")
   $("#" + text2).trigger("blur")


Append multiple opinions on the same Factlink in stream

Signed-off-by: tomdev <96835dd8bfa718bd6447ccc87af89ae1675daeca@codigy.nl>

--- core/app/backbone/views/user_activities_view.coffee
+++ core/app/backbone/views/user_activities_view.coffee
@@ -13,6 +13,8 @@
       UserChannelActivitiesView
     else if model.get('action') in ["added_supporting_evidence", "added_weakening_evidence"]
       EvidenceActivitiesView
+    else if model.get('action') in ["believes", "doubts", "disbelieves"]
+      OpinionActivitiesView
     else
       UserActivitiesView

@@ -40,3 +42,10 @@
     same_fact = @model.get('activity')?.fact?.id == m.get('activity')?.fact?.id

     correct_action and same_fact
+
+
+class OpinionActivitiesView extends UserActivitiesView
+  appendable: (m) ->
+    return false unless @model.get('username') == m.get('username')
+
+    return @model.get('activity')?.fact?.id == m.get('activity')?.fact?.id


Revert "typo for @compile_bitwise_or"

Revert "typo for @compile_bitwise_or"

This reverts commit 45aae5e322c5b3b4823246f3b63a3894dd5f0d26.

--- nodes.coffee
+++ nodes.coffee
@@ -1291,7 +1291,7 @@
     new OpNode('|', @left, @right).compile o

   compile_node: (o) ->
-    return @compile_bitwise_or o unless @right instanceof CallNode and not (@right.is_new or @right.is_super)
+    return compile_bitwise_or o unless @right instanceof CallNode and not (@right.is_new or @right.is_super)
     @right.args.unshift @left
     @right.compile o


fixes (temporarily) issue #908; line 1232 of src/nodes.coffee still needs a rewrite though

--- nodes.coffee
+++ nodes.coffee
@@ -1228,7 +1228,8 @@
   compileChain: (o) ->
     [@first.second, shared] = @first.second.cache o
     fst = @first.compile o, LEVEL_OP
-    fst = fst.slice 1, -1 if @first.unwrap() instanceof Op and @first.isChainable() and fst.charAt(0) is '('
+    # TODO: find a way to make this next line a proper check or remove it entirely and deal with extra parens
+    fst = fst.slice 1, -1 if @first.unwrap() instanceof Op and @first.isChainable() and fst.charAt(0) is '(' and fst.charAt(fst.length-1) is ')'
     code = "#{fst} #{if @invert then '&&' else '||'} #{ shared.compile o } #{@operator} #{ @second.compile o, LEVEL_OP }"
     "(#{code})"


Referral System: fixed a big issue on referral system

--- client/Intro/views/registerinlineform.coffee
+++ client/Intro/views/registerinlineform.coffee
@@ -112,7 +112,7 @@
   doRegister:(formData)->
     (KD.getSingleton 'mainController').isLoggingIn on
     formData.agree = 'on'
-    formData.referrer = $.cookie 'refererer'
+    formData.referrer = $.cookie 'referrer'
     # we need to close the group channel so we don't receive the cycleChannel event.
     # getting the cycleChannel even for our own MemberAdded can cause a race condition
     # that'll leak a guest account.


Clean up

Clean up

--- node_modules/bongo-client/src/eventemitter/broker.coffee
+++ node_modules/bongo-client/src/eventemitter/broker.coffee
@@ -5,13 +5,6 @@
     else event

   {defineProperty} = Object
-  # ignoredEvents = [
-  #   'update'
-  #   'ContentMarkedAsLowQuality'
-  #   'ContentUnmarkedAsLowQuality'
-  #   'PostIsDeleted'
-  #   'TagsChanged'
-  # ]

   afterInit:do ->
     channels = {}
@@ -38,14 +31,12 @@
         constructor.wrapArgs [payload], ([arg])-> listener arg
       else if event is 'update'
         listener()
-
+
     id = @getId?() or @bongo_?.instanceId
     if id? and multiplex and event isnt 'update'
       name = "object-#{id}"
       @mq.updateInstanceChannel.on name, multiplex

-    # @channel.bind event, multiplex if multiplex and event isnt 'update'
-
   off:(event, listener)->
     getPusherEvent(event)
     @channel.off event, listener


Don't add BHL link dynamically.

Don't add BHL link dynamically.

--- overrides.coffee
+++ overrides.coffee
@@ -37,9 +37,6 @@

 bhl_link = document.querySelector('a[target=bhl]')
 page_zoom = document.querySelector('input[name=pagezoom]')
-
-drawing_controls = document.querySelector '.drawing-controls'
-drawing_controls.appendChild bhl_link

 # moving back and forward through the array of marked SVG rectangles
 classify_page.el.on decisionTree.LOAD_TASK, ({originalEvent: detail: {task}})->


add temp talk alert

add temp talk alert

--- overrides.coffee
+++ overrides.coffee
@@ -146,7 +146,7 @@

Located near

34'00'02.3 N

120'14'55.0 W

-          Discuss on Talk
+          Discuss on Talk


fallback '-' for no lat/long coords

fallback '-' for no lat/long coords

--- overrides.coffee
+++ overrides.coffee
@@ -70,7 +70,7 @@

   @mobile: -> window.innerWidth < 900

-  @roundTo: (dec, num) -> parseFloat(num).toFixed(dec)
+  @roundTo: (dec, num) -> if num then parseFloat(num).toFixed(dec) else "-"

   window.onresize = =>
     $(".summary-overlay").removeClass("mobile-done") if not @mobile()


Display camera counts for non-highway and roads with a single camera.

--- views/roads.coffee
+++ views/roads.coffee
@@ -11,8 +11,11 @@
                         # be laid out directionally.  This could be because
                         # there is only a single camera, or because the item
                         # represents more than one road.
-                        li -> a href: "/roads/#{road.roadId}", -> road.name
-
+                        li ->
+                            a href: "/roads/#{road.roadId}", ->
+                                h1 "#{road.name}"
+                                if road.cameraCount is 1 then p '1 Camera'
+                                else p "#{road.cameraCount} Cameras"
                     else if road.directions.length is 2
                         # A road list item that represents a road with cameras
                         # that can be laid out directionally (N, S, E, W).


Making button div dpened on ace_scroller instead of ace_active_line as that was off on lines that are longer than the editor. I know james implemented this but it looks like he didn't sync it, so I am just doing it again so we know the issue is closed. Fixes #2.

--- web/scripts/playerCodeEditor.coffee
+++ web/scripts/playerCodeEditor.coffee
@@ -177,7 +177,7 @@
             gtop = $(".ace_active-line").offset().top
             gleft = $(".ace_active-line").offset().left
             gheight = $(".ace_active-line").height()
-            gwidth = $(".ace_active-line").width()
+            gwidth = $(".ace_scroller").width()
             $(@acelne).css(
                 {"position":"absolute","top":gtop,
                 "left":gleft,"width":gwidth,


DNDUploader: add a log for upload event

DNDUploader: add a log for upload event

--- client/finder/commonviews/DNDUploader.coffee
+++ client/finder/commonviews/DNDUploader.coffee
@@ -174,6 +174,9 @@
   saveFile: (fsFile, data) ->
     @emit "uploadStart", fsFile
     fsFile.saveBinary data, (err, res, progress)=>
+
+      log "Upload result:", err, res, progress
+
       progress or= res
       return if err
       if res.finished


Modify button to read 'Create' when model is new

--- client/lanes/components/toolbar/Toolbar.cjsx
+++ client/lanes/components/toolbar/Toolbar.cjsx
@@ -12,9 +12,11 @@
         changedModel: 'remote-update'

     renderSaveButton: ->
+        model = @props.commands.getModel()
+        text = if model.isNew() then 'Create' else 'Save'
         <BS.Button navItem componentClass="button" disabled={!@isSavable()}
             onClick={@props.commands.saveModel} className="save navbar-btn control">
-            <LC.Icon type="cloud-upload" />{@props.saveButtonText || 'Save'}
+            <LC.Icon type="cloud-upload" />{text}
         </BS.Button>

     renderResetButton: ->


unnecessary activity fetch retrieval is prevented for group joiners and group lefters. (resolves having lots of "a koding user started following you" notifications)

--- client/landing/app/CommonViews/messagesList.coffee
+++ client/landing/app/CommonViews/messagesList.coffee
@@ -46,10 +46,7 @@
         'CLikeeBucketActivity'
         'CGroupJoineeBucketActivity'
         'CNewMemberBucketActivity'
-        'CGroupJoineeBucketActivity'
-        'CGroupJoinerBucketActivity'
         'CGroupLefteeBucketActivity'
-        'CGroupLefterBucketActivity'
       ]
     }, {
       limit: 8
@@ -91,7 +88,6 @@
     follow      : ""
     share       : "shared"
     commit      : "committed"
-    member      : "joined"
     groupJoin   : "joined"
     groupLeft   : "left"


TinyMCE initialization changes to fix default behavior for opening link in a new page

--- common/lib/xmodule/xmodule/js/src/html/edit.coffee
+++ common/lib/xmodule/xmodule/js/src/html/edit.coffee
@@ -73,6 +73,10 @@
         },
         # Disable visual aid on borderless table.
         visual: false,
+        target_list: [
+          {title: 'New page', value: '_blank'},
+          {title: 'None', value: '_self'},
+        ]
         plugins: "textcolor, link, image, codemirror",
         codemirror: {
           path: "#{baseUrl}/js/vendor"


[balrog-ui] Fixes jasmine-given path

[balrog-ui] Fixes jasmine-given path

--- ui/spec-e2e/login_spec.coffee
+++ ui/spec-e2e/login_spec.coffee
@@ -1,6 +1,6 @@
 protractor = require("protractor")
 require "protractor/jasminewd"
-require 'jasmine-given-actual'
+require 'jasmine-given'

 describe "my angular app", ->
   ptor = protractor.getInstance()


Fail on empty tasks properly

Fail on empty tasks properly

--- lib/ThenableCollection.coffee
+++ lib/ThenableCollection.coffee
@@ -12,6 +12,8 @@

   state = new SubtreeResults tasks.length, choice
   unless tasks.length
+    state.started[0] = []
+    state.started[0][''] = true
     state.handleResult state.rejected, 0, null, new Error("No tasks provided"), onResult
     return

@@ -25,7 +27,7 @@
     try
       val = t choice, data
       if val and typeof val.then is 'function' and typeof val.else is 'function'
-        log.values "#{choice.treeId} #{choice} returned subtree #{val.tree.name or val.tree.id} #{val.id}"
+        log.values "#{choice.treeId} #{choice} ##{i} returned subtree #{val.tree.name or val.tree.id} #{val.id}"
         state.registerTree i, val.tree, onResult
         val.then (p, d) ->
           log.values "#{choice} task #{i} #{p} resulted in #{typeof d} %s", d


:penguin: Added missing linux keymaps.

:penguin: Added missing linux keymaps.

Fixed "No shortcut equivalent to cmd-f2 on Linux" issue.

--- keymaps/bookmarks.cson
+++ keymaps/bookmarks.cson
@@ -10,3 +10,7 @@
 '.platform-win32 .editor':
   'alt-ctrl-f2': 'bookmarks:toggle-bookmark'
   'ctrl-shift-f2': 'bookmarks:clear-bookmarks'
+
+'.platform-linux .editor':
+  'ctrl-shift-f2': 'bookmarks:toggle-bookmark'
+  'alt-shift-f2': 'bookmarks:clear-bookmarks'


ScrollView: removed mousewheel jquery plugin

--- src/components/scrollview/customscrollviewinner.coffee
+++ src/components/scrollview/customscrollviewinner.coffee
@@ -1,4 +1,3 @@
-require('jquery-mousewheel') $
 KDCustomHTMLView = require './../../core/customhtmlview'
 KDScrollView     = require './scrollview'
 KDScrollThumb    = require './scrollthumb'


Add 'util' module for project-relative path helpers

--- lib/core.coffee
+++ lib/core.coffee
@@ -9,7 +9,7 @@
 _ = require 'lodash'

 bus = require './bus'
-
+util = require './util'

 getAxiomModules = (config) ->
   config or= {}
@@ -40,14 +40,20 @@
   config:
     blacklist: []
     timeout: 2000
+    projectRoot: undefined

   # a place to record what responders we have attached
   responders: {}

   init: (config, modules) ->
+    core.projectRoot = util.findProjRoot()

     requireModule = (moduleName) ->
-      require "#{process.cwd()}/node_modules/axiom-#{moduleName}"
+      # Get a project directory-relative path for the axiom module's
+      # corresponding NPM module.
+      npmName = "axiom-#{moduleName}"
+      npmModuleName = util.projRel path.join('node_modules', npmName)
+      require npmModuleName

     core.reset()
     modules or= []
@@ -75,7 +81,15 @@
   load: (moduleName, module) ->
     {config} = module
     config or= {}
-    services = law.create module
+    services = law.create {
+      services: module.services
+      # We create a custom resolver for 'lib' dependencies which, within
+      # a Law service, loads an NPM module relative to the project root.
+      resolvers:
+        lib: (name) ->
+          requireName = path.join util.projRel('node_modules'), name
+          return require(requireName)
+    }

     contexts = {}

@@ -347,5 +361,6 @@
   # for sending interrupts
   signal: (channel, data) ->

+  util: require './util'

 module.exports = core


Remove verify_html as it isn't supported in TinyMCE 4

--- common/lib/xmodule/xmodule/js/src/html/edit.coffee
+++ common/lib/xmodule/xmodule/js/src/html/edit.coffee
@@ -53,7 +53,6 @@
       valid_children : "+body[style]",

       # Allow any elements to be used, e.g. link, script, math
-      verify_html: false,
       valid_elements: "*[*]",
       extended_valid_elements: "*[*]",
       invalid_elements: "",


FIX: Ensure time to resolve is rounded

FIX: Ensure time to resolve is rounded

--- src/app/helpdesk/states/dashboard/dashboard.coffee
+++ src/app/helpdesk/states/dashboard/dashboard.coffee
@@ -49,7 +49,7 @@
   statsUpdated = (error, stats) ->
     # TODO: Handle error
     $scope.data.stats.push stats
-    avgWaitTime = $scope.avgWaitTime   = stats.tickets.average_wait_time
+    avgWaitTime = $scope.avgWaitTime = Math.round stats.tickets.average_wait_time
     numUnresolved = $scope.numUnresolved = stats.tickets.number_unresolved
     # TODO: Work out the right values
     $scope.averageWaitTimeColor =


FIX: Comment for root state in index.coffee

--- src/app/teaching-periods/states/index/index.coffee
+++ src/app/teaching-periods/states/index/index.coffee
@@ -1,7 +1,7 @@
 angular.module('doubtfire.teaching-periods.states.index', [])

 #
-# Root state for units
+# Root state for teaching periods
 #
 .config((headerServiceProvider) ->
   headerServiceProvider.state 'teaching-periods/index', {


Fixed typo.

Fixed typo.

--- lib/dhcp.coffee
+++ lib/dhcp.coffee
@@ -114,7 +114,7 @@
 			return current if current and (current.NetworkName == nn or current.NetworkName == "HostInterfaceNetworking-#{nn}")

 		if server
-			if server.IP != ip or server.NetMask != netmaks or server.lowerIPAddress != lower_ip or server.upperIPAddress != upper_ip
+			if server.IP != ip or server.NetworkMask != netmaks or server.lowerIPAddress != lower_ip or server.upperIPAddress != upper_ip
 				exports.modify_hostonly_server netname, ip, netmask, lower_ip, upper_ip, callback
 			else
 				return do callback if callback
@@ -230,7 +230,7 @@
 			return current if current and (current.NetworkName == nn or current.NetworkName == "HostInterfaceNetworking-#{nn}")

 		if server
-			if server.IP != ip or server.NetMask != netmaks or server.lowerIPAddress != lower_ip or server.upperIPAddress != upper_ip
+			if server.IP != ip or server.NetworkMask != netmaks or server.lowerIPAddress != lower_ip or server.upperIPAddress != upper_ip
 				exports.modify_internal_server netname, ip, netmask, lower_ip, upper_ip, callback
 			else
 				return do callback if callback


missing exports

missing exports

--- bokehjs/src/coffee/widget/radio_button_group.coffee
+++ bokehjs/src/coffee/widget/radio_button_group.coffee
@@ -56,6 +56,7 @@
 class RadioButtonGroups extends Collection
   model: RadioButtonGroup

+module.exports =
   Model: RadioButtonGroup
   View: RadioButtonGroupView
   Collection: new RadioButtonGroups()


Live-update the job filter.

Live-update the job filter.

Previously, the filtered job array was calculated only on filter value
change.  We now also recalculate the filter result when the job dataset
(or its arrangement) changes.

--- dashboard/assets/javascripts/controllers.js.coffee
+++ dashboard/assets/javascripts/controllers.js.coffee
@@ -31,7 +31,7 @@
         ident = item.get('ident')

         url.indexOf(fv) != -1 || ident.indexOf(fv) != -1
-  ).property('filterValue')
+  ).property('filterValue', 'controllers.jobs.arrangedContent.@each')

 Dashboard.JobsController = Ember.ArrayController.extend
   itemController: 'job'


Issue #1: update the language grammar in the Atom plugin

--- tools/atom-plugin/language-micro/grammars/micro.cson
+++ tools/atom-plugin/language-micro/grammars/micro.cson
@@ -42,7 +42,7 @@
 	}
 	{
 		'comment': 'Keywords (it should be described before functions)'
-		'match': '\\b(fn|let)\\b'
+		'match': '\\b(fn|let|as)\\b'
 		'name': 'keyword.control.statement.micro'
 	}
 	{


Add operator alias MutationOperator.partiallyMapped

--- lib/crossover_operator.coffee
+++ lib/crossover_operator.coffee
@@ -97,7 +97,7 @@

   # Partially-mapped crossover operation
-  @PMX: (n)-> withRotation n, (c1, c2, p)->
+  @PMX: @partiallyMapped = (n)-> withRotation n, (c1, c2, p)->
     o = c1[...p]
     for q in [p..c1.length - 1]
       o[q] ?= do ->


set the width and height of the main container div to make it easier to align sidebars

--- scripts/views/layouts/workspace/sidebar.coffee
+++ scripts/views/layouts/workspace/sidebar.coffee
@@ -1,11 +1,12 @@
 define [
+  'jquery'
   'marionette'
   'cs!collections/media-types'
   'cs!views/workspace/menu/add'
   'cs!views/workspace/sidebar/toc'
   'hbs!templates/layouts/workspace/sidebar'
   'filtered-collection'
-], (Marionette, mediaTypes, AddView, TocView, sidebarTemplate) ->
+], ($, Marionette, mediaTypes, AddView, TocView, sidebarTemplate) ->

   return class Sidebar extends Marionette.Layout
     template: sidebarTemplate
@@ -35,3 +36,15 @@
       # TODO: Make the collection a FilteredCollection that only shows @model.accepts
       @addContent.show(new AddView {context:model, collection:@filteredMediaTypes})
       @toc.show(new TocView {model:model, collection:collection})
+
+    onWindowResize: () ->
+      $window = $(window)
+      $scrollable = @$el.find('> .boxed-group > .boxed-group-inner')
+      height = $window.height() - $scrollable.offset().top
+      $scrollable.css {height:height}
+
+    onRender: () ->
+      # Update the width/height of main so we can have Scrollable boxes that vertically stretch the entire page
+      $window = $(window)
+      $window.on('resize', @onWindowResize.bind(@))
+      @onWindowResize()


account: remove token created

account: remove token created

--- workers/social/lib/social/models/account.coffee
+++ workers/social/lib/social/models/account.coffee
@@ -53,7 +53,7 @@
         { name: 'updateInstance' }
         { name: 'notification' }
         { name : "RemovedFromCollection" }
-        { name : "tokenCreated" }
+
       ]
     sharedMethods :
       static:


SocialWorker: add migration step to fetchOrCreateAppStorage method

--- workers/social/lib/social/models/account.coffee
+++ workers/social/lib/social/models/account.coffee
@@ -919,12 +919,26 @@
     query                     = { accountId : @getId() }
     query["storage.#{appId}"] = { $exists : true }

-    JCombinedAppStorage.one query, (err, storage) =>
-      return callback err  if err
-      return callback err, storage  if storage
-      @createAppStorage options, (err, newStorage) ->
-        if err then callback err
-        callback null, newStorage
+    queue = [
+
+      =>
+        @migrateOldAppStorageIfExists { appId, version }, (err, storage) ->
+          return callback err            if err
+          return callback null, storage  if storage
+          queue.next()
+
+      =>
+        JCombinedAppStorage.one query, (err, storage) =>
+          return callback err  if err
+          return callback err, storage  if storage
+          @createAppStorage options, (err, newStorage) ->
+            if err then callback err
+            callback null, newStorage
+
+    ]
+
+    daisy queue
+

   createAppStorage: (options, callback) ->


Social: fix code style and add documentation

--- workers/social/lib/social/models/session.coffee
+++ workers/social/lib/social/models/session.coffee
@@ -81,7 +81,11 @@
       return callback err  if err
       return callback null, session

-
+  # fetchSession tries to fetch session with given clientId, if client id is not
+  # set, it tries to create a new session, if session doesnt exist in db with
+  # given clientId, it creates a new one
+  #
+  # ps: i didnt write this function, just documenting it ~ CS
   @fetchSession = (clientId, callback)->

     return @createSession callback  unless clientId
@@ -104,12 +108,9 @@
   # fetchSession ~ CS
   @fetchSessionByData = (data, callback)->
     @one data, (err, session)=>
-      if err
-        callback err
-      else if session?
-        callback null, { session }
-      else
-        @createNewSession data, callback
+      return callback err  if err
+      return callback null, { session }  if session?
+      @createNewSession data, callback

   @updateClientIP = (clientId, ipAddress, callback)->


remove workaround from osu.trans*

remove workaround from osu.trans*

--- resources/assets/coffee/osu_common.coffee
+++ resources/assets/coffee/osu_common.coffee
@@ -217,14 +217,7 @@

   trans: (key, replacements) ->
-    try
-      Lang.get key, replacements
-    catch
-      Lang.setLocale fallbackLocale
-      message = Lang.get key, replacements
-      Lang.setLocale currentLocale
-
-      message
+    Lang.get key, replacements

   transArray: (array, key = 'common.array_and') ->
@@ -242,11 +235,6 @@
   transChoice: (key, count, replacements) ->
     message = Lang.choice key, count, replacements, currentLocale

-    if message == key
-      message = Lang.choice key, count, replacements, fallbackLocale
-
-    message
-

   xhrErrorMessage: (xhr) ->
     validationMessage = xhr?.responseJSON?.validation_error


js timeout utility functions

js timeout utility functions

--- app/assets/javascripts/ab_admin/core/utils.js.coffee
+++ app/assets/javascripts/ab_admin/core/utils.js.coffee
@@ -43,7 +43,19 @@
     res[k] = v[0]
   res

-# jquery
+_.timeout = (timeout, fn) ->
+  setTimeout(fn, timeout)
+
+_.interval = (timeout, fn) ->
+  setInterval(fn, timeout)
+
+# execute function periodically while it return false
+_.tryInterval = (timeout, fn) ->
+  proxy_fn = ->
+    clearInterval(try_interval_id) if fn.call()
+  try_interval_id = setInterval(proxy_fn, timeout)
+
+# jquery utils
 $.fn.serializeJSON = ->
   json = {}
   jQuery.map $(this).serializeArray(), (n) ->


this maybe

this maybe

--- app/assets/javascripts/components/articles.js.coffee
+++ app/assets/javascripts/components/articles.js.coffee
@@ -16,7 +16,7 @@
 			React.DOM.h3
 				className: 'title'
 				'Send us a blog article that you would like to have analyzed by a expert mood musician from ListenLoop.'
-			React.createElement ArticleForm, handleNewArticle: @addArticle, handleNewSortFilter: @sortFilter
+			React.createElement ArticleForm, handleNewArticle: @addArticle
 			React.DOM.table
 				className: 'table table-bordered'
 				React.DOM.thead null


removed a console.debug statement.

removed a console.debug statement.

--- app/assets/javascripts/habberdash/lib/i18n.js.coffee
+++ app/assets/javascripts/habberdash/lib/i18n.js.coffee
@@ -8,7 +8,6 @@
         subLocale = if locale.length > 1 then topLocale["_#{locale[1].toUpperCase()}_"]
       if !@I18n[locale[0]]
         locale = @localization.preferedLocale
-        console.debug(locale[0])
         topLocale = @I18n[locale[0]] || {}
         subLocale = if locale.length > 1 then topLocale["_#{locale[1].toUpperCase()}_"]
     return @determinedLocale = {top: topLocale || {}, sub: subLocale || {}}


Update sidebar item percentage bars for etmodel issue #3733

--- app/assets/javascripts/lib/views/sidebar_view.coffee
+++ app/assets/javascripts/lib/views/sidebar_view.coffee
@@ -73,7 +73,7 @@
       result = gquery.future_value()

       $item      = $(item)
-      percentage = Math.round(result * 100)
+      percentage = Math.round(result)
       pixels     = "#{ percentage }px"

       if percentage is 0


OX-187 performance testing on server

OX-187 performance testing on server

--- app/assets/javascripts/model/binary/pullqueue.coffee
+++ app/assets/javascripts/model/binary/pullqueue.coffee
@@ -6,8 +6,8 @@
 class PullQueue

   # Constants
-  BATCH_LIMIT : 100
-  BATCH_SIZE : 1
+  BATCH_LIMIT : 10
+  BATCH_SIZE : 2
   ROUND_TRIP_TIME_SMOOTHER : .125
   BUCKET_TIME_SMOOTHER : .125


Fix multiple ajax calls and plugin instantiation

--- app/assets/javascripts/search_autocomplete.js.coffee
+++ app/assets/javascripts/search_autocomplete.js.coffee
@@ -33,6 +33,7 @@
     @saveOriginalState()

     @searchInput.addClass('disabled')
+    @autocomplete = false

     @bindEvents()

@@ -61,8 +62,12 @@
     @searchInput.on 'blur', @onSearchInputBlur

   enableAutocomplete: ->
+    return if @autocomplete
+
     dropdownMenu = @dropdown.find('.dropdown-menu')
     _this = @
+    loading = false
+
     @searchInput.glDropdown
         filterInputBlur: false
         filterable: true
@@ -72,7 +77,19 @@
         search:
           fields: ['text']
         data: (term, callback) ->
-          $.get(_this.autocompletePath, {
+          # Ensure this is not called when autocomplete is disabled because
+          # this method still will be called because `GitLabDropdownFilter` is triggering this on keyup
+          return if _this.autocomplete is false
+
+          # Do not trigger request if input is empty
+          return if _this.searchInput.val() is ''
+
+          # Prevent multiple ajax calls
+          return if loading
+
+          loading = true
+
+          jqXHR = $.get(_this.autocompletePath, {
               project_id: _this.projectId
               project_ref: _this.projectRef
               term: term
@@ -99,7 +116,8 @@
                     text: item.label
                     url: item.url
               callback(data)
-          )
+          ).always ->
+            loading = false

     @dropdown.addClass('open')
     @searchInput.removeClass('disabled')
@@ -109,23 +127,26 @@
     @dropdown.dropdown('toggle')

   onSearchInputKeyDown: (e) =>
-    # Remove tag when pressing backspace and input search is empty
-    if e.keyCode is KEYCODE.BACKSPACE and e.currentTarget.value is ''
-      @removeLocationBadge()
-      @searchInput.focus()
-
-    else if e.keyCode is KEYCODE.ESCAPE
-      @searchInput.val('')
-      @restoreOriginalState()
-    else
-      # Create new autocomplete if it hasn't been created yet and there's no badge
-      if @autocomplete is undefined
-        if !@badgePresent()
-          @enableAutocomplete()
+    switch e.keyCode
+      when KEYCODE.BACKSPACE
+        if e.currentTarget.value is ''
+          @removeLocationBadge()
+          @searchInput.focus()
+      when KEYCODE.ESCAPE
+        if @badgePresent()
+        else
+          @restoreOriginalState()
+
+          # If after restoring there's a badge
+          @disableAutocomplete() if @badgePresent()
       else
-        # There's a badge
         if @badgePresent()
           @disableAutocomplete()
+        else
+          @enableAutocomplete()
+
+    # Avoid falsy value to be returned
+    return

   onSearchInputFocus: =>
     @wrap.addClass('search-active')
@@ -193,6 +214,6 @@
     @resetSearchState()

   disableAutocomplete: ->
-    if @autocomplete?
+    if @autocomplete
       @searchInput.addClass('disabled')
-    @autocomplete = null
+    @autocomplete = false


fix problem with opening points

fix problem with opening points

Former-commit-id: ee3faeb059973d890874b436002aca5e301fb9b8 [formerly cc8e544400ef44c067bed9b8b30225b245c937f0] [formerly 97cd5066572b67d6fb72760acada6c5d9f82cdfa [formerly 97cd5066572b67d6fb72760acada6c5d9f82cdfa [formerly 3e067fcf556411d92532f74386d064f9bfd0cdd7]]]
Former-commit-id: 0558b8b26dfb7a37f120ad1d9c15b6b54ff2e9de [formerly b539213622b7048cb28872e804d99201c8137873]
Former-commit-id: 60b760e719d3359ef84cec6d32d9687bb4dc4cd7
Former-commit-id: 67d2f090c460754d31909d7a5884f4ab12a89b32

--- app/assets/javascripts/views/pointdetailsview.coffee
+++ app/assets/javascripts/views/pointdetailsview.coffee
@@ -74,9 +74,7 @@
       @$el.find('.m-point-wrap > *').css 'visibility', ''

       # when clicking outside of point, close it
-      $(document).on 'click.m-point-details', (ev)  =>
-        @close_details( !$(ev.target).data('target') )
-        ev.stopPropagation()
+      $(document).on 'click.m-point-details', (ev)  => @close_details( $(ev.target).closest('[data-role="m-point"]').length == 0 )

       @$el.on 'click.m-point-details', (ev) => ev.stopPropagation() if !$(ev.target).data('target')

@@ -96,8 +94,8 @@
     $(ev.currentTarget).parent().addClass('hide').siblings('.follow, .unfollow').removeClass('hide')
     ConsiderIt.current_user.set_following(data.follow.follow)

-  close_details : (trigger) ->
-    trigger ?= true
+  close_details : (go_back) ->
+    go_back ?= true
     @$el.find('.m-point-wrap > *').css 'visibility', 'hidden'

     @commentsview.clear()
@@ -115,6 +113,6 @@
     delete this

     @model.trigger 'change' #trigger a render event
-    ConsiderIt.app.go_back()
+    ConsiderIt.app.go_back() if go_back
     #next()


Accidentally used wrong syntax, caused build error. Updated syntax.

--- app/assets/javascripts/views/provider_view.js.coffee
+++ app/assets/javascripts/views/provider_view.js.coffee
@@ -21,9 +21,7 @@
     startDate = $(".start-date").val()
     endDate = $(".end-date").val()
     user = PopHealth.currentUser.get 'username'
-    $.post "home/set_reporting_period", {"effective_start_date": startDate,
-                                         "effective_end_date": endDate,
-                                         "username": user}, (d) -> location.reload()
+    $.post "home/set_reporting_period", {"effective_start_date": startDate, "effective_end_date": endDate, "username": user}, (d) -> location.reload()

 # Layout for provider index; includes search bar and provider table
 class Thorax.Views.ProvidersView extends Thorax.View


add another check if roles exist

add another check if roles exist

--- lib/sources/championgg.coffee
+++ lib/sources/championgg.coffee
@@ -112,6 +112,11 @@
     gg = parseGGData($c)
   catch err
     return step(new cErrors.ParsingError("Couldn\'t parse champion.gg script tag for #{champ}"))
+
+  # TODO: Another quick fix for users who seem to have some kind of software that is
+  # altering the response
+  if !gg.champion?.roles
+    return step(new cErrors.ParsingError("Couldn\'t parse roles from champion.gg script tag for #{champ}"))

   # Check what role were currently grabbing, and what other roles exist.
   currentPosition = ''


add some more debug logic

add some more debug logic

--- library/membrane/duplex.coffee
+++ library/membrane/duplex.coffee
@@ -345,7 +345,10 @@
     # to the opened channel. Refer to the `register` implementation
     # for more information on when, where and how this is happening.
     publishProviders: (context, binder, socket, next) ->
-        _.forIn this, (value, name, service) =>
+        assert ms = "Provide %s to %s in %s".magenta
+        assert id = @constructor.identify().underline
+        exec = (arbitrary) -> return next undefined
+        exec _.forIn this, (value, name, service) =>
             internal = "the #{value} is not function"
             providing = value?.providing or undefined
             return unless _.isFunction providing or 0
@@ -353,11 +356,13 @@
             bound = providing socket, context, binder
             assert mangled = "#{@location()}/#{name}"
             mangled += "/#{nsp}" if nsp = binder.nsp
+            assert _.isString si = try socket.id.bold
+            assert _.isString pn = name.toString().bold
+            logger.debug ms.magenta, pn, si.bold, id
             socket.on mangled, (args..., callback) =>
                 sentence = @downstream sentence: =>
                     bound.call this, args..., callback
                 sentence socket, name, value, args
-        return next undefined

     # A hook that will be called prior to unregistering the service
     # implementation. Please refer to this prototype signature for


ActivityActions: change pop-up relative point to share link not to activity actions view

--- client/Social/Activity/views/activityactions.coffee
+++ client/Social/Activity/views/activityactions.coffee
@@ -61,8 +61,8 @@
           cssClass    : "activity-share-popup"
           type        : "activity-share"
           delegate    : this
-          x           : @getX() + 160
-          y           : @getY() - 7
+          x           : @shareLink.getX() + 25
+          y           : @shareLink.getY() - 7
           menuMaxWidth: 400
           lazyLoad    : yes
         , customView  : new ActivitySharePopup delegate: this, url: shareUrl


client: fix bug where page scrolls to top when user clicks on 'x' others like this post link

--- client/Social/Activity/views/likesummaryview.coffee
+++ client/Social/Activity/views/likesummaryview.coffee
@@ -12,7 +12,8 @@
       .on "LikeChanged", @bound "handleLikeChanged"

-  showLikers: ->
+  showLikers: (event)->
+    KD.utils.stopDOMEvent event

     {id} = @getData()


minor changes/fixes and reorderings

minor changes/fixes and reorderings

--- library/nucleus/compose.coffee
+++ library/nucleus/compose.coffee
@@ -81,22 +81,6 @@
                 constructor = subject.constructor or null
                 return no unless _.isFunction constructor
                 accumulate.push try subject = constructor
-
-    # A method for comparing different classes for equality. Be careful
-    # as this method is very loose in terms of comparison and its main
-    # purpose is aiding in implementation of the composition mechanism
-    # rather than any else. Comparison algorithms is likely to change.
-    # This is used internally in the composition system implementation.
-    Object.defineProperty Object::, "similarWith",
-        enumerable: no, value: (archetype, loose) ->
-            isClass = _.isObject this.prototype
-            noClass = "the subject is not a class"
-            throw new Error noClass unless isClass
-            return yes if this is archetype or no
-            return yes if @watermark is archetype
-            return undefined unless loose is yes
-            return yes if @name is archetype.name
-            return yes if @nick is archetype.nick

     # A unique functionality built around the composition system. It
     # allows for an asynchronous way of calling a stream of methods,
@@ -236,3 +220,19 @@
             assert this.__super__ = baseclass.prototype
             try this.prototype = new ctor() or original
             _.extend this.prototype, original; this
+
+    # A method for comparing different classes for equality. Be careful
+    # as this method is very loose in terms of comparison and its main
+    # purpose is aiding in implementation of the composition mechanism
+    # rather than any else. Comparison algorithms is likely to change.
+    # This is used internally in the composition system implementation.
+    Object.defineProperty Object::, "similarWith",
+        enumerable: no, value: (archetype, loose) ->
+            isClass = _.isObject this.prototype
+            noClass = "the subject is not a class"
+            throw new Error noClass unless isClass
+            return yes if this is archetype or no
+            return yes if @watermark is archetype
+            return undefined unless loose is yes
+            return yes if @name is archetype.name
+            return yes if @nick is archetype.nick


syntax conv in the service mod

syntax conv in the service mod

--- library/nucleus/service.coffee
+++ library/nucleus/service.coffee
@@ -190,15 +190,15 @@
     # Supports implicit extraction of captured groups in the match.
     # Use this to configure what resources should match with service.
     @resource: (pattern) ->
-        identify = @identify().underline
+        assert identify = @identify().underline.toString()
         regexify = (s) -> new RegExp "^#{RegExp.escape(s)}$"
         pattern = regexify pattern if _.isString pattern
         inspected = pattern.unescape()?.underline or pattern
         associate = "Associating #{inspected} resource with %s"
         notRegexp = "The #{inspected} is not a valid regexp"
         assert _.isRegExp(pattern) and pattern.source, notRegexp
-        @resources = (@resources or []).concat pattern
-        logger.debug associate.grey, identify; this
+        assert @resources = (@resources or []).concat pattern
+        logger.debug associate.grey, identify; return this

     # This is a very basic method that adds the specified regular
     # expression pattern to the list of permitted domain patterns.
@@ -206,16 +206,15 @@
     # Supports implicit extraction of captured groups in the match.
     # Use this to configure what domains should match with service.
     @domain: (pattern) ->
-        previous = @domains or []
-        identify = @identify().underline
+        assert identify = @identify().underline.toString()
         regexify = (s) -> new RegExp "^#{RegExp.escape(s)}$"
         pattern = regexify pattern if _.isString pattern
         inspected = pattern.unescape()?.underline or pattern
         associate = "Associating #{inspected} domain with %s"
         notRegexp = "The #{inspected} is not a valid regexp"
         assert _.isRegExp(pattern) and pattern.source, notRegexp
-        @domains = (@domains or []).concat pattern
-        logger.debug associate.grey, identify; this
+        assert @domains = (@domains or []).concat pattern
+        logger.debug associate.grey, identify; return @

     # This method handles the rescuing of the request/response pair
     # when some error happens during the processing of the request
@@ -248,9 +247,9 @@
         hostname = _.first request.headers.host.split ":"
         pdomain = (p) -> gdomain = hostname.match p
         presource = (p) -> gresource = pathname.match p
-        pdomain = _.find domains, pdomain
-        presource = _.find resources, presource
-        assert gdomain isnt null, "missing domain"
+        pdomain = _.find(domains, pdomain) or null
+        presource = _.find(resources, presource) or null
+        assert gdomain isnt null, "missing the domain"
         assert gresource isnt null, "missing resource"
         @emit "process", gdomain, gresource, arguments...
         return domain: gdomain, resource: gresource
@@ -267,8 +266,8 @@
         hostname = _.first request.headers.host.split ":"
         pdomain = (pattern) -> pattern.test hostname
         presource = (pattern) -> pattern.test pathname
-        domainOk = _.some domains, pdomain
-        resourceOk = _.some resources, presource
-        matches = domainOk and resourceOk
-        @emit "matches", matches, arguments...
+        domainOk = _.some(domains, pdomain) or no
+        resourceOk = _.some(resources, presource) or no
+        matches = domainOk is yes and resourceOk is yes
+        @emit "matches", matches, request, response
         return decide domainOk and resourceOk


Append wrap-guide inside `.scroll-view`

Append wrap-guide inside `.scroll-view`

--- lib/wrap-guide-element.coffee
+++ lib/wrap-guide-element.coffee
@@ -14,8 +14,8 @@
     @element.getDefaultColumn = @getDefaultColumn.bind(this)

   attachToLines: ->
-    lines = @editorElement.rootElement?.querySelector?('.lines')
-    lines?.appendChild(@element)
+    scrollView = @editorElement.querySelector('.scroll-view')
+    scrollView?.appendChild(@element)

   handleEvents: ->
     updateGuideCallback = => @updateGuide()


better seaport logging

better seaport logging

--- library/nucleus/scaled.coffee
+++ library/nucleus/scaled.coffee
@@ -209,9 +209,10 @@
     # for instantiating, configuring and launching up the servers.
     # This version goes to the Seaport hub to obtain the options!
     startupHttpsServer: ->
+        type = "https".toUpperCase().bold
         assert _.isObject config = nconf.get()
         assert _.isObject(@seaport), "no seaport"
-        msg = "Got HTTPS port from the Seaport: %s"
+        msg = "Got #{type} port from the Seaport: %s"
         assert identica = @constructor.identica()
         cfg = config: config, identica: identica
         _.extend cfg, uuid: uuid.v4(), kind: "https"
@@ -228,9 +229,10 @@
     # for instantiating, configuring and launching up the servers.
     # This version goes to the Seaport hub to obtain the options!
     startupHttpServer: ->
+        type = "http".toUpperCase().bold
         assert _.isObject config = nconf.get()
         assert _.isObject(@seaport), "no seaport"
-        msg = "Got HTTP port from the Seaport: %s"
+        msg = "Got #{type} port from the Seaport: %s"
         assert identica = @constructor.identica()
         cfg = config: config, identica: identica
         _.extend cfg, uuid: uuid.v4(), kind: "http"


removed isTagParticipant check from sendTeamUpdate; added temp logging; #321

--- server/methods/mail/sendTeamUpdate.coffee
+++ server/methods/mail/sendTeamUpdate.coffee
@@ -7,7 +7,9 @@
 		project = Projects.findOne shift.projectId, fields: name: 1, email: 1

 		check { userId: Meteor.userId(), projectId: shift.projectId }, isMember
-		check { userId: Meteor.userId(), tagId: shift.tagId }, isTagParticipant
+		# fails sometimes because ? let's see what the logging beneath reveals
+		# check { userId: Meteor.userId(), tagId: shift.tagId }, isTagParticipant
+		console.log('sendTeamUpdate; shiftId:' + shiftId + '; tagId: ' + shift.tagId + '; userId: ' + Meteor.userId() + ' permitted: ' + Roles.userIsInRole(Meteor.userId(), Permissions.participant, shift.tagId))

 		if shift?
 			time = moment(shift.start, 'Hmm').format('HH:mm') + ' - ' + moment(shift.end, 'Hmm').format('HH:mm')


spec that coffeescript for_device_type block should run only once

--- spec/javascripts/mobvious-rails_spec.js.coffee
+++ spec/javascripts/mobvious-rails_spec.js.coffee
@@ -32,3 +32,12 @@
         'multiple_retval'
       expect(multiple_block_executed).toEqual true
       expect(multiple_retval).toEqual 'multiple_retval'
+
+    it 'should only run once', ->
+      block_executed_times = 0
+
+      multiple_retval = Mobvious.for_device_type 'desktop', 'mobile', ->
+        block_executed_times += 1
+        'multiple_retval'
+      expect(block_executed_times).toEqual 1
+      expect(multiple_retval).toEqual 'multiple_retval'


Get the trigger working to create and show/hide the DatePicker

--- tapestry-core/src/main/coffeescript/META-INF/modules/core/datefield.coffee
+++ tapestry-core/src/main/coffeescript/META-INF/modules/core/datefield.coffee
@@ -15,8 +15,65 @@
 # ##core/datefield
 #
 # Provides support for the `core/DateField` component.
-define ["core/dom", "core/events"],
-  (dom, events) ->
+define ["core/dom", "core/events", "core/messages", "core/builder", "_"],
+  (dom, events, messages, builder, _) ->
+
+    # Translate from the provided order (SUNDAY = 0, MONDAY = 1), to
+    # the order needed by the DatePicker component (MONDAY = 0 ... SUNDAY = 6)
+    serverFirstDay = parseInt messages "date-symbols.first-day"
+    datePickerFirstDay = if serverFirstDay is 0 then 6 else serverFirstDay - 1
+
+    # Loalize a few other things.
+    DatePicker.months = (messages "date-symbols.months").split ","
+    days = (messages "date-symbols.days").split ","
+    DatePicker.days = _.map days, (name) -> name.substr(0, 1).toLowerCase()
+
+    class Controller
+      constructor: (@container) ->
+        @field = @container.findFirst "input"
+        @trigger = @container.findFirst "button"
+
+        @trigger.on "click", =>
+          @doTogglePopup()
+          false
+
+      doTogglePopup: ->
+        return if @field.element.disabled
+
+        unless @popup
+          @createPopup()
+          return
+
+        if @popup.visible()
+          @popup.hide()
+        else
+          @popup.show()
+
+      createPopup: ->
+        @datePicker = new DatePicker()
+        @popup = builder "div.t-datefield-popup"
+        @popup.append dom @datePicker.create()
+        @trigger.insertAfter @popup
+
+      # @popup.absolutize().hide()
+
+      positionPopup: ->
+        reference = @container.findFirst "input[type=text], button"
+
+    scan = (root) ->
+      for container in root.find "[data-component-type=core/DateField]"
+        # Hide it from later scans
+        container.attribute "data-component-type", null
+
+        new Controller(container)
+
+    # Initialization:
+
+    scan dom.body()
+
+    # And scan any newly added content:
+
+    dom.onDocument events.zone.didUpdate, -> scan this

     # Exports nothing.
     return null


Upgrades for better kernel operations

Upgrades for better kernel operations

--- library/gearing/kernel.coffee
+++ library/gearing/kernel.coffee
@@ -72,13 +72,14 @@
         @setupConnectPipeline()
         server = nconf.get("server")
         secure = nconf.get("secure")
+        hostname = nconf.get("server:hostname")
         message = "Booted up the kernel instance".red
         rserver = "Running HTTP server at %s:%s".magenta
         rsecure = "Running HTTPS server at %s:%s".magenta
-        logger.info(rserver, server.hostname, server.port)
-        logger.info(rsecure, server.hostname, secure.port)
-        @secure.listen(secure, port, hostname)
-        @server.listen(port, hostname)
+        logger.info(rserver, hostname, server.port) if @server
+        logger.info(rsecure, hostname, secure.port) if @secure
+        @secure?.listen(secure, secure.port, hostname)
+        @server?.listen(server.port, hostname)
         logger.info(message); this

     # This method sets up the necessary internal toolkits, such as
@@ -109,6 +110,6 @@
         @connect.use(connect.bodyParser())
         @connect.use(connect.cookieParser())
         @connect.use m for m in middlewares
-        @server = http.createServer(@connect)
-        @secure = https.createServer(@connect)
+        @server = try http.createServer(@connect)
+        @secure = try https.createServer(@connect)
         @connect.use(@middleware)


CouchMuffin findAll fix

CouchMuffin findAll fix

--- server/src/Component/Builtin/Database/CouchMuffin.coffee
+++ server/src/Component/Builtin/Database/CouchMuffin.coffee
@@ -30,7 +30,7 @@
         data._lastUpdate = new Date().toISOString() if @_trackDates

     _query: (query, callback) ->
-        @_dataSource.bucket.query (@_dataSource.n1ql.fromString query), (error, result) ->
+        @_dataSource.bucket.query (new @_dataSource.N1qlQuery.fromString query), (error, result) ->
             callback error if error
             callback null, result


avoid double callback

avoid double callback

--- services/real-time/app/coffee/WebsocketController.coffee
+++ services/real-time/app/coffee/WebsocketController.coffee
@@ -113,7 +113,7 @@
 			AuthorizationManager.assertClientCanViewProject client, (error) ->
 				if error?
 					logger.warn {client_id: client.id, project_id, user_id}, "silently ignoring unauthorized updateClientPosition. Client likely hasn't called joinProject yet."
-					callback()
+					return callback()
 				cursorData.id      = client.id
 				cursorData.user_id = user_id if user_id?
 				cursorData.email   = email   if email?


:new: Add `showProviderName` config

:new: Add `showProviderName` config

--- lib/main.coffee
+++ lib/main.coffee
@@ -36,6 +36,11 @@
       type: 'string'
     underlineIssues:
       title: 'Underline Issues'
+      type: 'boolean'
+      default: true
+      order: 3
+    showProviderName:
+      title: 'Show Provider Name (when available)'
       type: 'boolean'
       default: true
       order: 3


Add minWordLength to the schema

Add minWordLength to the schema

--- lib/main.coffee
+++ lib/main.coffee
@@ -65,6 +65,11 @@
       type: 'boolean'
       default: false
       order: 9
+    minimumWordLength:
+      description: "Only autocomplete when you've typed at least this many characters."
+      type: 'integer'
+      default: 1
+      order: 10
     enableBuiltinProvider:
       title: 'Enable Built-In Provider'
       description: 'The package comes with a built-in provider that will provide suggestions using the words in your current buffer or all open buffers. You will get better suggestions by installing additional autocomplete+ providers. To stop using the built-in provider, disable this option.'


Force the format to default (#217)

Force the format to default (#217)

Override any format specified in the configuration file so the parsing of the output isn't broken.

--- lib/main.coffee
+++ lib/main.coffee
@@ -199,7 +199,7 @@
       lint: (textEditor) =>
         filePath = textEditor.getPath()
         fileText = textEditor.getText()
-        parameters = []
+        parameters = ['--format=default']

         if maxLineLength = atom.config.get('linter-flake8.maxLineLength')
           parameters.push('--max-line-length', maxLineLength)


kernel's bootstrap may take options

kernel's bootstrap may take options

--- library/nucleus/kernel.coffee
+++ library/nucleus/kernel.coffee
@@ -100,8 +100,9 @@
     # that are necessary, do the configuration on the kernel, then
     # boot it up, using the hostname and port parameters from config.
     # Please use this static method instead of manually launching up.
-    @bootstrap: -> new this ->
+    @bootstrap: (options={}) -> return new this ->
         @broker = new content.JsonBroker this
+        assert _.isObject(options), "no options"
         message = "Booted up the kernel instance"
         sigint = "Received the SIGINT (interrupt signal)"
         sigterm = "Received the SIGTERM (terminate signal)"


fix double callback for proc.on 'error' and proc.on 'close'

--- services/clsi/app/coffee/OutputFileOptimiser.coffee
+++ services/clsi/app/coffee/OutputFileOptimiser.coffee
@@ -2,6 +2,7 @@
 Path = require "path"
 spawn = require("child_process").spawn
 logger = require "logger-sharelatex"
+_ = require "underscore"

 module.exports = OutputFileOptimiser =

@@ -22,12 +23,15 @@
 		stdout = ""
 		proc.stdout.on "data", (chunk) ->
 			stdout += chunk.toString()
-		proc.on "error", callback
+		callback = _.once(callback) # avoid double call back for error and close event
+		proc.on "error", (err) ->
+			logger.warn {err, args}, "qpdf failed"
+			callback(null) # ignore the error
 		proc.on "close", (code) ->
 			if code != 0
-				logger.warn {directory, code}, "qpdf returned error"
-				return callback null
+				logger.warn {code, args}, "qpdf returned error"
+				return callback(null) # ignore the error
 			fs.rename tmpOutput, dst, (err) ->
 				if err?
 					logger.warn {tmpOutput, dst}, "failed to rename output of qpdf command"
-				callback err
+				callback(null) # ignore the error


artistview chart is now updating on newrating

--- src/scripts/directives/artist-view/artist-view.coffee
+++ src/scripts/directives/artist-view/artist-view.coffee
@@ -26,9 +26,14 @@
           .endAngle 90 * (pi / 180)
           .value (d) -> d.value

-        chart = svg.append "g"
+        chart = svg.selectAll ".chart"
           .data [votes]
-          .attr "transform", "translate(#{radius}, #{radius})"
+
+        chart
+          .enter()
+            .append "g"
+            .attr "class", "chart"
+            .attr "transform", "translate(#{radius}, #{radius})"

         slices = chart.selectAll ".slice"
           .data pie
@@ -41,5 +46,6 @@
           .transition().duration(1000)
             .attr "d", arc

-      scope.$watchCollection "songs", (newData) ->
+      scope.$watch "songs", (newData, oldData) ->
         render newData if newData isnt null
+      , true


Coffeescript is less bad.

Coffeescript is less bad.

--- filemanager/static/script/thumbloader.coffee
+++ filemanager/static/script/thumbloader.coffee
@@ -23,3 +23,4 @@

     register: (pk, gallery) ->
         this.datalist.push([pk,gallery])
+        console.log this.datalist


Activity: lazyload restored

Activity: lazyload restored

--- client/Main/maincontroller/mainviewcontroller.coffee
+++ client/Main/maincontroller/mainviewcontroller.coffee
@@ -42,7 +42,7 @@
       currentHeight = 0

       _.throttle (event)->
-        el = document.documentElement
+        el = document.body
         {scrollHeight, scrollTop} = el

         return  if scrollHeight <= window.innerHeight or scrollTop <= 0


MainViewController: Ignore no scrollbar states and negative scroll values

--- client/Main/maincontroller/mainviewcontroller.coffee
+++ client/Main/maincontroller/mainviewcontroller.coffee
@@ -46,6 +46,8 @@
       (event)->
         el = document.body
         {scrollHeight, scrollTop} = el
+
+        return  if scrollHeight <= window.innerHeight or scrollTop <= 0

         current = scrollTop + window.innerHeight
         if current > scrollHeight - threshold


missing word

missing word

--- spec/management/authenticator_spec.coffee
+++ spec/management/authenticator_spec.coffee
@@ -71,7 +71,7 @@
         authenticate( (request, response) ->

             #
-            # authentic, runs this (the actual)
+            # authentic, runs this (the actual request handler)
             #

             done()


shortcuts: rm obsolete listcontroller

shortcuts: rm obsolete listcontroller

--- client/app/lib/shortcuts/views/listcontroller.coffee
+++ client/app/lib/shortcuts/views/listcontroller.coffee
@@ -1,16 +0,0 @@
-kd                = require 'kd'
-ShortcutsListItem = require './listitem'
-_                 = require 'lodash'
-
-module.exports =
-
-class ShortcutsListController extends kd.ListViewController
-
-  constructor: (options={}, data) ->
-
-    options = _.extend {}, options,
-      view        : new kd.ListView
-        cssClass  : 'shortcuts-list'
-        itemClass : ShortcutsListItem
-
-    super options, data


DRYer demo code

DRYer demo code

--- demo/demo.coffee
+++ demo/demo.coffee
@@ -1,9 +1,11 @@
-text1 = 'HEXA'.split ''
-text2 = 'FLIP'.split ''
+demoText = [
+  'HEXA'.split ''
+  'FLIP'.split ''
+]
 logoSettings =
-    size: 120,
-    margin: 8,
-    fontSize: 82,
+    size:        120
+    margin:      8
+    fontSize:    82
     perspective: 450

 makeObj = (a) ->
@@ -25,9 +27,8 @@
   o

 document.addEventListener 'DOMContentLoaded', ->
-  logos = document.getElementsByClassName 'logo'
-  hexaLogo1 = new HexaFlip logos[0], makeObj(text1), logoSettings
-  hexaLogo2 = new HexaFlip logos[1], makeObj(text2), logoSettings
+  logos     = document.getElementsByClassName 'logo'
+  textDemos = (new HexaFlip logos[n], makeObj(demoText[n]), logoSettings for n in [0..1])
   hexaPhoto = new HexaFlip document.getElementById('photo-demo'),
     {photos: ("./demo/images/#{ i }.jpg" for i in [1..18])},
     size: 400
@@ -41,30 +42,30 @@
   hexaTime = new HexaFlip document.getElementById('time-demo'), null, size: 150, fontSize: 100

   setTimeout ->
-    hexaLogo1.setValue getSeq text1, true
-    hexaLogo2.setValue getSeq text2, true
+    textDemos[n].setValue getSeq demoText[n], true for n in [0..1]
+    null
   , 0

   setTimeout ->
-    hexaLogo1.setValue getSeq text1
-    hexaLogo2.setValue getSeq text2
+    textDemos[n].setValue getSeq demoText[n] for n in [0..1]
+    null
   , 1000

   setTimeout ->
       setInterval ->
-          hexaLogo1.setValue getSeq text1, false, true
-          hexaLogo2.setValue getSeq text2, false, true
+          textDemos[n].setValue getSeq demoText[n], false, true for n in [0..1]
+          null
       , 3000
   , 5000

   setTimeout ->
-    now = new Date
-    hour = now.getHours()
+    now    = new Date
+    hour   = now.getHours()
     minute = now.getMinutes().toString()

     if hour > 12
-      hour = (hour - 12).toString()
+      hour     = (hour - 12).toString()
       meridian = 'pm'
     else
       meridian = 'am'


Fix responsive styles (vendor stylesheet order was busted)

--- SingularityUI/config.coffee
+++ SingularityUI/config.coffee
@@ -31,6 +31,12 @@
         stylesheets:
             defaultExtension: 'styl'
             joinTo: 'static/css/app.css'
+            order:
+                before: [
+                    'vendor/styles/bootstrap.css'
+                    'vendor/styles/bootstrap-responsive.css'
+                    'vendor/styles/docs.css'
+                ]

         templates:
             defaultExtension: 'hbs'


About: removed avatarview

About: removed avatarview

--- client/landing/app/coffee/about/aboutlistitem.coffee
+++ client/landing/app/coffee/about/aboutlistitem.coffee
@@ -13,7 +13,9 @@
     super options, data

     {username} = @getData()
-    @avatar    = new AvatarView
+    @avatar    = new KDCustomHTMLView
+      tagName  : 'img'
+      cssClass : 'avatarview'
       origin   : username
       size     : width : 160


Add ran as admin

Add ran as admin

--- server/accounts.coffee
+++ server/accounts.coffee
@@ -26,3 +26,8 @@
     user.profile = {}

   user
+
+Meteor.startup ->
+  ran = Meteor.users.findOne({"services.google.email": "rantav@gmail.com"})
+  if ran
+    Roles.addUsersToRoles(ran._id, ['admin'], Roles.GLOBAL_GROUP)


set server -> null

set server -> null

--- lib/atom-ternjs.coffee
+++ lib/atom-ternjs.coffee
@@ -127,8 +127,9 @@
       @documentationView.hide()

   stopServer: ->
-    return unless @server?.process
-    @server.stop()
+    if @server?.process
+      @server.stop()
+    @server = null

   restartServer: ->
     if @server?.process


=== does not exist in coffee script

=== does not exist in coffee script

--- generators/application/test/unit/truth_test.coffee
+++ generators/application/test/unit/truth_test.coffee
@@ -1,3 +1,3 @@
-test 'Truth', ->
-  ok true === true, "Passed!"
+test 'Truth', ->
+  ok true == true, "Passed!"


Fix skipping on own items

Fix skipping on own items

--- modules/player/commands.coffee
+++ modules/player/commands.coffee
@@ -38,19 +38,19 @@
         }

     # Skip
-    @registerCommand 'skip', (msg, args, d, player)=>
-      msg.delete() if d.data.autoDel
+    @registerCommand 'skip', (m, args, d, player)=>
+      m.delete() if d.data.autoDel
       # Some checks
-      return if msg.author.bot
+      return if m.author.bot
       unless player.queue._d.items.length or player.queue._d.nowPlaying
-        return msg.reply 'Nothing being played in this server.'
+        return m.reply 'Nothing being played in this server.'
       # Instant skip for DJs and people who requested the current element
-      if @permissions.isDJ(msg.member) or msg.author is player.queue.nowPlaying.requestedBy
-        msg.channel.sendMessage "**#{msg.member.name}** skipped the current song."
+      if @permissions.isDJ(m.member) or m.author.id is player.queue._d.nowPlaying.requestedBy
+        m.channel.sendMessage "**#{m.member.name}** skipped the current song."
         return player.skip()
-      return msg.reply 'You are not allowed to skip songs.' unless d.data.voteSkip
+      return m.reply 'You are not allowed to skip songs.' unless d.data.voteSkip
       # Vote skip if enabled
-      commands.run('voteskip', msg, args)
+      commands.run('voteskip', m, args)

     @registerCommand 'voteskip', { aliases: ['vs'] }, (msg, args, d, player)=>
       msg.delete() if d.data.autoDel


Remove some logs

Remove some logs

--- packages/rocketchat-lib/settings/server/methods.coffee
+++ packages/rocketchat-lib/settings/server/methods.coffee
@@ -9,19 +9,20 @@
 	if not _id or not value?
 		return false

-	console.log '[functions] RocketChat.settings.add -> '.green, 'arguments:', arguments
+	# console.log '[functions] RocketChat.settings.add -> '.green, 'arguments:', arguments

 	if Meteor.settings?[_id]?
 		value = Meteor.settings[_id]
-
+
 	updateSettings =
 		i18nLabel: options.i18nLabel or _id
 		i18nDescription: options.i18nDescription if options.i18nDescription?
-
+
 	updateSettings.type = options.type if options.type
+	updateSettings.multiline = options.multiline if options.multiline
 	updateSettings.group = options.group if options.group
 	updateSettings.public = options.public if options.public
-
+
 	return Settings.upsert { _id: _id }, { $setOnInsert: { value: value }, $set: updateSettings }

 ###
@@ -33,7 +34,7 @@
 	if not _id
 		return false

-	console.log '[functions] RocketChat.settings.addGroup -> '.green, 'arguments:', arguments
+	# console.log '[functions] RocketChat.settings.addGroup -> '.green, 'arguments:', arguments

 	updateSettings =
 		i18nLabel: options.i18nLabel or _id
@@ -50,6 +51,6 @@
 		unless user?.admin is true
 			throw new Meteor.Error 503, 'Not authorized'

-		console.log "saveSetting -> ".green, _id, value
+		# console.log "saveSetting -> ".green, _id, value
 		Settings.update { _id: _id }, { $set: { value: value } }
 		return true


Add more 0.999 milli DateTime precision tests and comment out the current
one.

The existing test for 0.999 milli second precision causing the second,
minute, hour and day to flip on precision adjustment. This passes on some
verions of SQL Server but fails on the version of SQL Server on AppVeyor
machine. Commented that one out and instead added 0.999 milli second
precision tests that would flip second, minute and hour.

--- test/integration/parameterised-statements-test.coffee
+++ test/integration/parameterised-statements-test.coffee
@@ -208,7 +208,7 @@
 exports.dateTimeNull = (test) ->
   execSql(test, TYPES.DateTime, null)

-# The tests below validates DateTime precision on the input side, as described in
+# The tests below validate DateTime precision on the input side, as described in
 #  the section "Rounding of datetime Fractional Second Precision" from
 # https://msdn.microsoft.com/en-us/library/ms187819.aspx

@@ -239,8 +239,18 @@
 exports.dateTimePrecision_8 = (test) ->
   execSql(test, TYPES.DateTime, new Date('January 1, 1998 23:59:59.998'), null, null, new Date('January 1, 1998 23:59:59.997'))

-exports.dateTimePrecision_9 = (test) ->
-  execSql(test, TYPES.DateTime, new Date('January 1, 1998 23:59:59.999'), null, null, new Date('January 2, 1998 00:00:00.000'))
+exports.dateTimePrecision_9_sec_flip = (test) ->
+  execSql(test, TYPES.DateTime, new Date('January 1, 1998 23:59:58.999'), null, null, new Date('January 1, 1998 23:59:59.000'))
+
+exports.dateTimePrecision_9_min_flip = (test) ->
+  execSql(test, TYPES.DateTime, new Date('January 1, 1998 23:58:59.999'), null, null, new Date('January 1, 1998 23:59:00.000'))
+
+exports.dateTimePrecision_9_hr_flip = (test) ->
+  execSql(test, TYPES.DateTime, new Date('January 1, 1998 22:59:59.999'), null, null, new Date('January 1, 1998 23:00:00.000'))
+
+# This test fails on the version of SQL Server in AppVeyor.
+#exports.dateTimePrecision_9_day_flip = (test) ->
+#  execSql(test, TYPES.DateTime, new Date('January 1, 1998 23:59:59.999'), null, null, new Date('January 2, 1998 00:00:00.000'))

 exports.dateTime2 = (test) ->
   execSql(test, TYPES.DateTime2, new Date('December 4, 2011 10:04:23'), '7_3_A')
@@ -320,7 +330,7 @@
 exports.outputDateTimeNull = (test) ->
   execSqlOutput(test, TYPES.DateTime, null)

-# The tests below validates DateTime precision on the output side, as described in
+# The tests below validate DateTime precision on the output side, as described in
 #  the section "Rounding of datetime Fractional Second Precision" from
 # https://msdn.microsoft.com/en-us/library/ms187819.aspx

@@ -351,8 +361,18 @@
 exports.outputDatePrecision_8 = (test) ->
   execSqlOutput(test, TYPES.DateTime, new Date('January 1, 1998 23:59:59.998'), new Date('January 1, 1998 23:59:59.997'))

-exports.outputDatePrecision_9 = (test) ->
-  execSqlOutput(test, TYPES.DateTime, new Date('January 1, 1998 23:59:59.999'), new Date('January 2, 1998 00:00:00.000'))
+exports.outputDatePrecision_9_sec_flip = (test) ->
+  execSqlOutput(test, TYPES.DateTime, new Date('January 1, 1998 23:59:58.999'), new Date('January 1, 1998 23:59:59.000'))
+
+exports.outputDatePrecision_9_min_flip = (test) ->
+  execSqlOutput(test, TYPES.DateTime, new Date('January 1, 1998 23:58:59.999'), new Date('January 1, 1998 23:59:00.000'))
+
+exports.outputDatePrecision_9_hr_flip = (test) ->
+  execSqlOutput(test, TYPES.DateTime, new Date('January 1, 1998 22:59:59.999'), new Date('January 1, 1998 23:00:00.000'))
+
+# This test fails on the version of SQL Server in AppVeyor.
+#exports.outputDatePrecision_9_day_flip = (test) ->
+#  execSqlOutput(test, TYPES.DateTime, new Date('January 1, 1998 23:59:59.999'), new Date('January 2, 1998 00:00:00.000'))

 exports.multipleParameters = (test) ->
   test.expect(7)


The Great Rename

The Great Rename

--- test/lib/WorkflowExecutionHistoryGeneratorSpec.coffee
+++ test/lib/WorkflowExecutionHistoryGeneratorSpec.coffee
@@ -137,24 +137,24 @@
   it "should run complex history", ->
     generator.seed -> [
       events: [@WorkflowExecutionStarted
-                 "FreshdeskDownloadUsers":
-                   avatarId: "D6vpAkoHyBXPadp4c"
-                   params: {}
-                 "3DCartDownloadOrders":
-                   avatarId: "T7JwArn9vCJLiKXbn"
-                   baseUrl: "http://store.bellefit.com"
-                   params: {}
-                 "BellefitGenerate3DCartOrdersByFreshdeskUserIdCollection":
-                   avatarIds:
-                     "Freshdesk": "D6vpAkoHyBXPadp4c"
-                     "3DCart": "T7JwArn9vCJLiKXbn"
+         FreshdeskDownloadUsers:
+           avatarId: "D6vpAkoHyBXPadp4c"
+           params: {}
+         _3DCartDownloadOrders:
+           avatarId: "T7JwArn9vCJLiKXbn"
+           baseUrl: "http://store.bellefit.com"
+           params: {}
+         BellefitGenerate3DCartOrdersByFreshdeskUserIdCollection:
+           avatarIds:
+             Freshdesk: "D6vpAkoHyBXPadp4c"
+             _3DCart: "T7JwArn9vCJLiKXbn"
       ]
       decisions: [
         @ScheduleActivityTask "FreshdeskDownloadUsers",
           avatarId: "D6vpAkoHyBXPadp4c"
           params: {}
       ,
-        @ScheduleActivityTask "3DCartDownloadOrders",
+        @ScheduleActivityTask "_3DCartDownloadOrders",
           avatarId: "T7JwArn9vCJLiKXbn"
           params: {}
       ]
@@ -162,13 +162,13 @@
         events: [
           @ActivityTaskCompleted "FreshdeskDownloadUsers"
         ,
-          @ActivityTaskCompleted "3DCartDownloadOrders"
+          @ActivityTaskCompleted "_3DCartDownloadOrders"
         ]
         decisions: [
           @ScheduleActivityTask "BellefitGenerate3DCartOrdersByFreshdeskUserIdCollection",
             avatarIds:
-              "Freshdesk": "D6vpAkoHyBXPadp4c"
-              "3DCart": "T7JwArn9vCJLiKXbn"
+              Freshdesk: "D6vpAkoHyBXPadp4c"
+              _3DCart: "T7JwArn9vCJLiKXbn"
         ]
         branches: [
           events: [
@@ -181,13 +181,13 @@
           events: [@ActivityTaskCompleted "FreshdeskDownloadUsers"]
           decisions: []
         ,
-          events: [@ActivityTaskCompleted "3DCartDownloadOrders"]
+          events: [@ActivityTaskCompleted "_3DCartDownloadOrders"]
           decisions: []
         ,
           events: [@ActivityTaskFailed "FreshdeskDownloadUsers"]
           decisions: [@FailWorkflowExecution()]
         ,
-          events: [@ActivityTaskFailed "3DCartDownloadOrders"]
+          events: [@ActivityTaskFailed "_3DCartDownloadOrders"]
           decisions: [@FailWorkflowExecution()]
         ]
       ]


ignore gitignore

ignore gitignore

--- root/app.coffee
+++ root/app.coffee
@@ -3,7 +3,7 @@
 rupture      = require 'rupture'

 module.exports =
-  ignores: ['readme.md', '**/layout.*', '**/_*']
+  ignores: ['readme.md', '**/layout.*', '**/_*', '.gitignore']

   stylus:
     use: [axis(), autoprefixer(), rupture()]


fixed @Region test failure. why did travis-ci say it passed?

--- lib/coffeecloud.coffee
+++ lib/coffeecloud.coffee
@@ -88,10 +88,8 @@
     'Fn::Base64': arg
   GetAZs: (arg) ->
     'Fn::GetAZs': arg
-  Region: ->
-    'AWS::Region'
-  StackName: ->
-    'AWS::StackName'
+  Region: 'AWS::Region'
+  StackName: 'AWS::StackName'

 module.exports.CloudFormationTemplateContext = CloudFormationTemplateContext