Fix capitalisation of subsection macro

Fix capitalisation of subsection macro

This error is the fault of an online reference with incorrect info:

    http://www.lemoda.net/unix/troff-dictionary/index.html

The page erroneously lists several macros with inaccurate capitalisation
and describes some as GNU-specific. Since this source is unreliable, the
mention of GNU has been pulled from the TH macro's scope, as it may very
well be supported by other troff processors too.

--- grammars/roff.cson
+++ grammars/roff.cson
@@ -309,8 +309,8 @@
 	macros:
 		patterns: [{

-			# .TH: Title (GNU manual macro)
-			name: "markup.heading.title.gnu.man.macro.roff"
+			# .TH: Title
+			name: "markup.heading.title.man.macro.roff"
 			patterns: [{include: "#params"}]
 			begin: "^([.'])[ \t]*(TH)(?=[ \t]|$)"
 			end: "$"
@@ -329,10 +329,10 @@
 				2: {name: "entity.name.function.roff"}
 		},{

-			# .Ss: Subsection
+			# .SS: Subsection
 			name: "markup.heading.subsection.man.macro.roff"
 			patterns: [{include: "#params"}]
-			begin: "^([.'])[ \t]*(Ss)(?=[ \t]|$)"
+			begin: "^([.'])[ \t]*(SS)(?=[ \t]|$)"
 			end: "$"
 			beginCaptures:
 				1: {name: "punctuation.definition.macro.roff"}


Scope `finish` as a control-like keyword

Since it essentially behaves as a top-level return, according to E168.

--- grammars/viml.cson
+++ grammars/viml.cson
@@ -322,7 +322,7 @@
 	keyword:
 		patterns: [{
 			name: "keyword.control.$1.viml"
-			match: "\\b(if|while|for|return|try|catch|finally|end(if|for|while|try)?|else(if)?|do|in|:)\\b"
+			match: "\\b(if|while|for|return|try|catch|finally|finish|end(if|for|while|try)?|else(if)?|do|in|:)\\b"
 		},{
 			name: "keyword.operator.$1.viml"
 			match: "\\b(unlet)\\b"


Scene: Fix parenting of objects not in the scene, it should throw.

--- engine/scene.coffee
+++ engine/scene.coffee
@@ -122,6 +122,17 @@
     make_parent: (parent, child, keep_transform=true)->
         if child.parent
             @clear_parent child, keep_transform
+        auchildren = @auto_updated_children
+        # TODO: should we store the index in the objects
+        # to make this check faster?
+        parent_index = auchildren.indexOf(parent)
+        child_index = auchildren.indexOf(child)
+        if parent_index == -1
+            throw Error "Object '#{parent.name}' is not part of scene
+                '#{@name}'. Both parent and child must belong to it."
+        if child_index == -1
+            throw Error "Object '#{parent.name}' is not part of scene
+                '#{@name}'. Both parent and child must belong to it."
         if keep_transform
             {rotation_order} = child
             child.set_rotation_order 'Q'
@@ -134,12 +145,9 @@
             child.set_rotation_order rotation_order
         child.parent = parent
         parent.children.push child
-        auchildren = @auto_updated_children
-        # TODO: should we store the index in the objects
-        # to make this check faster?
-        if auchildren.indexOf(parent) > auchildren.indexOf(child)
+        if parent_index > child_index
             # When this is set to false, reorder_children() is called
-            # in render_manager.draw_viewport
+            # in update_all_matrices()
             @_children_are_ordered = false

     clear_parent: (child, keep_transform=true)->


Scene: Warn when enabling render with no camera.

--- engine/scene.coffee
+++ engine/scene.coffee
@@ -245,6 +245,8 @@
             ob.render = false

     enable_render: ->
+        if not @active_camera?
+            console.warn "Scene '#{@name}' has no active camera, nothing will be rendered."
         @enabled = true
         return @

@@ -253,6 +255,7 @@
         return @

     enable_physics: ->
+        # TODO: Warn if physics are disabled
         @physics_enabled = true
         return @


Update markup with class-named spans

Update markup with class-named spans

--- lib/ui.coffee
+++ lib/ui.coffee
@@ -20,8 +20,8 @@

   chosenTemplate: """

-      {{name}}
-      ×
+      {{name}}
+      ×

   """


clear row marker and early return from preview when no items

--- lib/ui.coffee
+++ lib/ui.coffee
@@ -433,6 +433,12 @@
       if @isActive()
         @selectItemForRow(@findRowForNormalItem(0, 'next'))
       @setModifiedState(false)
+      unless @hasItems()
+        @selectedItem = null
+        @previouslySelectedItem = null
+        @rowMarker?.destroy()
+        @rowMarker = null
+
       @emitDidRefresh()
       @emitDidStopRefreshing()

@@ -634,6 +640,11 @@
   preview: ->
     @preventSyncToEditor = true
     item = @getSelectedItem()
+    unless item
+      @preventSyncToEditor = false
+      @rowMarker?.destroy()
+      return
+
     @provider.openFileForItem(item).then (editor) =>
       editor.scrollToBufferPosition(item.point, center: true)
       @setRowMarker(editor, item.point)
@@ -739,6 +750,9 @@
   selectItem: (item) ->
     if (row = @getRowForItem(item)) >= 0
       @selectItemForRow(row)
+
+  hasItems: ->
+    @items.length > 1 # ignore prompt placeholder item

   selectItemForRow: (row) ->
     item = @items[row]


Work around pathwatcher silliness

Work around pathwatcher silliness

--- build/Gruntfile.coffee
+++ build/Gruntfile.coffee
@@ -163,7 +163,7 @@
       ]

     'build-atom-shell':
-      tag: "v0.21.0"
+      tag: "13c887d"
       nodeVersion: '0.21.0'
       remoteUrl: "https://github.com/atom/atom-shell"
       buildDir: buildDir


fix(linter): fix linter errors

fix(linter): fix linter errors

--- build/Gruntfile.coffee
+++ build/Gruntfile.coffee
@@ -389,7 +389,7 @@
   ciTasks.push('dump-symbols') if process.platform isnt 'win32'
   ciTasks.push('set-version', 'lint', 'generate-asar')

-  if process.platform is "darwin"
+  if process.platform is "darwin"
     ciTasks.push('test', 'codesign')

   if process.platform is "linux"


Add -> test to filter unique update actions.

--- test/product-import.spec.coffee
+++ test/product-import.spec.coffee
@@ -760,7 +760,48 @@
       .catch (err) ->
         done(err)

-
-
-
-
+    it ' :: should filter unique update actions', ->
+      sampleUpdateAction1 =
+        action: 'addPlainEnumValue'
+        attributeName: 'sample-enum-attribute'
+        value:
+          key: 'enum-1-key'
+          label: 'enum-1-key'
+
+      sampleUpdateAction2 =
+        action: 'addPlainEnumValue'
+        attributeName: 'sample-enum-attribute'
+        value:
+          key: 'enum-2-key'
+          label: 'enum-2-key'
+
+      sampleInput =
+        product_type_internal_id_1: [
+          sampleUpdateAction1
+        ,
+          sampleUpdateAction2
+        ,
+          sampleUpdateAction1
+        ]
+        product_type_internal_id_2: [
+          sampleUpdateAction2
+        ,
+          sampleUpdateAction1
+        ,
+          sampleUpdateAction2
+        ]
+
+      expectedOutput =
+        product_type_internal_id_1: [
+          sampleUpdateAction1
+        ,
+          sampleUpdateAction2
+        ]
+        product_type_internal_id_2: [
+          sampleUpdateAction2
+        ,
+          sampleUpdateAction1
+        ]
+
+      expect(@import._filterUniqueUpdateActions(sampleInput)).toEqual expectedOutput
+


Clean module on formatter helpeR.

Clean module on formatter helpeR.

--- lib/helpers/formatter_helper.coffee
+++ lib/helpers/formatter_helper.coffee
@@ -1,47 +1,36 @@
 "use strict"
-((NS) ->
-  # Filename: helpers/formatter_helper.coffee
-  NS = NS or {}
-  isInBrowser = typeof module is 'undefined' and typeof window isnt 'undefined'
+# Default confifuration of the formaters.
+format =
+  currency: '0,0.00'
+  date: 'L'
+  dateTime: 'LLL'

-  # Default confifuration of the formaters.
-  format =
-    currency: '0,0.00'
-    date: 'L'
-    dateTime: 'LLL'
-
-  # Container for all the formaters.
-  formaters = {}
-
-  #Update the configuration or the formater with the configuration given in option.
-  formaters.configure = (options) ->
-    _.extend(format, options)
+# Container for all the formaters.
+formaters = {}

-  #Format date
-  formaters.date = (prop, options) ->
-    options = options or {}
-    dateFormat = options.dateFormat or format.date
-    #Convert the isoString to a date without timezone.
-    if prop is undefined
-      return undefined
-    prop = prop.slice(0,10)
-    return moment(prop).format(dateFormat)
-
-  #Format dateTime
-  formaters.dateTime = (prop, options) ->
-    options = options or {}
-    dateTimeFormat = options.dateTimeFormat or format.dateTime
-    return  moment(prop).format(dateTimeFormat)
-
-  #Currency formatter
-  formaters.number = (prop, options) ->
-    options = options or {}
-    numeralFormat = options.numeralFormat or format.currency
-    return numeral(prop).format(numeralFormat);
-
-  if isInBrowser
-    NS.Helpers = NS.Helpers or {}
-    NS.Helpers.formaters  = formaters
-  else
-    module.exports = formaters
-)(if typeof module is 'undefined' and typeof window isnt 'undefined' then window.Fmk else module.exports)+#Update the configuration or the formater with the configuration given in option.
+formaters.configure = (options) ->
+  _.extend(format, options)
+
+#Format date
+formaters.date = (prop, options) ->
+  options = options or {}
+  dateFormat = options.dateFormat or format.date
+  #Convert the isoString to a date without timezone.
+  if prop is undefined
+    return undefined
+  prop = prop.slice(0,10)
+  return moment(prop).format(dateFormat)
+
+#Format dateTime
+formaters.dateTime = (prop, options) ->
+  options = options or {}
+  dateTimeFormat = options.dateTimeFormat or format.dateTime
+  return  moment(prop).format(dateTimeFormat)
+
+#Currency formatter
+formaters.number = (prop, options) ->
+  options = options or {}
+  numeralFormat = options.numeralFormat or format.currency
+  return numeral(prop).format(numeralFormat);
+module.exports = formaters


Corrected small bug.

Corrected small bug.

--- lib/process/nrepl-connection.coffee
+++ lib/process/nrepl-connection.coffee
@@ -152,10 +152,10 @@
       evalOptions = {op: "eval", code: wrappedCode, ns: ns, session: session}
       if options?.inlineOptions?.range?
         evalOptions.line = options.inlineOptions.range.start.row + 1
-        evalOptions.column = options.inlineOptions.range.start.col + 1
+        evalOptions.column = options.inlineOptions.range.start.column + 1

-      if options?.editor
-        evalOptions.file = options.editor.getPath()
+      if options?.inlineOptions?.editor
+        evalOptions.file = options.inlineOptions.editor.getPath()

       @conn.send evalOptions, (err, messages)=>
         try


removed arvid's idiotic copypasta

removed arvid's idiotic copypasta

--- workers/social/lib/social/models/messages/blog/index.coffee
+++ workers/social/lib/social/models/messages/blog/index.coffee
@@ -16,35 +16,6 @@
     html    : String
     checksum: String
   }
-
-  @generateHTML = (content)->
-
-    options =
-      gfm       : yes
-      sanitize  : yes
-      highlight : (code, lang)->
-        hljs = require('highlight.js')
-        try
-          hljs.highlight(lang, code).value
-        catch e
-          try
-            hljs.highlightAuto(code).value
-          catch _e
-            code
-      breaks     : yes
-      langPrefix : 'lang-'
-
-    marked = require('marked')
-    marked.setOptions options
-
-    markdown = sanitize(marked content).xss()
-    return markdown
-
-  @generateChecksum=(content)->
-    require('crypto')
-      .createHash('sha1')
-      .update(content)
-      .digest 'hex'

   @set
     slugifyFrom       : 'title'
@@ -74,22 +45,24 @@
   @getActivityType =-> require './blogpostactivity'

   @create = secure (client, data, callback)->
+    JMarkdownDoc = require '../../markdowndoc'
     blogPost  =
       meta        : data.meta
       title       : data.title
       body        : data.body
       group       : data.group
-      html        : @generateHTML data.body
-      checksum    : @generateChecksum data.body
+      html        : JMarkdownDoc.generateHTML data.body
+      checksum    : JMarkdownDoc.generateChecksum data.body
     JPost.create.call @, client, blogPost, callback

   modify: secure (client, data, callback)->
+    JMarkdownDoc = require '../../markdowndoc'
     blogPost =
       meta        : data.meta
       title       : data.title
       body        : data.body
-      html        : JBlogPost.generateHTML data.body
-      checksum    : JBlogPost.generateChecksum data.body
+      html        : JMarkdownDoc.generateHTML data.body
+      checksum    : JMarkdownDoc.generateChecksum data.body
     JPost::modify.call @, client, blogPost, callback

   reply: permit 'reply to posts',


Update version

Update version

--- index.cjsx
+++ index.cjsx
@@ -14,7 +14,7 @@
   description: "任务信息查询 & 任务面板强化"
   author: "马里酱"
   link: "https://github.com/malichan"
-  version: "1.1.4"
+  version: "1.1.5"
   reactClass: React.createClass
     getInitialState: ->
       fs = require "fs-extra"


fix typo

fix typo

--- index.cjsx
+++ index.cjsx
@@ -204,7 +204,7 @@
         refreshCountdown = getCountdown('refresh')
         if getCountdown('') <= 1
           accounted = true
-          presumedSenka = (senka - detail.rate).toFixed(1)
+          presumedSenka = (senka - baseDetail.rate).toFixed(1)
           presumedExp = exp - baseDetail.exp
         if accounted
           accountCountdown = 0


Add new filters

Add new filters

--- index.cjsx
+++ index.cjsx
@@ -2,8 +2,9 @@
 {_, $, $$, React, ReactBootstrap, FontAwesome, layout} = window
 {Grid, Row, Col, Input, Panel, OverlayTrigger, Tooltip} = ReactBootstrap

-categoryNames = ["空", "编成", "出击", "演习", "远征", "补给/入渠", "工厂", "改装"]
-typeNames = ["空", "单次任务", "每日任务", "每周任务", "3/7/0日任务", "2/8日任务", "每月任务"]
+filterNames = ["空", "编成任务", "出击任务", "演习任务", "远征任务", "补给/入渠任务", "工厂任务", "改装任务", "结婚任务", "日常任务", "周常任务", "月常任务"]
+categoryNames = ["", "编成", "出击", "演习", "远征", "补给/入渠", "工厂", "改装"]
+typeNames = ["", "单次任务", "每日任务", "每周任务", "3/7/0日任务", "2/8日任务", "每月任务"]

 module.exports =
   name: "quest-info"
@@ -12,7 +13,7 @@
   description: "任务信息查询 & 任务面板强化"
   author: "马里酱"
   link: "https://github.com/malichan"
-  version: "1.0.0"
+  version: "1.1.0"
   reactClass: React.createClass
     getInitialState: ->
       fs = require "fs-extra"
@@ -21,9 +22,9 @@
       quests[quest.game_id] = quest for quest in json
       {
         quests: quests
-        quest_category: 0
+        quest_filter: 0
         quest_id: 0
-        quests_in_category: []
+        quests_filtered: []
         quest_selected: null
       }
     handleTaskChange: (e) ->
@@ -38,23 +39,35 @@
         detail:
           tasks: tasks
       window.dispatchEvent event
-    handleCategoryChange: (cid) ->
-      quest_category = cid
-      quests_in_category = (quest for quest in @state.quests when quest? and quest.category is quest_category)
-      quests_in_category = _.sortBy quests_in_category, (e) ->
+    handleFilterChange: (fid) ->
+      quest_filter = fid
+      quests_filtered = switch quest_filter
+        when 0
+          []
+        when 1, 2, 3, 4, 5, 6, 7
+          (quest for quest in @state.quests when quest? and quest.category is quest_filter and quest.wiki_id.charAt(0) isnt "W")
+        when 8
+          (quest for quest in @state.quests when quest? and quest.wiki_id.charAt(0) is "W")
+        when 9
+          (quest for quest in @state.quests when quest? and quest.type in [2, 4, 5])
+        when 10
+          (quest for quest in @state.quests when quest? and quest.type is 3)
+        when 11
+          (quest for quest in @state.quests when quest? and quest.type is 6)
+      quests_filtered = _.sortBy quests_filtered, (e) ->
         e.wiki_id
       @setState
-        quest_category: quest_category
-        quests_in_category: quests_in_category
+        quest_filter: quest_filter
+        quests_filtered: quests_filtered
     handleQuestChange: (qid) ->
       quest_id = qid
       quest_selected = @state.quests[quest_id]
       @setState
         quest_id: quest_id
         quest_selected: quest_selected
-    handleCategorySelect: (e) ->
-      quest_category = parseInt e.target.value
-      @handleCategoryChange quest_category
+    handleFilterSelect: (e) ->
+      quest_filter = parseInt e.target.value
+      @handleFilterChange quest_filter
       @setState
         quest_id: 0
         quest_selected: null
@@ -62,9 +75,15 @@
       quest_id = parseInt e.target.value
       @handleQuestChange quest_id
     handlePrereqClick: (qid) ->
-      quest_category = @state.quests[qid].category
+      quest = @state.quests[qid]
+      quest_filter = switch
+        when quest.type in [2, 4, 5] then 9
+        when quest.type is 3 then 10
+        when quest.type is 6 then 11
+        when quest.wiki_id.charAt(0) is "W" then 8
+        else quest.category
       quest_id = qid
-      @handleCategoryChange quest_category
+      @handleFilterChange quest_filter
       @handleQuestChange quest_id
     componentDidMount: ->
       window.addEventListener "task.change", @handleTaskChange
@@ -75,16 +94,16 @@
           <Row>
             <Col xs=12>
               <Panel header='任务选择' bsStyle='primary'>
-                <Input type='select' label='任务种类' value={@state.quest_category} onChange={@handleCategorySelect}>
+                <Input type='select' label='任务种类' value={@state.quest_filter} onChange={@handleFilterSelect}>
                   {
-                    for category, idx in categoryNames
-                      <option key={idx} value={idx}>{category}</option>
+                    for filter, idx in filterNames
+                      <option key={idx} value={idx}>{filter}</option>
                   }
                 </Input>
                 <Input type='select' label='任务名称' value={@state.quest_id} onChange={@handleQuestSelect}>
                   <option key={0}>空</option>
                   {
-                    for quest in @state.quests_in_category
+                    for quest in @state.quests_filtered
                       <option key={quest.game_id} value={quest.game_id}>{quest.wiki_id} - {quest.name}</option>
                   }
                 </Input>


Remove loggers

Remove loggers

--- lib/services/php-file-parser.coffee
+++ lib/services/php-file-parser.coffee
@@ -683,7 +683,6 @@
                 console.log 'Failed to get methods for ' + calledClass + ' : ' + methods.error.message

             return
-        console.log(methods.values)
         if methods.values?.hasOwnProperty(term) == -1
             return


Update toggle.coffee

Update toggle.coffee

Explicitly change button state when button is pressed.

--- bokehjs/src/coffee/widget/toggle.coffee
+++ bokehjs/src/coffee/widget/toggle.coffee
@@ -37,7 +37,7 @@
     return @

   change_input: () ->
-    @mset('active', @$el.hasClass("bk-bs-active"))
+    @mset('active', not @mget('active'))
     @mget('callback')?.execute(@model)

 class Toggle extends AbstractButton.Model


fix two shift scheduling bugs

fix two shift scheduling bugs

--- both/methods/shift/shiftSchedule.coffee
+++ both/methods/shift/shiftSchedule.coffee
@@ -74,7 +74,8 @@
 							$addToSet: 'teams.$.participants': approvedUser
 						break

-					Meteor.call 'closeTeam', shiftId, teamId
+					if team.participants.length == team.max - 1
+						Meteor.call 'closeTeam', shiftId, teamId
 				else
 					for user in team.participants when user._id == userId
 						wholeTeamCancelled = false
@@ -172,6 +173,8 @@
 					if participantData.informed and userId != Meteor.userId()
 						Meteor.call 'sendReversal', shiftId, teamId, userId

+					Meteor.call 'openTeam', shiftId, teamId
+
 	setLeader: (shiftId, teamId, userId) ->
 		shift = Shifts.findOne shiftId, fields: teams: 1, tagId: 1, projectId: 1
 		user = Meteor.users.findOne userId, fields: _id: 1


:lipstick:

:lipstick:

--- lib/views/delete-branch-view.coffee
+++ lib/views/delete-branch-view.coffee
@@ -3,7 +3,6 @@
 BranchListView = require './branch-list-view'

 module.exports =
-  # Extension of BranchListView
   class DeleteBranchListView extends BranchListView
     initialize: (@repo, @data, {@isRemote}={}) -> super


referral: invitation mail text update

referral: invitation mail text update

--- workers/social/lib/social/models/referrableemail.coffee
+++ workers/social/lib/social/models/referrableemail.coffee
@@ -56,18 +56,13 @@
       from    : 'hello@koding.com'
       email   : @email
       replyto : 'hello@koding.com'
-      subject : "#{@username} has invited you to Koding!"
+      subject : "#{firstName} #{lastName} has invited you to try Koding!"
       content : """
-        Hi there,
-
-        #{firstName} #{lastName} wants you to try Koding!
-
         Koding is a new way for developers to work where developers come together and code in the browser – with a real development server to run their code.
-        Developers can work, collaborate, write and run apps without jumping through hoops and spending unnecessary money.

         Click here to try: #{shareUrl}

-        See you on Koding
+        See you on Koding!
         """

     email.save (err)=>


Fixed genericAttributes to use newer api

--- scripts/genericAttributesTab.coffee
+++ scripts/genericAttributesTab.coffee
@@ -1,10 +1,13 @@
 ReportTab = require './reportTab.coffee'
-templates = require '../templates/templates.js'
+templates = require 'api/templates'
+partials = []
+for key, val of templates
+  partials[key.replace('node_modules/seasketch-reporting-api/', '')] = val

 class GenericAttributesTab extends ReportTab
   name: 'Attributes'
   className: 'genericAttributes'
-  template: templates.genericAttributes
+  template: templates['node_modules/seasketch-reporting-api/genericAttributes']

   render: () ->
     context =
@@ -12,7 +15,7 @@
       sketchClass: @sketchClass.forTemplate()
       attributes: @model.getAttributes()
       admin: @project.isAdmin window.user
-    @$el.html @template.render(context, templates)
+    @$el.html @template.render(context, partials)

 module.exports = GenericAttributesTab


Add css attributes to placeHolder

Add css attributes to placeHolder

--- BackofficeBundle/Resources/public/coffee/areaView.coffee
+++ BackofficeBundle/Resources/public/coffee/areaView.coffee
@@ -76,7 +76,12 @@
     $("ul.ui-model-blocks", @el).remove() if $("ul.ui-model-blocks", @el).children().length == 0
     if $("ul.ui-model-areas", @el).children().length == 0
       $("ul.ui-model-areas", @el).remove()
-      $("ul.ui-model-blocks", @el).sortable(connectWith: "ul.ui-model-blocks").disableSelection()
+      $("ul.ui-model-blocks", @el).sortable(
+        connectWith: "ul.ui-model-blocks",
+        start: (event, ui)->
+            ui.placeholder.css('height', ui.helper.css('height'))
+            ui.placeholder.css('width', ui.helper.css('width'))
+      ).disableSelection()
     this

   addAreaToView: (area, areaHeight) ->


Corrected facts

Corrected facts

--- scripts/facts.coffee
+++ scripts/facts.coffee
@@ -66,7 +66,7 @@
   "Only half a billionth of the energy released by the Sun reaches Earth.",
   "Rogue planets are not bound by any star, brown dwarf or another planet which makes them free-float around the galaxy.",
   "Sweeps 10 is the planet with the shortest orbital period found. It orbits its star in only 10 hours.",
-  "85% of all stars in our galaxy are part of multiple-star systems.",
+  "85\% of all stars in our galaxy are part of multiple-star systems.",
   "Some brown dwarfs have liquid iron rain falling down on them.",
   "The light emitted by the Sun is actually 30,000 years old.",
   "Of the over 20 million meteors that are observable every day only one or two reach the surface of Earth.",


don't decrement karma if there's a space before `--`

--- scripts/karma.coffee
+++ scripts/karma.coffee
@@ -92,7 +92,7 @@
     else
       msg.send msg.random karma.selfDeniedResponses(msg.message.user.name)

-  robot.hear /(?:[\(]([\S\s]+)[\)]|([\S]+[^()]))--(\s|$)/, (msg) ->
+  robot.hear /(?:[\(]([\S\s]+)[\)]|([\S]+[^()][^ ]))--(\s|$)/, (msg) ->
     subject = (msg.match[1] || msg.match[2]).toLowerCase()
     if allow_self is true or msg.message.user.name.toLowerCase() != subject
       karma.decrement subject


taco town meme

taco town meme

--- scripts/memes.coffee
+++ scripts/memes.coffee
@@ -55,6 +55,9 @@
   robot.hear /pull yourself together/i, (msg) ->
     msg.send 'http://i.imgur.com/JNrl4.gif'

+  robot.respond /taco town/i, (msg) ->
+    msg.send 'http://i848.photobucket.com/albums/ab49/iamfilthy/taco_town.gif'
+
   robot.respond /torture .* kitten/i, (msg) ->
     msg.send 'http://awesomegifs.com/wp-content/uploads/kitten-mittens-always-sunny.gif'


input: null and undefined as non-values

input: null and undefined as non-values

--- input/index.coffee
+++ input/index.coffee
@@ -93,7 +93,7 @@
     z '.zp-input',
       className: z.classKebab {
         isFloating
-        hasValue: value isnt ''
+        hasValue: value? and value isnt ''
         isFocused
         isDisabled
         isError: error?


disable preview scraping for old messages

--- scripts/theme.coffee
+++ scripts/theme.coffee
@@ -25,11 +25,12 @@
     $('.actionMessageUserName', fragment).addClass('sender')
     $('.actionMessageBody', fragment).text (i, text) -> " #{text}"

-  $('a', fragment)
-  .each( (i) -> Preview.loadPreviews fragment, this )
-  .filter( (i) -> $(@).text() is $(@).attr('href') )
-  .text( (i, text) -> text.replace /// \w+ :// ([^/]+) (?: /.* )? ///, '$1\u2026' )
-  .addClass('shortened')
+  unless fragment.hasClass 'history'
+    $('a', fragment)
+    .each( (i) -> Preview.loadPreviews fragment, this )
+    .filter( (i) -> $(@).text() is $(@).attr('href') )
+    .text( (i, text) -> text.replace /// \w+ :// ([^/]+) (?: /.* )? ///, '$1\u2026' )
+    .addClass('shortened')

   $('button', fragment).button()


Client: Activity: Feed: Addded messages getter and set likers to the messages in this getter

--- client/activity/lib/flux/getters.coffee
+++ client/activity/lib/flux/getters.coffee
@@ -102,9 +102,24 @@
       , immutable.Map()
 ]

+messages = [
+  MessagesStore
+  MessageLikersStore
+  allUsers
+  (messages, likers, users) ->
+    messages.map (msg) ->
+      msg.updateIn ['interactions', 'like'], (like) ->
+        like.withMutations (like) ->
+          messageLikers = likers.get (msg.get 'id'), immutable.Map()
+          like
+            .set 'actorsPreview', messageLikers.map (id) -> users.get id
+            .set 'actorsCount', messageLikers.size
+            .set 'isInteracted', messageLikers.contains whoami()._id
+]
+
 messagesWithComments = [
   MessageThreadsStore
-  MessagesStore
+  messages
   MessageFlagsStore
   (threads, messages, flags) ->
     messages
@@ -219,14 +234,6 @@
           # don't show channel name on post body.
           body.replace(///\##{channel.get('name')}($|\s)///, '').trim()

-        msg.updateIn ['interactions', 'like'], (like) ->
-          like.withMutations (like) ->
-            messageLikers = likers.get (msg.get 'id'), immutable.Map()
-            like
-              .set 'actorsPreview', messageLikers.map (id) -> users.get id
-              .set 'actorsCount', messageLikers.size
-              .set 'isInteracted', messageLikers.contains whoami()._id
-
     return thread
 ]


[About: #27976329] changed options and piped input stream default

--- bin/precious.coffee
+++ bin/precious.coffee
@@ -20,7 +20,7 @@

 # There are several man pages, reused for help.
-man = (page) ->
+man = (page, status = 0) ->
   require('child_process').exec "man #{page}", (err, out) ->
     if err
       console.error "Can't get: `man #{page}`."
@@ -28,6 +28,7 @@
       process.exit(1)
     else
       console.log out
+      process.exit(status)

 # Fill in the input with convenient niceties / default settings.
@@ -70,13 +71,13 @@

 # Processing of command-line args.  Minimal on purpose.
-# Expects `<json>` string or `-i <file>`.
 # Does help with man pages for precious, precious-json.
 args = process.argv.splice(2)
-if args.length > 0
-  if args[0] is '-i'
+if args.length > 0 then switch args[0]
+
+  when '-f', '--file'
     unless args[1]?
-      console.error "Usage: precious -i <file>"
+      console.error "Usage: precious -f <file>"
       process.exit(1)
     require('fs').readFile "./#{args[1]}", "utf8", (err, data) ->
       if err
@@ -85,7 +86,27 @@
         console.error err
         process.exit(1)
       else fetch data
-  else if args[0] is "json" then man "precious-json"
-  else fetch args[0]
-else man "precious"

+  when '-o', '--json'
+    if args[1]? then fetch args[1]
+    else
+      console.error "Usage: precious -o <json>"
+      console.error "No JSON provided, format instructions follow...\n"
+      man "precious-json", 1
+
+  when '-h', '--help'
+    if args?[1] is "json" then man "precious-json"
+    else man "precious"
+
+  else
+    console.error "Unclear usage, instructions follow...\n"
+    man "precious", 1
+
+
+# stream pipe expected as default
+else
+  process.stdin.resume()
+  process.stdin.setEncoding("utf8")
+
+  process.stdin.on "data", (data) -> fetch data
+


Test/Utilities fix coffeelint error

Test/Utilities fix coffeelint error

--- client/test/lib/dashboard/myteam.coffee
+++ client/test/lib/dashboard/myteam.coffee
@@ -42,7 +42,7 @@
           next null, result
       # (next) ->
       #   myteamhelper.uploadAndRemoveLogo browser, host, (result) ->
-      #     next null, result
+      #     next null, result
       (next) ->
         myteamhelper.inviteAndJoinToTeam browser, host, (result) ->
           next null, result


Fix string constants in macros

Fix string constants in macros

--- src/js/app/compilers/teascript/compiler.coffee
+++ src/js/app/compilers/teascript/compiler.coffee
@@ -1718,7 +1718,7 @@
   switch typeof value
     when 'boolean' then (tokenize (if value then 'True' else 'False'))[0]
     when 'number' then (tokenize (if value < 0 then "~#{Math.abs value}" else "#{value}"))[0]
-    when 'string' then (tokenize "#{value}")[0]
+    when 'string' then (tokenize JSON.stringify value)[0]
     when 'object'
       kind = Object.prototype.toString.call(value).slice(8, -1)
       value


Fix seq_at and remove == from contexts for completion

--- src/js/app/compilers/teascript/compiler.coffee
+++ src/js/app/compilers/teascript/compiler.coffee
@@ -3885,7 +3885,7 @@
   if (typeof xs === "undefined" || xs === null) {
     throw new Error('Pattern matching required sequence got undefined');
   }
-  if (Immutable.List.isList(xs)) {
+  if (Immutable.Iterable.isIterable(xs)) {
     if (i >= xs.size) {
       throw new Error('Pattern matching required a list of size at least ' + (i + 1));
     }
@@ -4152,6 +4152,7 @@
     found = savedScopes[scope]
     scope = found.parent
     found.definitions)..., ctx._scope()
+  removeFromMap definitions, '=='
   findMatchingDefinitionsOnType type, definitions

 findMatchingDefinitionsOnType = (type, definitions) ->


fixing packaging regression from b9a2a486ffd4d

--- c3_renderers.coffee
+++ c3_renderers.coffee
@@ -1,13 +1,13 @@
 callWithJQuery = (pivotModule) ->
     if typeof exports is "object" and typeof module is "object" # CommonJS
-        pivotModule require("jquery")
+        pivotModule require("jquery"), require("c3")
     else if typeof define is "function" and define.amd # AMD
-        define ["jquery"], pivotModule
+        define ["jquery", "c3"], pivotModule
     # Plain browser env
     else
-        pivotModule jQuery
+        pivotModule jQuery, c3

-callWithJQuery ($) ->
+callWithJQuery ($, c3) ->

     makeC3Chart = (chartOpts = {}) -> (pivotData, opts) ->
         defaults =


Update latest link on page changes

Update latest link on page changes

--- src/scripts/modules/media/latest/latest.coffee
+++ src/scripts/modules/media/latest/latest.coffee
@@ -18,4 +18,4 @@

     initialize: () ->
       super()
-      @listenTo(@model, 'change:isLatest', @render)
+      @listenTo(@model, 'change:isLatest change:currentPage', @render)


Add fixtures for headings

Add fixtures for headings

--- test/src/test_helpers/fixtures/fixtures.coffee
+++ test/src/test_helpers/fixtures/fixtures.coffee
@@ -480,9 +480,21 @@
     document: createDocument(["a\nb"], ["c", {}, ["quote"]])
     html: "
#{blockComment}a
b

#{blockComment}c
"

-  "two adjacent headers":
+  "empty heading block":
+    document: createDocument(["", {}, ["heading1"]])
+    html: "
#{blockComment}

"
+
+  "two adjacent heading":
     document: createDocument( ["a", {}, ["heading1"]], ["b", {}, ["heading1"]])
     html: "
#{blockComment}a

#{blockComment}b
"
+
+  "heading in ordered list":
+    document: createDocument(["a", {}, ["numberList", "number", "heading1"]])
+    html: "

#{blockComment}a

"
+
+  "headings with formatted text":
+    document: createDocument(["a", { bold: true }, ["heading1"]], ["b", { italic: true, bold: true }, ["heading1"]])
+    html: "
#{blockComment}a

#{blockComment}b
"

 @eachFixture = (callback) ->
   for name, details of @fixtures


Yuuup, been slackin

Yuuup, been slackin

--- server/crypto.coffee
+++ server/crypto.coffee
@@ -76,7 +76,7 @@
 #       512-bit salt will be generated.
 #
 #     * `iterations`: The number of iterations to use for the PBKDF. Defaults
-#       to 10000\. **NOTE:** This ***must*** be the same number when
+#       to 20000\. **NOTE:** This ***must*** be the same number when
 #       generating and verifying hashes, otherwise verification will fail.

 # *Cryptographic authentication functionality.*
@@ -98,8 +98,8 @@
       exports.hasher options
     )

-  options.digest ?= 'sha1'
-  options.iterations ?= 10000
+  options.digest ?= 'sha512'
+  options.iterations ?= 20000

   exports.pbkdf2(
     options.plaintext, options.salt, options.iterations, 64, options.digest


Sort events returned by events-with-resolved-data

--- server/router.coffee
+++ server/router.coffee
@@ -286,6 +286,9 @@
       deleted:
         $in: [null, false]
     ).fetch()
+  # sort events so they are returned in same order as the ids
+  events = eventIds.map (eventId)->
+    events.findOne(eventId)
   events.forEach (event) ->
     if event.incidents
       query =
@@ -355,6 +358,7 @@
         .sortBy('date')
         .value()
       return {
+        eventId: event._id
         eventName: event.eventName
         locations: countryCodeToCount
         timeseries: overallTimeseries


Tech works under env variable

Tech works under env variable

--- server/server.coffee
+++ server/server.coffee
@@ -55,13 +55,12 @@

 configurePassport(app, db)

-###
-app.use (req, res, next) ->
-    if not req.user?.admin
-        res.status(503).send("На сервере проводятся технические работы. Ожидаемая продолжительность — до часа.")
-        return
-    next()
-###
+if process.env["TECH_WORKS"]
+    app.use (req, res, next) ->
+        if not req.user?.admin
+            res.status(503).send("На сервере проводятся технические работы. Ожидаемая продолжительность — несколько часов.")
+            return
+        next()

 setupApi(app)


remove deprecated math script based on decommissioned google math service

--- roles/hubot/files/scripts/math.coffee
+++ roles/hubot/files/scripts/math.coffee
@@ -1,22 +0,0 @@
-# Description:
-#   Allows Hubot to do mathematics.
-#
-# Commands:
-#   hubot math me <expression> - Calculate the given expression.
-#   hubot convert me <expression> to <units> - Convert expression to given units.
-module.exports = (robot) ->
-  robot.respond /(calc|calculate|calculator|convert|math|maths)( me)? (.*)/i, (msg) ->
-    msg
-      .http('https://www.google.com/ig/calculator')
-      .query
-        hl: 'en'
-        q: msg.match[3]
-      .headers
-        'Accept-Language': 'en-us,en;q=0.5',
-        'Accept-Charset': 'utf-8',
-        'User-Agent': "Mozilla/5.0 (X11; Linux x86_64; rv:2.0.1) Gecko/20100101 Firefox/4.0.1"
-      .get() (err, res, body) ->
-        # Response includes non-string keys, so we can't use JSON.parse here.
-        json = eval("(#{body})")
-        msg.send json.rhs || 'Could not compute.'
-


Fix plot full name

Fix plot full name

--- projects/static/coffee/project.coffee
+++ projects/static/coffee/project.coffee
@@ -98,13 +98,13 @@
                     colorNames = []

                     datasets = _.map _.pairs(data.violations[name].plots), (plotPair) =>
-                        name = plotPair[0]
+                        plotName = plotPair[0]
                         plot = plotPair[1]

                         preparedPlot = _.flatten [_.map(_.range(30), -> 0), [plot.reverse()]]

                         color = colorer.getColor()
-                        colorNames.push([name, color])
+                        colorNames.push([plotName, color])

                         _.extend
                             data: _.last preparedPlot, 30


re-enable spec

re-enable spec

--- spec/skr/models/CustomerSpec.coffee
+++ spec/skr/models/CustomerSpec.coffee
@@ -3,7 +3,7 @@
     beforeEach ->
         Lanes.Test.ModelSaver.setUser('admin')

-    xit "sends failure messages when code isn't set", (done) ->
+    it "sends failure messages when code isn't set", (done) ->
         model = new Skr.Models.Customer()
         Lanes.Test.ModelSaver.perform(model, done).then (save) ->
             expect(model.errors?.code).toContain("blank")
@@ -17,4 +17,4 @@
         )

         Lanes.Test.ModelSaver.perform(model, done).then (save) ->
-            expect(model.errors).toBeNull()
+            expect(model.errors).toBeUndefined()


Export ::isTextEditor function

Export ::isTextEditor function

--- exports/atom.coffee
+++ exports/atom.coffee
@@ -23,10 +23,15 @@
 unless process.env.ATOM_SHELL_INTERNAL_RUN_AS_NODE
   module.exports.Task = require '../src/task'

+  InternalTextEditor = require('../src/text-editor')
+
+  module.exports.isTextEditor = (object) ->
+    object instanceof InternalTextEditor
+
   TextEditor = (params) ->
     atom.workspace.buildTextEditor(params)

-  TextEditor.prototype = require('../src/text-editor').prototype
+  TextEditor.prototype = InternalTextEditor.prototype

   Object.defineProperty module.exports, 'TextEditor',
     enumerable: true


:memo: :art:

:memo: :art:

--- exports/atom.coffee
+++ exports/atom.coffee
@@ -35,7 +35,6 @@
         The `TextEditor` constructor is no longer public.

         To construct a text editor, use `atom.workspace.buildTextEditor()`.
-        To check if an object is a text editor, look for for the existence of
-        a public method that you're using (e.g. `::getText`).
+        To check if an object is a text editor, use `atom.workspace.isTextEditor(object)`.
       """
       TextEditor


Export {Workspace} in the 'atom' module

Export {Workspace} in the 'atom' module

--- exports/atom.coffee
+++ exports/atom.coffee
@@ -21,3 +21,4 @@
   module.exports.Task = require '../src/task'
   module.exports.View = View
   module.exports.WorkspaceView = require '../src/workspace-view'
+  module.exports.Workspace = require '../src/workspace'


colors corrected

colors corrected

--- src/RobustaTest/TotalSummary.coffee
+++ src/RobustaTest/TotalSummary.coffee
@@ -2,9 +2,9 @@

 exports.text =
 text = (useFormatting, summary) ->
-  green   = if useFormatting then "\\033[32m" else ""
-  red     = if useFormatting then "\\033[31m" else ""
-  normal  = if useFormatting then "\\033[0m" else ""
+  green   = if useFormatting then '\x1B[32m' else ""
+  red     = if useFormatting then "\x1B[31m" else ""
+  normal  = if useFormatting then "\x1B[0m" else ""

   testSummaryText = (summary) ->
     Strings.interlayedUnion "\n", [


Adding batches

Adding batches

--- spec/browser_spec.coffee
+++ spec/browser_spec.coffee
@@ -2,7 +2,7 @@
 JSDOM = require("jsdom")

-Vows.describe("Browser").addBatch(
+Vows.describe("Browser").addBatch

   "browsing":
     topic: ->
@@ -212,6 +212,8 @@
           Browser.site = null

+.addBatch
+
   "content selection":
     topic: ->
       brains.get "/browser/walking", (req, res)->
@@ -309,6 +311,8 @@
         assert.equal $('body').find('#main a').text(), 'Kill'

+.addBatch
+
   "click link":
     topic: ->
       brains.get "/browser/head", (req, res)->
@@ -383,6 +387,8 @@
       "should be accessible from navigator": (browser)->
         assert.equal browser.window.navigator.userAgent, "imposter"

+
+.addBatch

   "authentication":
     "basic":
@@ -514,6 +520,8 @@
       assert.equal "http://localhost:3003/browser/living", forked.location.href

+.addBatch
+
   "iframes":
     topic: ->
       brains.get "/iframe", (req, res)->
@@ -551,4 +559,4 @@
       assert.equal "http://localhost:3003/iframe", browser.window.location

-).export(module)
+.export(module)


Remove describe line in spec.

Remove describe line in spec.

--- spec/grammar-spec.coffee
+++ spec/grammar-spec.coffee
@@ -49,5 +49,4 @@

   # misc Tests
   grammarTest path.join(__dirname, 'fixtures/grammar/misc.js')
-  describe 'ES6 modules', ->
-    grammarTest path.join(__dirname, 'fixtures/grammar/es6module.js')
+  grammarTest path.join(__dirname, 'fixtures/grammar/es6module.js')


Improved test flow

Improved test flow

--- spec/grammar-spec.coffee
+++ spec/grammar-spec.coffee
@@ -42,31 +42,26 @@
       expect(tokens[6]).toEqual value: "gxr", scopes: ["source.perl", "string.regexp.replace.perl", "punctuation.definition.string.perl", "keyword.control.regexp-option.perl"]

   describe "tokenizes constant variables", ->
-    it "test __FILE__", ->
+    it "highlight constants", ->
       {tokens} = grammar.tokenizeLine("__FILE__")
       expect(tokens[0]).toEqual value: "__FILE__", scopes: ["source.perl", "constant.language.perl"]

-    it "test __LINE__", ->
       {tokens} = grammar.tokenizeLine("__LINE__")
       expect(tokens[0]).toEqual value: "__LINE__", scopes: ["source.perl", "constant.language.perl"]

-    it "test __PACKAGE__", ->
       {tokens} = grammar.tokenizeLine("__PACKAGE__")
       expect(tokens[0]).toEqual value: "__PACKAGE__", scopes: ["source.perl", "constant.language.perl"]

-    it "test __SUB__", ->
       {tokens} = grammar.tokenizeLine("__SUB__")
       expect(tokens[0]).toEqual value: "__SUB__", scopes: ["source.perl", "constant.language.perl"]

-    it "test __END__", ->
       {tokens} = grammar.tokenizeLine("__END__")
       expect(tokens[0]).toEqual value: "__END__", scopes: ["source.perl", "constant.language.perl"]

-    it "test __DATA__", ->
       {tokens} = grammar.tokenizeLine("__DATA__")
       expect(tokens[0]).toEqual value: "__DATA__", scopes: ["source.perl", "constant.language.perl"]

-    it "test non constant", ->
+    it "does not highlight custom constants like a default constant", ->
       {tokens} = grammar.tokenizeLine("__TEST__")
       expect(tokens[0]).toEqual value: "__TEST__", scopes: ["source.perl", "string.unquoted.program-block.perl", "punctuation.definition.string.begin.perl"]

@@ -96,54 +91,48 @@
       expect(tokens[0]).toEqual value: "DESTROY", scopes: ["source.perl", "meta.function.perl", "entity.name.function.perl"]

   describe "tokenizes method calls", ->
-    it "test q (quoting) without brackets", ->
+    it "ignores highlight if called like a method", ->
       {tokens} = grammar.tokenizeLine("$test->q;")
       expect(tokens[2]).toEqual value: "->", scopes: ["source.perl", "keyword.operator.comparison.perl"]
       expect(tokens[3]).toEqual value: "q;", scopes: ["source.perl"]

-    it "test q (quoting) with brackets", ->
       {tokens} = grammar.tokenizeLine("$test->q();")
       expect(tokens[2]).toEqual value: "->", scopes: ["source.perl", "keyword.operator.comparison.perl"]
       expect(tokens[3]).toEqual value: "q();", scopes: ["source.perl"]

-    it "test qq (double quoting) with brackets", ->
       {tokens} = grammar.tokenizeLine("$test->qq();")
       expect(tokens[2]).toEqual value: "->", scopes: ["source.perl", "keyword.operator.comparison.perl"]
       expect(tokens[3]).toEqual value: "qq();", scopes: ["source.perl"]

-    it "test qw (word quoting) with brackets", ->
       {tokens} = grammar.tokenizeLine("$test->qw();")
       expect(tokens[2]).toEqual value: "->", scopes: ["source.perl", "keyword.operator.comparison.perl"]
       expect(tokens[3]).toEqual value: "qw();", scopes: ["source.perl"]

-    it "test qx (executing) with brackets", ->
       {tokens} = grammar.tokenizeLine("$test->qx();")
       expect(tokens[2]).toEqual value: "->", scopes: ["source.perl", "keyword.operator.comparison.perl"]
       expect(tokens[3]).toEqual value: "qx();", scopes: ["source.perl"]

   describe "tokenizes single quoting", ->
-    it "'text'", ->
+    it "does not escape characters in single-quote strings", ->
       {tokens} = grammar.tokenizeLine("'Test this\\nsimple one';")
       expect(tokens[0]).toEqual value: "'", scopes: ["source.perl", "string.quoted.single.perl", "punctuation.definition.string.begin.perl"]
       expect(tokens[1]).toEqual value: "Test this\\nsimple one", scopes: ["source.perl", "string.quoted.single.perl"]
       expect(tokens[2]).toEqual value: "'", scopes: ["source.perl", "string.quoted.single.perl", "punctuation.definition.string.end.perl"]
       expect(tokens[3]).toEqual value: ";", scopes: ["source.perl"]

-    it "q(text)", ->
       {tokens} = grammar.tokenizeLine("q(Test this\\nsimple one);")
       expect(tokens[0]).toEqual value: "q(", scopes: ["source.perl", "string.quoted.other.q-paren.perl", "punctuation.definition.string.begin.perl"]
       expect(tokens[1]).toEqual value: "Test this\\nsimple one", scopes: ["source.perl", "string.quoted.other.q-paren.perl"]
       expect(tokens[2]).toEqual value: ")", scopes: ["source.perl", "string.quoted.other.q-paren.perl", "punctuation.definition.string.end.perl"]
       expect(tokens[3]).toEqual value: ";", scopes: ["source.perl"]

-    it "q~text~", ->
       {tokens} = grammar.tokenizeLine("q~Test this\\nadvanced one~;")
       expect(tokens[0]).toEqual value: "q~", scopes: ["source.perl", "string.quoted.other.q.perl", "punctuation.definition.string.begin.perl"]
       expect(tokens[1]).toEqual value: "Test this\\nadvanced one", scopes: ["source.perl", "string.quoted.other.q.perl"]
       expect(tokens[2]).toEqual value: "~", scopes: ["source.perl", "string.quoted.other.q.perl", "punctuation.definition.string.end.perl"]
       expect(tokens[3]).toEqual value: ";", scopes: ["source.perl"]

-    it "q(multiline text)", ->
+    it "does not escape characters in single-quote multiline strings", ->
       lines = grammar.tokenizeLines("""q(
       This is my first line\\n
       and this the second one\\x00
@@ -156,7 +145,6 @@
       expect(lines[4][0]).toEqual value: ")", scopes: ["source.perl", "string.quoted.other.q-paren.perl", "punctuation.definition.string.end.perl"]
       expect(lines[4][1]).toEqual value: ";", scopes: ["source.perl"]

-    it "q~multiline text~", ->
       lines = grammar.tokenizeLines("""q~
       This is my first line\\n
       and this the second one)\\x00
@@ -198,7 +186,7 @@
       expect(tokens[5]).toEqual value: ";", scopes: ["source.perl"]

   describe "tokenizes word quoting", ->
-    it "qw(word)", ->
+    it "quotes words", ->
       {tokens} = grammar.tokenizeLine("qw(Aword Bword Cword);")
       expect(tokens[0]).toEqual value: "qw(", scopes: ["source.perl", "string.quoted.other.q-paren.perl", "punctuation.definition.string.begin.perl"]
       expect(tokens[1]).toEqual value: "Aword Bword Cword", scopes: ["source.perl", "string.quoted.other.q-paren.perl"]
@@ -232,7 +220,7 @@
       expect(lines[2][0]).toEqual value: "}};", scopes: ["source.perl"]

   describe "tokenizes format", ->
-    it "format with @", ->
+    it "works as expected", ->
       lines = grammar.tokenizeLines("""format STDOUT_TOP =
                      Passwd File
 Name                Login    Office   Uid   Gid Home
@@ -253,7 +241,6 @@
       expect(lines[6][0]).toEqual value: "@<<<<<<<<<<<<<<<<<< @||||||| @<<<<<<@>>>> @>>>> @<<<<<<<<<<<<<<<<<", scopes: ["source.perl", "meta.format.perl"]
       expect(lines[8][0]).toEqual value: ".", scopes: ["source.perl", "meta.format.perl"]

-    it "format mixed", ->
       lines = grammar.tokenizeLines("""format STDOUT_TOP =
                          Bug Reports
 @<<<<<<<<<<<<<<<<<<<<<<<     @|||         @>>>>>>>>>>>>>>>>>>>>>>>


:art: Harmonize ascii comments

:art: Harmonize ascii comments


Additional Player properties

Additional Player properties

--- src/Battle/Player.coffee
+++ src/Battle/Player.coffee
@@ -2,6 +2,10 @@
   init: ->
     sidepane = d.querySelector ".clb"
     statRoots = sidepane.querySelectorAll ".cwbdv"
+
+    @recover =
+      form: sidepane.querySelector "#recoverForm"
+      field: sidepane.querySelector "#recover"

     @healthRoot = statRoots[0]
     @manaRoot = statRoots[1]
@@ -17,7 +21,13 @@
     for buff in [d.querySelectorAll(".bte img")...]
       @buffs.push Parse.buff buff

+    @isSpiritActive = d.getElementById("ckey_spirit").src == "http://ehgt.org/v/battle/spirit_a.png"
+
   statPercent: (root) ->
     current = root.querySelector(".cwb2").width
     max = root.querySelector(".cwb3").width
     (current / max) * 100
+
+  recoverAll: ->
+    @recover.field.value = "all"
+    @recover.form.submit()


Proxy sub-properties of borderRadius, borderWidth and gradient.

--- framer/Layer.coffee
+++ framer/Layer.coffee
@@ -337,9 +337,9 @@
 	@define "color", layerProperty(@, "color", "color", null, Color.validColorValue, Color.toColor)

 	# Border properties
-	@define "borderRadius", layerProperty(@, "borderRadius", "borderRadius", 0, null, asBorderRadius, null, null, "_elementBorder", true)
+	@define "borderRadius", layerProperty(@, "borderRadius", "borderRadius", 0, null, asBorderRadius, null, null, "_elementBorder", true, true)
 	@define "borderColor", layerProperty(@, "borderColor", "borderColor", null, Color.validColorValue, Color.toColor, null, null, "_elementBorder")
-	@define "borderWidth", layerProperty(@, "borderWidth", "borderWidth", 0, null, asBorderWidth, null, null, "_elementBorder")
+	@define "borderWidth", layerProperty(@, "borderWidth", "borderWidth", 0, null, asBorderWidth, null, null, "_elementBorder", false, true)
 	@define "borderStyle", layerProperty(@, "borderStyle", "borderStyle", "solid", _.isString, null, null, null, "_elementBorder")

 	@define "force2d", layerProperty(@, "force2d", "webkitTransform", false, _.isBoolean)
@@ -970,7 +970,7 @@

 	@define "gradient",
 		get: ->
-			return @image if Gradient.isGradient(@image)
+			return layerProxiedValue(@image, @, "gradient") if Gradient.isGradient(@image)
 			return null
 		set: (value) ->
 			if Gradient.isGradient(value)


explicitly reference 'global.*' properties

--- shared/syncer.coffee
+++ shared/syncer.coffee
@@ -63,7 +63,7 @@
   ret

 exports.getSync = ->
-  if isServer
+  if global.isServer
     serverSync
   else
     clientSync


fix #1505 replace no longer existing marionette properties isRendered and isDestroyed with their new function equivalents

--- app/assets/javascripts/dashboard/views/dataset/dataset_list_item_view.coffee
+++ app/assets/javascripts/dashboard/views/dataset/dataset_list_item_view.coffee
@@ -175,7 +175,7 @@

   importFailed : (response) ->

-    if @isRendered and not @isDestroyed
+    if @isRendered() and not @isDestroyed()
       @ui.importLink.show()
       @ui.progressbarContainer.addClass("hide")
       @ui.row.addClass('import-failed')


Manually unset the expiring objects after deletion

--- SingularityUI/app/models/Request.coffee
+++ SingularityUI/app/models/Request.coffee
@@ -103,19 +103,25 @@
         $.ajax(
           url: "#{ @url() }/scale?user=#{ app.getUsername() }"
           type: "DELETE"
-        ).then callback
+        ).then () =>
+          @unset('expiringScale')
+          callback()

     makePausePermanent: (callback) =>
         $.ajax(
           url: "#{ @url() }/pause?user=#{ app.getUsername() }"
           type: "DELETE"
-        ).then callback
+        ).then () =>
+          @unset('expiringPause')
+          callback()

     cancelBounce: (callback) =>
         $.ajax(
           url: "#{ @url() }/bounce?user=#{ app.getUsername() }"
           type: "DELETE"
-        ).then callback
+        ).then () =>
+          @unset('expiringBounce')
+          callback()

     bounce: (incremental, duration) =>
         data =


Beter normalization for directive and filter names

--- client/packages.coffee
+++ client/packages.coffee
@@ -45,20 +45,26 @@
 			require = requireProvider.require

 			i8n = require 'inflection'
-
-			# Use camelized names for directives and filters:
+
+			# Use normalize names for directives and filters:
 			# 'core/foo/bar' -> 'coreFooBar'
-			camelize = (path) ->
-				i8n.camelize (path.replace /\//g, '_'), true
-
+			normalize = (path) ->
+				parts = for part, i in path.split '/'
+					i8n.camelize(
+						part.replace /[^\w]/g, '_'
+						0 is i
+					)
+
+				i8n.camelize (i8n.underscore parts.join ''), true
+
 			pkgmanProvider.invoke 'controller', (path, spec) ->
 				$controllerProvider.register path, spec

 			pkgmanProvider.invoke 'directive', (path, spec) ->
-				$compileProvider.directive (camelize path), spec
+				$compileProvider.directive (normalize path), spec

 			pkgmanProvider.invoke 'filter', (path, spec) ->
-				$filterProvider.register (camelize path), spec
+				$filterProvider.register (normalize path), spec

 			pkgmanProvider.invoke 'service', (path, spec, isMock) ->
 				if isMock
@@ -67,7 +73,3 @@
 					$provide.service path, spec

 	])
-
-
-
-


Fix range selector for substitution

Fix range selector for substitution

--- annotran/static/scripts/annotator/plugin/substitution.coffee
+++ annotran/static/scripts/annotator/plugin/substitution.coffee
@@ -53,15 +53,16 @@
     this.state = "dirty"

     for data in annotations.reverse()
+      for target_selector in data.target[0].selector
+        if target_selector.type == "RangeSelector"
+          packager = {
+            start: target_selector.startContainer
+            startOffset: target_selector.startOffset
+            end: target_selector.endContainer
+            endOffset: target_selector.endOffset
+          }

-      packager = {
-        start: data.target[0].selector[1].startContainer
-        startOffset: data.target[0].selector[1].startOffset
-        end: data.target[0].selector[1].endContainer
-        endOffset: data.target[0].selector[1].endOffset
-      }
-
-      this.singleSubstitution(packager, data.text)
+          this.singleSubstitution(packager, data.text)

   createSubstitutionElement: (originalText, substituteText, ele) ->
     newEle = $('')


user objects in org

user objects in org

--- js/inner/org.coffee
+++ js/inner/org.coffee
@@ -14,16 +14,21 @@

     super json

-    @projects(new CI.inner.Project(project) for project in @projects())
-
     # projects that have been turned into Project objects
     @project_objs = @komp =>
       for project in @projects()
+        project.follower_logins = (u.login for u in project.followers)
         project.followers = (new CI.inner.User(u) for u in project.followers)
-        project
+        new CI.inner.Project(project)
+
+    # users that have been turned into User objects
+    @user_objs = @komp =>
+      for user in @users()
+        user.projects = _.filter @project_objs(), (p) -> user.login in p.follower_logins
+        new CI.inner.User(user)

     @projects_with_followers = @komp =>
       _.filter @project_objs(), ((p) -> p.followers.length)

     @projects_without_followers = @komp =>
-      _.reject @project_objs(), ((p) -> p.followers.length)+      _.reject @project_objs(), ((p) -> p.followers.length)


really disable voting

really disable voting

--- nodeko.coffee
+++ nodeko.coffee
@@ -280,6 +280,7 @@

 # create vote
 post '/teams/:teamId/votes', ->
+  return @next()
   Team.fromParam @req.param('teamId'), (error, team) =>
     # TODO: handle error
     @vote = new Vote @req.body, @req
@@ -290,6 +291,7 @@
     saveVote.call(this)

 put '/teams/:teamId/votes/:voteId', ->
+  return @next()
   Team.fromParam @req.param('teamId'), (error, team) =>
     Vote.fromParam @req.param('voteId'), (error, vote) =>
       @ensurePermitted vote, =>


use local references to uploadcare.files namespace

--- app/assets/javascripts/uploadcare/files/group.coffee
+++ app/assets/javascripts/uploadcare/files/group.coffee
@@ -3,7 +3,8 @@
   jQuery: $,
   utils,
   locale: {t},
-  settings: s
+  settings: s,
+  files: uc_files,
 } = uploadcare

 namespace 'files', (ns) ->
@@ -150,7 +151,7 @@
       else if utils.isFileGroup(item)
         for file in item.files()
           files.push(file)
-    return new uploadcare.files.FileGroup(files, settings).api()
+    return new uc_files.FileGroup(files, settings).api()

   ns.loadFileGroup = (groupIdOrUrl, settings) ->
     settings = s.build(settings)
@@ -167,7 +168,7 @@
                     id[0], settings.publicKey, reason)
         df.reject()
       .done (data) ->
-        group = new uploadcare.files.SavedFileGroup(data, settings)
+        group = new uc_files.SavedFileGroup(data, settings)
         df.resolve(group.api())
     else
       df.reject()


Removed unnecessary symbols

Removed unnecessary symbols

--- app/common/elements/sidenav/SidenavController.coffee
+++ app/common/elements/sidenav/SidenavController.coffee
@@ -17,9 +17,9 @@
 			params =
 				id: user.id
 				view: "posts"
-			$state.go("profile", params)
+			$state.go "profile", params
 		else
-			$state.go("login")
+			$state.go "login"
 	self

 SidenavCtrl.$inject = ["$mdMedia", "$state", "LoginService"]


Syntax error fixed

Syntax error fixed

--- addon/locales/zh-tw/translations.coffee
+++ addon/locales/zh-tw/translations.coffee
@@ -60,7 +60,7 @@
     "rate_button_label":"好的"
     "yes_button_label":"是!"
     "no_button_label":"不是"
-    "app_rate_prompt_title":"謝謝，我們非常感激您的善心和慷慨。要給好人好巿評分嗎？
+    "app_rate_prompt_title":"謝謝，我們非常感激您的善心和慷慨。要給好人好巿評分嗎？"
     "feedback_prompt_title":"請分享閣下的意見。＂

   "menu":


Forgot to commit for last push -_-

Forgot to commit for last push -_-

--- admin/static/coffee/dataexplorer.coffee
+++ admin/static/coffee/dataexplorer.coffee
@@ -2198,11 +2198,10 @@
             @.$(event.target).toggleClass('jt_arrow_hidden')
             @set_scrollbar()

-        #TODO Fix it for Firefox
         expand_raw_textarea: =>
-            if $('.'+classname).length > 0
-                height = $('.'+classname)[0].scrollHeight
-                $('.'+classname).height(height)
+            if $('.raw_view_textarea').length > 0
+                height = $('.raw_view_textarea')[0].scrollHeight
+                $('.raw_view_textarea').height(height)

         destroy: =>
             $(document).unbind 'mousemove', @handle_mousemove


Implement brace pairing

Implement brace pairing

--- admin/static/coffee/dataexplorer.coffee
+++ admin/static/coffee/dataexplorer.coffee
@@ -366,6 +366,218 @@

         handle_click: (event) =>
             @handle_keypress null, event
+
+        # Pair ', ", {, [, (
+        # Return true if we want code mirror to ignore the key event
+        pair_char: (event, stack) =>
+            if event?.which?
+                # If there is a selection and the user hit a quote, we wrap the seleciton in quotes
+                if @codemirror.getSelection() isnt ''
+                    char_to_insert = String.fromCharCode event.which
+                    if char_to_insert? and char_to_insert is '"' or char_to_insert is "'"
+                        @codemirror.replaceSelection(char_to_insert+@codemirror.getSelection()+char_to_insert)
+                        event.preventDefault()
+                        return true
+                    return false
+
+                if event.which is 8 # Backspace
+                    if event.type isnt 'keydown'
+                        return false
+                    previous_char = @get_previous_char()
+                    if previous_char is null
+                        return false
+                    # If the user remove the opening bracket and the next char is the closing bracket, we delete both
+                    if previous_char of @matching_opening_bracket
+                        next_char = @get_next_char()
+                        if next_char is @matching_opening_bracket[previous_char]
+                            @remove_next()
+                            return true
+                    # If the user remove the first quote of an empty string, we remove both quotes
+                    else if previous_char is '"' or previous_char is "'"
+                        next_char = @get_next_char()
+                        if next_char is previous_char and @get_previous_char(2) isnt '\\'
+                            @remove_next()
+                            return true
+                    return false
+
+                char_to_insert = String.fromCharCode event.which
+                if char_to_insert?
+                    if event.type isnt 'keypress' # We catch keypress because single and double quotes have not the same keyCode on keydown/keypres #thisIsMadness
+                        return false
+
+                    if char_to_insert is '"' or char_to_insert is "'"
+                        num_quote = @count_char char_to_insert
+                        next_char = @get_next_char()
+                        if next_char is char_to_insert # Next char is a single quote
+                            if num_quote%2 is 0
+                                if @last_element_type_if_incomplete(stack) is 'string' # We are at the end of a string and the user just wrote a quote
+                                    @move_cursor 1
+                                    event.preventDefault()
+                                    return true
+                                else
+                                    # We are at the begining of a string, so let's just add one quote
+                                    return false
+                            else
+                                # Let's add the closing/opening quote missing
+                                return true
+                        else
+                            if num_quote%2 is 0 # Next char is not a single quote and the user has an even number of quotes.
+                                # Let's keep a number of quote even, so we add one extra quote
+                                if @last_element_type_if_incomplete(stack) isnt 'string'
+                                    @insert_next char_to_insert
+                                else # We add a quote inside a string, probably something like that 'He doesn|\'t'
+                                    return false
+                            else # Else we'll just insert one quote
+                                return false
+                    else if @last_element_type_if_incomplete(stack) isnt 'string'
+                        next_char = @get_next_char()
+
+                        if char_to_insert of @matching_opening_bracket
+                            num_not_closed_bracket = @count_not_closed_brackets char_to_insert
+                            if num_not_closed_bracket >= 0 # We insert a closing bracket only if it help having a balanced number of opened/closed brackets
+                                @insert_next @matching_opening_bracket[char_to_insert]
+                                return false
+                            return true
+                        else if char_to_insert of @matching_closing_bracket
+                            opening_char = @matching_closing_bracket[char_to_insert]
+                            num_not_closed_bracket = @count_not_closed_brackets opening_char
+                            if next_char is char_to_insert
+                                if num_not_closed_bracket <= 0 # g(f(...|) In this case we add a closing parenthesis. Same behavior as in Ace
+                                    @move_cursor 1
+                                    event.preventDefault()
+                                return true
+            return false
+
+        get_next_char: =>
+            cursor_end = @codemirror.getCursor()
+            cursor_end.ch++
+            return @codemirror.getRange @codemirror.getCursor(), cursor_end
+
+        get_previous_char: (less_value) =>
+            cursor_start = @codemirror.getCursor()
+            cursor_end = @codemirror.getCursor()
+            if less_value?
+                cursor_start.ch -= less_value
+                cursor_end.ch -= (less_value-1)
+            else
+                cursor_start.ch--
+            if cursor_start.ch < 0
+                return null
+            return @codemirror.getRange cursor_start, cursor_end
+
+
+        # Insert str after the cursor in codemirror
+        insert_next: (str) =>
+            @codemirror.replaceRange str, @codemirror.getCursor()
+            @move_cursor -1
+
+        remove_next: =>
+            end_cursor = @codemirror.getCursor()
+            end_cursor.ch++
+            @codemirror.replaceRange '', @codemirror.getCursor(), end_cursor
+
+        # Move cursor of move_value
+        # A negative value move the cursor to the left
+        move_cursor: (move_value) =>
+            cursor = @codemirror.getCursor()
+            cursor.ch += move_value
+            if cursor.ch < 0
+                cursor.ch = 0
+            @codemirror.setCursor cursor
+
+
+        # Count how many time char_to_count appeared ignoring strings and comments
+        count_char: (char_to_count) =>
+            query = @codemirror.getValue()
+
+            is_parsing_string = false
+            to_skip = 0
+            result = 0
+
+            for char, i in query
+                if to_skip > 0 # Because we cannot mess with the iterator in coffee-script
+                    to_skip--
+                    continue
+
+                if is_parsing_string is true
+                    if char is string_delimiter and query[i-1]? and query[i-1] isnt '\\' # We were in a string. If we see string_delimiter and that the previous character isn't a backslash, we just reached the end of the string.
+                        is_parsing_string = false # Else we just keep parsing the string
+                        if char is char_to_count
+                            result++
+                else # if element.is_parsing_string is false
+                    if char is char_to_count
+                        result++
+
+                    if char is '\'' or char is '"' # So we get a string here
+                        is_parsing_string = true
+                        string_delimiter = char
+                        continue
+
+                    result_inline_comment = @regex.inline_comment.exec query.slice i
+                    if result_inline_comment?
+                        to_skip = result_inline_comment[0].length-1
+                        start += result_inline_comment[0].length
+                        continue
+                    result_multiple_line_comment = @regex.multiple_line_comment.exec query.slice i
+                    if result_multiple_line_comment?
+                        to_skip = result_multiple_line_comment[0].length-1
+                        start += result_multiple_line_comment[0].length
+                        continue
+
+            return result
+
+        matching_opening_bracket:
+            '(': ')'
+            '{': '}'
+            '[': ']'
+        matching_closing_bracket:
+            ')': '('
+            '}': '{'
+            ']': '['
+
+
+        # opening_char has to be in @matching_bracket
+        # Count how many time opening_char has been opened but not closed
+        # A result < 0 means that the closing char has been found more often than the opening one
+        count_not_closed_brackets: (opening_char) =>
+            query = @codemirror.getValue()
+
+            is_parsing_string = false
+            to_skip = 0
+            result = 0
+
+            for char, i in query
+                if to_skip > 0 # Because we cannot mess with the iterator in coffee-script
+                    to_skip--
+                    continue
+
+                if is_parsing_string is true
+                    if char is string_delimiter and query[i-1]? and query[i-1] isnt '\\' # We were in a string. If we see string_delimiter and that the previous character isn't a backslash, we just reached the end of the string.
+                        is_parsing_string = false # Else we just keep parsing the string
+                else # if element.is_parsing_string is false
+                    if char is opening_char
+                        result++
+                    else if char is @matching_opening_bracket[opening_char]
+                        result--
+
+                    if char is '\'' or char is '"' # So we get a string here
+                        is_parsing_string = true
+                        string_delimiter = char
+                        continue
+
+                    result_inline_comment = @regex.inline_comment.exec query.slice i
+                    if result_inline_comment?
+                        to_skip = result_inline_comment[0].length-1
+                        start += result_inline_comment[0].length
+                        continue
+                    result_multiple_line_comment = @regex.multiple_line_comment.exec query.slice i
+                    if result_multiple_line_comment?
+                        to_skip = result_multiple_line_comment[0].length-1
+                        start += result_multiple_line_comment[0].length
+                        continue
+
+            return result
+

         # Handle events on codemirror
         # Return true if we want code mirror to ignore the event
@@ -481,6 +693,37 @@
                     event.preventDefault()
                     return true

+            # Codemirror return a position given by line/char.
+            # We need to retrieve the lines first
+            query_lines = @codemirror.getValue().split '\n'
+            # Then let's get query before the cursor
+            query_before_cursor = ''
+            if @codemirror.getCursor().line > 0
+                for i in [0..@codemirror.getCursor().line-1]
+                    query_before_cursor += query_lines[i] + '\n'
+            query_before_cursor += query_lines[@codemirror.getCursor().line].slice 0, @codemirror.getCursor().ch
+
+            # Get query after the cursor
+            query_after_cursor = query_lines[@codemirror.getCursor().line].slice @codemirror.getCursor().ch
+            if query_lines.length > @codemirror.getCursor().line+1
+                query_after_cursor += '\n'
+                for i in [@codemirror.getCursor().line+1..query_lines.length-1]
+                    if i isnt query_lines.length-1
+                        query_after_cursor += query_lines[i] + '\n'
+                    else
+                        query_after_cursor += query_lines[i]
+            @query_last_part = query_after_cursor
+
+            # Initialize @current_element, which tracks what the user typed before they hit TAB (to auto-complete).
+            # Tracking this helps us let the user loop over all the suggestions available for the fragment they typed (and go back to the fragment).
+            @current_element = ''
+
+            stack = @extract_data_from_query
+                query: query_before_cursor
+                position: 0
+
+            if @pair_char(event, stack) is true
+                return true
             # If a selection is active, we just catch shift+enter
             if @codemirror.getSelection() isnt ''
                 @hide_suggestion_and_description()
@@ -532,35 +775,6 @@

             @current_highlighted_suggestion = -1
             @.$('.suggestion_name_list').empty()
-
-            # Codemirror return a position given by line/char.
-            # We need to retrieve the lines first
-            query_lines = @codemirror.getValue().split '\n'
-            # Then let's get query before the cursor
-            query_before_cursor = ''
-            if @codemirror.getCursor().line > 0
-                for i in [0..@codemirror.getCursor().line-1]
-                    query_before_cursor += query_lines[i] + '\n'
-            query_before_cursor += query_lines[@codemirror.getCursor().line].slice 0, @codemirror.getCursor().ch
-
-            # Get query after the cursor
-            query_after_cursor = query_lines[@codemirror.getCursor().line].slice @codemirror.getCursor().ch
-            if query_lines.length > @codemirror.getCursor().line+1
-                query_after_cursor += '\n'
-                for i in [@codemirror.getCursor().line+1..query_lines.length-1]
-                    if i isnt query_lines.length-1
-                        query_after_cursor += query_lines[i] + '\n'
-                    else
-                        query_after_cursor += query_lines[i]
-            @query_last_part = query_after_cursor
-
-            # Initialize @current_element, which tracks what the user typed before they hit TAB (to auto-complete).
-            # Tracking this helps us let the user loop over all the suggestions available for the fragment they typed (and go back to the fragment).
-            @current_element = ''
-
-            stack = @extract_data_from_query
-                query: query_before_cursor
-                position: 0

             result =
                 status: null
@@ -632,9 +846,9 @@
             last_char_is_white: /.*(\s+)$/
         stop_char: # Just for performance (we look for a stop_char in constant time - which is better than having 3 and conditions) and cleaner code
             opening:
-                '(': true
-                '{': true
-                '[': true
+                '(': ')'
+                '{': '}'
+                '[': ']'
             closing:
                 ')': '(' # Match the opening character
                 '}': '{'
@@ -1319,7 +1533,10 @@
         # Write the suggestion in the code mirror
         write_suggestion: (args) =>
             suggestion_to_write = args.suggestion_to_write
-            @codemirror.setValue @query_first_part+suggestion_to_write+@query_last_part
+            if suggestion_to_write[suggestion_to_write.length-1] is '(' and @count_not_closed_brackets('(') >= 0
+                @codemirror.setValue @query_first_part+suggestion_to_write+')'+@query_last_part
+            else
+                @codemirror.setValue @query_first_part+suggestion_to_write+@query_last_part

             @codemirror.focus() # Useful if the user used the mouse to select a suggestion
             @codemirror.setCursor


removing connect string announcement

removing connect string announcement

--- lib/Pontifex.coffee
+++ lib/Pontifex.coffee
@@ -82,7 +82,7 @@
 				).addCallback (ok) ->
 					socket.ctag = ok.consumerTag
 					console.log "subscribed #{socket.ctag} from #{queue}"
-					socket.send "[ \"connected\", \"#{queue}\" ]"
+				#	socket.send "[ \"connected\", \"#{queue}\" ]"
 		else
 			(self.queues[queue].subscribe { ack: false, prefetchCount: 1 },  (message, headers, deliveryInfo) ->
 				listener(message.data.toString())


Force unless the user wants --stack (they conflict)

Fixes #62

--- lib/cli/main.coffee
+++ lib/cli/main.coffee
@@ -24,6 +24,7 @@
     description(" - runs the development server from /generated and watches files for updates").
     action (context) ->
       process.env["LINEMAN_RUN"] = true
+      cli.options.force = true unless cli.options.stack?
       cli.tasks = ["common", "dev"]
       grunt.cli()


simplify command line to launch topology

--- lib/launcher.coffee
+++ lib/launcher.coffee
@@ -28,7 +28,6 @@
 {Actor} = require "./actor/hactor"
 os = require "os"
 _ = require "underscore"
-opts = require("./options.coffee").options

 createActor = (properties) ->
   actorModule = require "#{__dirname}/actor/#{properties.type}"
@@ -36,9 +35,10 @@

 main = ->

+  topologyPath = process.argv[2] or "samples/sample1.json"
   hTopology = `undefined`
   try
-    hTopology = eval("(" + fs.readFileSync(opts["topology.path"], "utf8") + ")")
+    hTopology = eval("(" + fs.readFileSync(topologyPath, "utf8") + ")")
   catch err
     console.log "erreur : ",err
   unless hTopology


Implemented a digit multiplier for LongInt

--- lib/long_int.coffee
+++ lib/long_int.coffee
@@ -15,12 +15,16 @@
 else
   { recur, resolve, List, Stream } = this.pazy

+#testing = true

-BASE = Stream.from(1)
-  .select((n) -> n % 2 == 0)
-  .map((n) -> Math.pow 10, n)
-  .take_while((b) -> 2 * b - 2 != 2 * b - 1)
-  .last()
+if testing?
+  [BASE, HALFBASE] = [10000, 100]
+else
+  [BASE, HALFBASE] = Stream.from(1)
+    .map((n) -> [Math.pow(10, 2 * n), Math.pow(10, n)])
+    .take_while(([b,h]) -> 2 * b - 2 != 2 * b - 1)
+    .last()
+
 ZEROES = BASE.toString()[1..]

@@ -92,6 +96,20 @@
     else
       create(sub(this.digits, other.digits), this.sign)

+  split = (n) -> [n % HALFBASE, Math.floor n / HALFBASE]
+
+  multiply_digits = (a, b) ->
+    if b < BASE / a
+      [a * b, 0]
+    else
+      [a0, a1] = split a
+      [b0, b1] = split b
+      [m0, m1] = split a0 * b1 + b0 * a1
+
+      tmp = a0 * b0 + m0 * HALFBASE
+      [lo, carry] = if tmp < BASE then [tmp, 0] else [tmp - BASE, 1]
+      [lo, a1 * b1 + m1 + carry]
+
   toString: ->
     rev = @digits.reverse().drop_while (d) -> d == 0
     buf = [rev?.first().toString()]


Improved sorting of suggestions

Improved sorting of suggestions

--- lib/provider.coffee
+++ lib/provider.coffee
@@ -1914,6 +1914,7 @@
       suggestions = @operators

     @setReplacementPrefix(prefix, suggestions)
+    suggestions = @pruneSuggestions(prefix, suggestions)
     @orderSuggestions(prefix, suggestions)

     return suggestions
@@ -1923,27 +1924,20 @@
     prefixRegex = /([\s]*([^\s]*))*$/
     prefixRegex.exec(line)?[2] or ''

+  # Prune the list of suggestions to improve speed
+  pruneSuggestions: (prefix, suggestions) ->
+    if prefix.length > 0
+      upperPrefix = prefix.toUpperCase()
+      prunedSuggestions = (suggestion for suggestion in suggestions when suggestion.snippet.toUpperCase().indexOf(upperPrefix) > -1)
+
+    return prunedSuggestions
+
   # Order the suggestions based on the prefix
   orderSuggestions: (prefix, suggestions) ->
-    # There are more efficient sorting methods but this is simple and the task is quick
-    suggestionSwapped = suggestions.length > 1
-    upperPrefix = prefix.toUpperCase()
-    while suggestionSwapped
-      suggestionSwapped = false
-      for index in [0...suggestions.length - 1]
-        current = suggestions[index].snippet.toUpperCase().indexOf(upperPrefix)
-        next = suggestions[index + 1].snippet.toUpperCase().indexOf(upperPrefix)
-        if current >= 0 and next >= 0
-          if current > next
-            suggestionSwapped = true
-            temp = suggestions[index]
-            suggestions[index] = suggestions[index + 1]
-            suggestions[index + 1] = temp
-        else if next >= 0
-          suggestionSwapped = true
-          temp = suggestions[index]
-          suggestions[index] = suggestions[index + 1]
-          suggestions[index + 1] = temp
+    if prefix.length > 0
+      upperPrefix = prefix.toUpperCase()
+      suggestions.sort (a, b) ->
+        return a.snippet.toUpperCase().indexOf(upperPrefix) - b.snippet.toUpperCase().indexOf(upperPrefix)

   # Fixes the suggestedPrefix.
   # There is an issue with the default function of using the prefix passed into getSuggestions,


small syntax fix

small syntax fix

--- lib/renderer.coffee
+++ lib/renderer.coffee
@@ -308,9 +308,7 @@
         gl.bindTexture gl.TEXTURE_2D, texture
         gl.uniform1i index, textureCount
         textureCount++
-      when 'f'
-        gl.uniform1f index, value
-      when 'f 1'
+      when 'f', 'f 1'
         gl.uniform1f index, value
       when 'f 2'
         gl.uniform2fv index, value
@@ -324,9 +322,7 @@
         gl.uniformMatrix3fv index, false, value
       when 'm 4'
         gl.uniformMatrix4fv index, false, value
-      when 'i'
-        gl.uniform1i index, value
-      when 'i 1'
+      when 'i', 'i 1'
         gl.uniform1i index, value
       when 'i 2'
         gl.uniform2iv index, value


It says that there is an error, but there is no error...

--- app/assets/javascripts/movies.js.coffee
+++ app/assets/javascripts/movies.js.coffee
@@ -9,8 +9,8 @@
     url: "https://codechallenge.orasi.com/actors",
     data: {random: "true"}
   }
-).success (data)->
-    $("#init-actor").text($.parseJSON(data).name)
+).complete (xhr) ->
+    $("#init-actor").text($.parseJSON(xhr.responseText).name)

 #Get all movie data
 for actor in actorList


Prevent nesting on Pjax hook

Prevent nesting on Pjax hook

--- app/assets/javascripts/nembrot.document.js.coffee
+++ app/assets/javascripts/nembrot.document.js.coffee
@@ -191,7 +191,7 @@
 $ ->
   document_initializers()

-$(document).on 'pjax:end', '#main', ->
+$(document).on 'pjax:end', '#main :not(#main)', ->
   content_initializers()
   content_initializers_reload_only()


clarify intent

clarify intent

cc: da39a3ee5e6b4b0d3255bfef95601890afd80709@mtodd

--- app/assets/javascripts/task_list.coffee
+++ app/assets/javascripts/task_list.coffee
@@ -115,10 +115,10 @@
 # Useful when you need iterate over all items.
 itemPattern = ///
   ^
-  (?:                     # optional list prefix, consisting of
+  (?:                     # optional prefix, consisting of
     \s*                   # optional leading whitespace
     (?:>\s*)*             # zero or more blockquotes
-    (?:[-+*]|(?:\d+\.))   # item indicator
+    (?:[-+*]|(?:\d+\.))   # list item indicator
   )?
   \s*                     # optional whitespace prefix
   (                       # checkbox


readd rebind

readd rebind

--- app/assets/javascripts/views/restrooms/new.coffee
+++ app/assets/javascripts/views/restrooms/new.coffee
@@ -85,6 +85,7 @@

   _updateForm: (coords, data, textStatus) =>
     $('.form-container').html(data).hide().fadeIn()
+    @_rebind()
     @_requestNearbyRestrooms(coords)
     @_updateMap(coords)


Add a loading indicator.

Add a loading indicator.

--- app/assets/javascripts/tryEvalGD.coffee
+++ app/assets/javascripts/tryEvalGD.coffee
@@ -1,15 +1,16 @@
 $ ->
   $('textarea').keydown (event) =>
     if (event.keyCode == 10 or event.keyCode == 13) and event.ctrlKey
-        $.ajax {
-          "url": "/jsontest",
-          "type": "POST",
-          "data": JSON.stringify({
-            "language": "ruby",
-            "code": $('textarea').val()
-          }),
-          "dataType": "json",
-          "contentType": "application/json; charset=utf-8",
-          "success": (data) =>
-            $('#result').text(JSON.stringify(data, null, 4))
-        }+      $('#result').text("Loading...")
+      $.ajax {
+        "url": "/jsontest",
+        "type": "POST",
+        "data": JSON.stringify({
+          "language": "ruby",
+          "code": $('textarea').val()
+        }),
+        "dataType": "json",
+        "contentType": "application/json; charset=utf-8",
+        "success": (data) =>
+          $('#result').text(JSON.stringify(data, null, 4))
+      }


stop agency id can be different from a bus agency id, use a correct one

--- app/assets/transit/lib/models/real_time.js.coffee
+++ app/assets/transit/lib/models/real_time.js.coffee
@@ -2,7 +2,7 @@

   sync: (method, model, options) =>
     if method == 'read'
-      agency_id = @get('segment').agencyId
+      agency_id = @get('segment').from.stopId.agencyId
       stop_id = @get('segment').from.stopId.id
       $.get "/workshop/stops/#{agency_id}/#{stop_id}/arrivals", (response) =>
         # find the prediction from OBA with the same trip id as in OTP


Close a span tag

Close a span tag

--- app/coffee/modules/issues/detail.coffee
+++ app/coffee/modules/issues/detail.coffee
@@ -411,6 +411,7 @@
             <% } else { %>
             Open
             <% } %>
+
             <span class="us-detail-status" style="color:<%= status.color %>"><%= status.name %>


support expanded trees

support expanded trees

--- lib/ui/views.coffee
+++ lib/ui/views.coffee
@@ -15,8 +15,10 @@
     view.innerHTML = content
     view

-  tree: ({head, children}) ->
-    @ink.tree.treeView(@render(head), children.map((x)=>@render @tags.div [x]))[0]
+  tree: ({head, children, expand}) ->
+    @ink.tree.treeView(@render(head),
+                       children.map((x)=>@render @tags.div [x]),
+                       expand: expand)

   subtree: ({label, child}) ->
     @render if child.type == "tree"


Updates to match new API.

Updates to match new API.

--- lib/wakatime.coffee
+++ lib/wakatime.coffee
@@ -42,14 +42,14 @@
         atom.config.set("wakatime", defaults)

 setupEventHandlers = () ->
-    atom.workspace.eachEditor (editor) =>
+    atom.workspace.observeTextEditors (editor) =>
         try
             buffer = editor.getBuffer()
-            buffer.on 'saved', (e) =>
+            buffer.onDidSave (e) =>
                 file = e.file
                 if file? and file
                     sendHeartbeat(file, true)
-            buffer.on 'changed', (e) =>
+            buffer.onDidChange (e) =>
                 file = buffer.file
                 if file? and file
                     sendHeartbeat(file)


add stubs to ServerAPI

add stubs to ServerAPI

--- app/templates/app/scripts/coffee/ServerAPI.coffee
+++ app/templates/app/scripts/coffee/ServerAPI.coffee
@@ -1,6 +1,8 @@
 define ["utils/ServerClient"],(ServerClient)->
   class ServerAPI extends ServerClient
     initialize:->
+
+    _isServer:-> false #can using stubs

     get_data:->
       @get {


Edit hare text

Edit hare text

Italicized scientific names in the description. Edited Length, Weight, Gestation, and Offspring. Deleted Height row.

--- app/lib/field-guide-content/hare.coffee
+++ app/lib/field-guide-content/hare.coffee
@@ -1,6 +1,6 @@
 module.exports =
   description: '''
-    There are two hare species in Gorongosa: savanna hare (Lepus microtis) and scrub hare (Lepus saxatilis). The savanna hare is usually darker in color than other hares, with a grayish-brown body, reddish-brown flanks and limbs, and white underparts. Scrub hares have thick, soft fur that is brown to gray in color with a black flecking, which gives their coat a grizzled appearance on their upper parts, contrasting with their under parts, which are white. Their head is whitish with a buff color on the sides of the face and around the eyes. Most individuals have a distinct white patch on the forehead just above the eyes.
+    There are two hare species in Gorongosa: savanna hare (Lepus microtis) and scrub hare (Lepus saxatilis). The savanna hare is usually darker in color than other hares, with a grayish-brown body, reddish-brown flanks and limbs, and white underparts. Scrub hares have thick, soft fur that is brown to gray in color with a black flecking, which gives their coat a grizzled appearance on their upper parts, contrasting with their under parts, which are white. Their head is whitish with a buff color on the sides of the face and around the eyes. Most individuals have a distinct white patch on the forehead just above the eyes.
   '''

   scientificName: ''
@@ -10,22 +10,19 @@

   information: [{
     label: 'Length'
-    value: '50-79 cm'
-  }, {
-    label: 'Height'
-    value: ''
+    value: '41-65 cm'
   }, {
     label: 'Weight'
-    value: ''
+    value: '1.5-4.5 kg'
   }, {
     label: 'Lifespan'
-    value: ''
+    value: '12 years'
   }, {
     label: 'Gestation'
-    value: '6 months'
+    value: '1-2 months'
   }, {
     label: 'Avg. number of offspring'
-    value: '1'
+    value: '1-3'
   }]

   sections: [{


Can now select districts with single click. Other districts deselected with selection.

--- app/scripts/controllers/district.coffee
+++ app/scripts/controllers/district.coffee
@@ -32,6 +32,7 @@
         console.log "Error: ", error

     $scope.highlightDistrict = () ->
+      d3.select('.districts').selectAll('path').classed('selected', false)
       if $scope.state_district.state
         $scope.district_element = d3.select(d3.select('.districts').selectAll('path').filter((d, i) -> return this.textContent == "#{$scope.state_district.state}-#{$scope.state_district.district}")[0][0])
         $scope.district_element.attr('class', 'selected')
@@ -49,7 +50,12 @@
         ).on("mousemove", () ->
           return tooltip.style("top", (event.pageY-10)+"px").style("left", (event.pageX+10+"px"))
         ).on("mouseout", () ->
-          return tooltip.style("visibility", "hidden"))
+          return tooltip.style("visibility", "hidden")
+        ).on("click", () ->
+          district_id = d3.select(this).text()
+          $scope.state_district = {state: district_id.slice(0, 2), district: district_id.slice(3, 6)}
+          $scope.highlightDistrict()
+        )
         $scope.usMap.append("path").attr("class", "district-boundaries").attr("clip-path", "url(#clip-land)").datum(topojson.mesh(congress, congress.objects.districts, (a, b) ->
           (a.id / 1000 | 0) is (b.id / 1000 | 0)
         )).attr "d", path
@@ -81,6 +87,7 @@
       $scope.usMap.transition().duration(750).attr("transform", "translate(" + 960 / 2 + "," + 600 / 2 + ")scale(" + scale + ")translate(" + -x + "," + -y + ")").style "stroke-width", 1.5 / scale + "px"

     $scope.zoomOut = (d) ->
+      d3.select('.districts').selectAll('path').classed('selected', false)
       $scope.position = null
       $scope.selected_zip = null
       $scope.warning = null


update product db

update product db

--- assets/coffeescript/product_list.coffee
+++ assets/coffeescript/product_list.coffee
@@ -168,7 +168,7 @@
         discount: edu_discount
       img: [pupil_img_path,'pupil_wnone_e120b.jpg'].join('/')
     pupil_w30_enone:
-      cost: 990
+      cost: 1190
       title_product: 'Pupil Headset'
       sub_products:
         world_camera: world_cam_data.w30
@@ -189,7 +189,7 @@
         eye_camera: eye_cam_data.e120
       img: [pupil_img_path,'pupil_w30_e120.jpg'].join('/')
     pupil_w30_enone_edu:
-      cost: 400
+      cost: 600
       title_product: 'Pupil Headset'
       sub_products:
         world_camera: world_cam_data.w30
@@ -214,7 +214,7 @@
         discount: edu_discount
       img: [pupil_img_path,'pupil_w30_e120.jpg'].join('/')
     pupil_w120_enone:
-      cost: 990
+      cost: 1190
       title_product: 'Pupil Headset'
       sub_products:
         world_camera: world_cam_data.w120
@@ -243,7 +243,7 @@
         eye_camera: eye_cam_data.e120b
       img: [pupil_img_path,'pupil_w120_e120b.jpg'].join('/')
     pupil_w120_enone_edu:
-      cost: 400
+      cost: 600
       title_product: 'Pupil Headset'
       sub_products:
         world_camera: world_cam_data.w120


Login: reload to root

Login: reload to root

--- client/Login/AppView.coffee
+++ client/Login/AppView.coffee
@@ -381,7 +381,7 @@
           @registerForm.reset()
           @registerForm.button.hideLoader()
           @hide()
-          location.replace('/Activity')
+          location.replace('/')

   doFinishRegistration: (formData) ->
     (KD.getSingleton 'mainController').handleFinishRegistration formData, @bound 'afterLoginCallback'


-1 comments count bug in hn ui

-1 comments count bug in hn ui

--- hn.coffee
+++ hn.coffee
@@ -3,7 +3,7 @@
 jquery = fs.readFileSync("./jquery.js", "utf-8")

 MORE_HREF = '\/x?fnid='
-nextUrl = "/newest"
+nextUrl = '/x?fnid=vX3PX8DtnP8o25bmASKTfm' #'/news'
 cnt = 0
 errCnt = 0

@@ -15,6 +15,7 @@
 setInterval check, 5000

 loadPage = (url) ->
+ url = '' if not url?
  time = new Date().getTime()
  jsdom.env
    url: "http://news.ycombinator.com#{url}",
@@ -51,7 +52,10 @@
         arr2 = a.text().split(' ')
         for v, i in arr2
          if v is 'comment' or v is 'comments'
-          d.comments_count = parseInt arr2[i-1]
+          if i is 0
+           d.comments_count = -1
+          else
+           d.comments_count = parseInt arr2[i-1]
        arr = text.split(' ')
        for v,i in arr
         if v is 'point' or v is 'points' and i > 0


allow changing of selection colour

allow changing of selection colour

--- client/prefs-colours.coffee
+++ client/prefs-colours.coffee
@@ -7,7 +7,7 @@
   # t: token type, a short key for storing customisations in localStorage
   # c: css selector
   # s: name to display in the UI
-  # showLB: whether to show the "Left border" control
+  # showX: whether to show the control for "X"
   {t:' ',  c:'.cm-s-default,.CodeMirror-gutter-wrapper', s:'normal'}
   {t:'0',  c:'.cm-apl-num',                 s:'number'          }
   {t:"'",  c:'.cm-apl-str',                 s:'string'          }
@@ -35,10 +35,12 @@
   {t:'⍝',  c:'.cm-apl-comment',             s:'comment'         }
   {t:'!',  c:'.cm-apl-err',                 s:'error'           }
   {t:'L',  c:'.CodeMirror-linenumber',      s:'line number'     }
-  {t:'cu', c:'div.CodeMirror-cursor',       s:'cursor', showLB:1}
+  {t:'cu', c:'div.CodeMirror-cursor',       s:'cursor',           controls:{lb:1}}
   {t:'mb', c:'.CodeMirror-matchingbracket', s:'matching bracket'}
   {t:'sc', c:'.CodeMirror-search-match',    s:'search match'    }
   {t:'mo', c:'.modified',                   s:'modified (session)'}
+  {t:'s1', c:'.CodeMirror-focused .CodeMirror-selected', s:'selected (focused)',    controls:{fg:0,BIU:0}}
+  {t:'s0', c:'.CodeMirror-selected',                     s:'selected (no focus)',   controls:{fg:0,BIU:0}}
 ]
 H = dict G.map (g, i) -> [g.t, i]

@@ -67,6 +69,8 @@
   'mb':bg:'#ffff88'
   'sc':bg:'#ff8800'
   'mo':bg:'#eeeeee'
+  's1':bg:'#d7d4f0'
+  's0':bg:'#d9d9d9'

 renderCSS = (v, rp = '') -> # v: style objects keyed by token type, rp: css rule prefix
   join G.map (g) ->
@@ -94,13 +98,13 @@

       <datalist id=col-list>#{join u.map (c) -> "<option value=#{c}>"}</datalist>
       <select id=col-group>#{join G.map (g, i) -> "<option value=#{i}>#{g.s}"}</select>
-
<input type=checkbox id=col-fg-cb>Foreground <input type=color id=col-fg list=col-list>
-
<input type=checkbox id=col-bg-cb>Background <input type=color id=col-bg list=col-list>
-
<input type=checkbox id=col-B>B
-         <input type=checkbox id=col-I>I
-         <input type=checkbox id=col-U>U
-

-         <input type=checkbox id=col-lb-cb>Left border <input type=color id=col-lb>
+
<input type=checkbox id=col-fg-cb>Foreground <input type=color id=col-fg list=col-list>
+
<input type=checkbox id=col-bg-cb>Background <input type=color id=col-bg list=col-list>
+

+        <input type=checkbox id=col-B>B
+        <input type=checkbox id=col-I>I
+        <input type=checkbox id=col-U>U
+
<input type=checkbox id=col-lb-cb>Left border <input type=color id=col-lb>

   """
   $cm = $ '#col-cm'
@@ -109,25 +113,25 @@
     indentUnit: 4, scrollButtonHeight: 12, matchBrackets: true, autoCloseBrackets: {pairs: '()[]{}', explode: '{}'}
   cm.on 'gutterClick', -> selectGroup H.L; return
   cm.on 'cursorActivity', ->
-    if t = cm.getTokenTypeAt cm.getCursor(), 1
+    if cm.somethingSelected()
+      selectGroup H.s1
+    else if t = cm.getTokenTypeAt cm.getCursor(), 1
       c = '.cm-' + t.split(' ')[0]; i = -1; for g, j in G when g.c == c then i = j; break
       i != -1 && selectGroup i
     else
       selectGroup H[' ']
     return
   $('#col-group').change -> selectGroup +@value; return
-  $('#col-fg').change -> model[sel].fg = @value;     updateSampleStyle(); return
-  $('#col-bg').change -> model[sel].bg = @value;     updateSampleStyle(); return
-  $('#col-lb').change -> model[sel].lb = @value;     updateSampleStyle(); return
-  $('#col-B').click   -> model[sel].B = +!!@checked; updateSampleStyle(); return
-  $('#col-I').click   -> model[sel].I = +!!@checked; updateSampleStyle(); return
-  $('#col-U').click   -> model[sel].U = +!!@checked; updateSampleStyle(); return
-  ['fg', 'bg', 'lb'].forEach (p) ->
+  qw('fg bg lb').forEach (p) ->
+    $("#col-#{p}").change -> model[sel][p] = @value; updateSampleStyle(); return
     $("#col-#{p}-cb").click ->
       $("#col-#{p}").toggle @checked
       model[sel][p] = @checked && $("#col-#{p}").val() || ''
       updateSampleStyle()
       return
+    return
+  qw('B I U').forEach (p) ->
+    $("#col-#{p}").click -> model[sel][p] = +!!@checked; updateSampleStyle(); return
     return
   return

@@ -166,12 +170,12 @@
 selectGroup = (i, forceRefresh) ->
   if i != sel || forceRefresh
     h = model[i]; $('#col-group').val i
-    $('#col-fg-cb').prop 'checked', !!h.fg; $('#col-fg').val(h.fg).toggle !!h.fg
-    $('#col-bg-cb').prop 'checked', !!h.bg; $('#col-bg').val(h.bg).toggle !!h.bg
-    $('#col-lb-cb').prop 'checked', !!h.lb; $('#col-lb').val(h.lb).toggle !!h.lb
-    $('#col-B').prop 'checked', !!h.B
-    $('#col-I').prop 'checked', !!h.I
-    $('#col-U').prop 'checked', !!h.U
-    $('#col-lb-p').toggle !!G[i].showLB
+    qw('fg bg lb').forEach (p) -> $("#col-#{p}-cb").prop 'checked', !!h[p]; $("#col-#{p}").val(h[p]).toggle !!h[p]; return
+    qw('B I U').forEach (p) -> $("#col-#{p}").prop 'checked', !!h[p]; return
+    c = G[i].controls || {}
+    $('#col-fg-p' ).toggle !!(c.fg ? 1)
+    $('#col-bg-p' ).toggle !!(c.bg ? 1)
+    $('#col-BIU-p').toggle !!(c.BIU ? 1)
+    $('#col-lb-p' ).toggle !!c.lb
     sel = i
   return


:bug: Fix Instant timer signature not valid

--- src/particles/timers/instant.coffee
+++ src/particles/timers/instant.coffee
@@ -1,5 +1,5 @@
 # Public:
-module.exports =
+module.exports =
 class Instant

   ### Public ###
@@ -8,4 +8,4 @@

   finished: -> true

-  nextTime: -> 0
+  nextTime: 0


github: set per_page as 10 when pluck is not defined

--- workers/social/lib/social/models/github.coffee
+++ workers/social/lib/social/models/github.coffee
@@ -155,7 +155,7 @@
     # because of max_call_stack_size issue in Bongo
     # Requires extensive debugging on Bongo.Base ~ GG
     # When used with Pluck array we are able to fetch more ~ CtF
-    options.per_page or= 10
+    options.per_page = 10  unless pluck?.length

     # Initialize Github api with client object
     # client object includes required token


NEW: named-layout: parentWidthChildrenHeightMaxParentHeight

--- source/Art/Engine/Core/Element.coffee
+++ source/Art/Engine/Core/Element.coffee
@@ -206,10 +206,12 @@
     childrenSizeMaxParentHeight:              cs:1, max: hh: 1

     parentHeightChildrenWidth:                hh:1, wcw:1
+    childrenWidthParentHeight:                hh:1, wcw:1
+
     parentWidthChildrenHeight:                ww:1, hch:1
-
-    childrenWidthParentHeight:                hh:1, wcw:1
     childrenHeightParentWidth:                ww:1, hch:1
+    parentWidthChildrenHeightMaxParentHeight: ww:1, hch:1, max: hh: 1
+    childrenHeightParentWidthMaxParentHeight: ww:1, hch:1, max: hh: 1

     parentHeightChildrenWidthMaxParentWidth:  wcw:1, hh:1, max: ww:1


Remove console.log.

Remove console.log.

--- src/coffee/import.coffee
+++ src/coffee/import.coffee
@@ -55,7 +55,6 @@

     deferred.promise

-
   changeState: (publish = true, remove = false, filterFunction) ->
     deferred = Q.defer()
     @publishProducts = true
@@ -133,7 +132,6 @@
           index = @slug2index[product.slug[GLOBALS.DEFAULT_LANGUAGE]] if product.slug? and product.slug[GLOBALS.DEFAULT_LANGUAGE]?
     return @existingProducts[index] if index > -1

-
   _matchOnCustomAttribute: (product) ->
     attribute = undefined
     if @customAttributeNameToMatch?
@@ -142,7 +140,6 @@
       _.find variants, (variant) =>
         variant.attributes or= []
         attribute = _.find variant.attributes, (attrib) =>
-          console.log "A", attrib
           attrib.name is @customAttributeNameToMatch
         attribute?