items > selectBar, remove elementFactory and type_properties references, fix #24

--- src/scripts/graph/Items.coffee
+++ src/scripts/graph/Items.coffee
@@ -14,22 +14,6 @@
       tweenTime = self.timeline.tweenTime

       selectBar = (d) ->
-        # Merge attributes with existing ones on click, so if we add
-        # an attribute we don't have to edit the json manually to allow
-        # existing object to use it.
-        factory = window.ElementFactory
-        type_properties = {}
-        if d.object then type_properties = d.object.constructor.properties
-
-        existing_options = _.map(d.properties, (prop) -> prop.name)
-
-        for key, property of type_properties
-          has_prop = if existing_options.indexOf(key) != -1 then true else false
-          # if prorperty doesn't exists in the d.options array create it
-          # and assign the default value. {keys: [], name: "n", val: 1}
-          if has_prop == false
-            d.properties.push({keys: [], name: key, val: property.val})
-
         self.timeline.selectionManager.select(this)

       dragmove = (d) ->


add default scene methods

add default scene methods

--- src/game/Scene.coffee
+++ src/game/Scene.coffee
@@ -1 +1,13 @@
 class Rotten.Scene
+
+    constructor: (@game) ->
+        @objects = []
+
+    setup: () ->
+        object.setup() for object in @objects
+
+    update: () ->
+        object.update() for object in @objects
+
+    draw: () ->
+        object.draw() for object in @objects


set the api version to v3

set the api version to v3

--- src/gh-request.coffee
+++ src/gh-request.coffee
@@ -2,6 +2,7 @@

 module.exports = (params) ->
   params.headers ?= {}
+  params.headers['Accept'] = 'application/vnd.github.v3+json'
   params.headers['User-Agent'] = 'gh-tree'
   request params
   .then ({ response, body }) ->


scatterplot test: more missing data in last example

--- test/scatterplot/test_scatterplot.coffee
+++ test/scatterplot/test_scatterplot.coffee
@@ -185,8 +185,8 @@
 # Example 4: color by grouping
 d3.json "data.json", (data) ->
     mychart = scatterplot({
-        xlab:"X1"
-        ylab:"X2"
+        xlab:"X"
+        ylab:"Y"
         height:h
         width:w
         margin:margin})
@@ -194,6 +194,9 @@
     ngroup = 3
     group = (Math.ceil(Math.random()*ngroup) for i in data)
     these_data = {x:(d[0] for d in data), y:d[1] for d in data, group:group}
+    for i of these_data.y
+        these_data.y[i] = null if Math.random() < 0.1
+        these_data.x[i] = null if Math.random() < 0.1

     mychart(d3.select("div#chart4"), these_data)


Fixed History updates

Fixed History updates

--- muleview/app/controller/History.coffee
+++ muleview/app/controller/History.coffee
@@ -4,11 +4,16 @@
     "Ext.util.History"
   ]

+  addToken: (key, ret) ->
+    return unless key and ret
+    Ext.util.History.add key + ";" + ret
+
   gotoToken: (token) ->
     [key, retention] = (token ? "").split(";")
     Muleview.event "viewChange", key, retention if key

   init: ->
+
   onLaunch: ->
     Ext.onReady =>
       Ext.util.History.init =>
@@ -16,3 +21,7 @@
           change: @gotoToken
           scope: @
       @gotoToken Ext.util.History.getToken()
+    Muleview.app.on
+      scope: @
+      viewChange: (key, ret) ->
+        @addToken(key, ret)


fix typo

fix typo

--- src/smc-hub/api/handler.coffee
+++ src/smc-hub/api/handler.coffee
@@ -113,7 +113,7 @@
             database       : opts.database
             compute_server : opts.compute_server
         client = new Client(options)
-        clien.push_to_client = (mesg, cb) =>
+        client.push_to_client = (mesg, cb) =>
             client.emit('push_to_client', mesg)
             cb?()
         client.ip_address = opts.ip_address


sagews2html: disable selection and no output numbering

--- src/smc-webapp/printing.coffee
+++ src/smc-webapp/printing.coffee
@@ -221,20 +221,8 @@
                             color: #888;
                             min-width: 2rem;
                             text-align: right;
-                        }
-                        /* numbering output, disabled because it doesn't look good */
-                        /*
-                        div.output:before {
-                            margin-left: -3rem;
-                            counter-increment: line;
-                            content: counter(line);
-                            display: inline-block;
-                            color: #888;
-                            min-width: 2rem;
-                            text-align: right;
-                            font-family: monospace;
-                        }
-                        */
+                            user-select: none;
+                        }
                         div.header { margin-bottom: 1rem; }
                         footer {
                             margin-top: 1rem;


Fixes tests, adds AppendEquals

Fixes tests, adds AppendEquals

--- javascripts/lib/math/expression_manipulation.coffee
+++ javascripts/lib/math/expression_manipulation.coffee
@@ -50,9 +50,6 @@
       initialize: (@opts)->
         @val = @opts.value

-      appendImplicitMultiplication: (expression)->
-        expression.append(comps.multiplication.build())
-
       doAppend: (expression)->
         last = expression.last()
         number_with_this_val = comps.number.build(value: @val)
@@ -61,7 +58,8 @@
           new_last = last.concatenate(@val)
           expression.replaceLast(new_last)
         else if (last && last instanceof comps.exponentiation) or (last && !last.isOperator())
-          @appendImplicitMultiplication(expression).append(number_with_this_val)
+          expression.append(comps.multiplication.build()).
+            append(number_with_this_val)
         else
           expression.append(number_with_this_val)

@@ -75,7 +73,7 @@
       initialize: (@opts={})->

       baseExpression: (base)->
-        comps.expression.build(expression: [base])
+        comps.expression.buildUnlessExpression base

       powerExpression: ()->
         power = if @opts.power
@@ -108,21 +106,16 @@
         else
           base = @baseExpression(expression.last())

-
         power = @powerExpression()
-
-

         expression.replaceLast(
           comps.exponentiation.build(base: base, power: power))

     class_mixer(ExponentiateLast)

-    class SquareLast
-
-
     class AppendMultiplication
       appendAction: (expression)->
+
         _OverrideIfOperatorOrAppend.build(expression).with comps.multiplication.build()

       invoke: (expression)->
@@ -131,6 +124,10 @@

     class_mixer(AppendMultiplication)

+    class AppendEquals
+      invoke: (expression)->
+        expression.append comps.equals.build()
+    class_mixer(AppendEquals)

     class AppendDivision
       invoke: (expression)->
@@ -225,12 +222,11 @@

     class CloseSubExpression
-      initialize: ->
-        @handled = false
       invoke: (expression)->
         logger.info("CloseSubExpression#invoke")
-        _FinalOpenSubExpressionApplication.build(expression).
+        ret = _FinalOpenSubExpressionApplication.build(expression).
           invoke((expression)-> expression.close())
+        ret
     class_mixer(CloseSubExpression)

@@ -271,7 +267,13 @@
       with: (operator)->
         last = @expression.last()
         if last && last.isOperator()
-          @expression.replaceLast(operator)
+          if last instanceof comps.exponentiation
+            if last.power().isBlank()
+              @expression.replaceLast(operator)
+            else
+              @expression.append(operator)
+          else
+            @expression.replaceLast(operator)
         else
           @expression.append(operator)
     class_mixer(_OverrideIfOperatorOrAppend)
@@ -294,6 +296,7 @@
       exponentiate_last: ExponentiateLast
       append_multiplication: AppendMultiplication
       append_addition: AppendAddition
+      append_equals: AppendEquals
       append_subtraction: AppendSubtraction
       negate_last: Negation
       open_sub_expression: OpenSubExpression


debug info

debug info

--- packages/rocketchat-channel-settings/client/views/channelSettings.coffee
+++ packages/rocketchat-channel-settings/client/views/channelSettings.coffee
@@ -21,6 +21,7 @@

 	getProjectInfo: ->
 		project_info = ChatRoom.findOne(@rid).details;
+		console.log ChatRoom.findOne(@rid)
 		return project_info
 	getRoom: ->
 		return ChatRoom.findOne(@rid)


Clear vendor search with empty input.

Clear vendor search with empty input.

--- kirppu/static_src/js/checkout/vendorfindmode.coffee
+++ kirppu/static_src/js/checkout/vendorfindmode.coffee
@@ -11,16 +11,22 @@
     @cfg.uiRef.body.append(@vendorList.render())

     if @query?
-      Api.vendor_find(q: @query).done(@onVendorsFound)
+      @onSearchVendor(@query)

   glyph: -> "user"
   title: -> gettext("Vendor Search")
   inputPlaceholder: -> gettext("Search vendor")

   actions: -> [
-    ["", (query) => Api.vendor_find(q: query).done(@onVendorsFound)]
+    ["", @onSearchVendor]
     [@commands.logout, @onLogout]
   ]
+
+  onSearchVendor: (query) =>
+    if query.trim() == ""
+      @vendorList.body.empty()
+    else
+      Api.vendor_find(q: query).done(@onVendorsFound)

   onVendorsFound: (vendors) =>
     @vendorList.body.empty()


Use persisted settings on spacewarp viewer

--- src/ubret/spacewarp_viewer/initialize.coffee
+++ src/ubret/spacewarp_viewer/initialize.coffee
@@ -54,7 +54,10 @@
   events:
     'next' : 'nextPage getNextSubject'
     'prev' : 'prevPage getNextSubject'
-
+    'setting:alpha' : 'updateAlpha'
+    'setting:q' : 'updateQ'
+    'setting:scale' : 'updateScale'
+    'setting:extent' : 'updateExtent'

   constructor: (selector) ->
     _.extend @, Ubret.Sequential
@@ -174,7 +177,8 @@
   start: =>
     console.log 'start'

-  setBand: (band) =>
+  setBand: =>
+    band = @opts.band
     if band is 'gri'
       @wfits.drawColor('i', 'r', 'g')
     else
@@ -190,28 +194,31 @@
       @wfits.setImage(band)
       @wfits.setStretch(@stretch)

-  updateAlpha: (value) =>
-    @wfits.setAlpha(value)
-
-  updateQ: (value) =>
-    @wfits.setQ(value)
-
-  updateScale: (band, value) =>
+  updateAlpha: =>
+    @wfits.setAlpha(@opts.alpha)
+
+  updateQ: =>
+    @wfits.setQ(@opts.q)
+
+  updateScale: =>
+    band = @opts.scale.band
+    value = @opts.scale.value
+
     scales = @collection.getColorScales()
     index = if band is 'i' then 0 else if band is 'g' then 1 else 2
     scales[index] = value
     @wfits.setScales.apply(@wfits, scales)

-  updateStretch: (value) =>
-    @stretch = value
-    @wfits.setStretch(value)
+  updateStretch: =>
+    @stretch = @opts.stretch
+    @wfits.setStretch(@stretch)

   getExtent: (value) ->
     return (@max - @min) * value / 1000

-  updateExtent: (min, max) =>
-    min = @getExtent(min)
-    max = @getExtent(max)
+  updateExtent: =>
+    min = @opts.extent.min
+    max = @opts.extent.max
     @wfits.setExtent(min, max)


Remove customer.alive (again, sorry)

Remove customer.alive (again, sorry)

--- source/z_game.coffee
+++ source/z_game.coffee
@@ -42,9 +42,8 @@
         $("#phone_queue").append("
" + phone.text + "

")

     for customer in Game.state.customers()
-      if customer.alive
-        id = customer.id
-        $('#customer_list').append("
" + customer.name + "
Mood: "+  Math.floor(customer.mood * 100) + " Worth: " + Math.floor(customer.worth) + "
")
+      id = customer.id
+      $('#customer_list').append("
" + customer.name + "
Mood: "+  Math.floor(customer.mood * 100) + " Worth: " + Math.floor(customer.worth) + "
")

   @run: ->


Items are accessed via availableItems(), not directly via attributes

--- spec/Thenable.coffee
+++ spec/Thenable.coffee
@@ -848,6 +848,7 @@
       ], (c, results) ->
         paths = results.map (r) -> r.path
         idx = paths.indexOf 'root-tripled-btreethen'
+        idx = 0 if idx is -1
         results[idx]
       .finally 'end',   (c, res) ->
         chai.expect(res).to.eql [15]
@@ -875,6 +876,7 @@
       ], (c, results) ->
         paths = results.map (r) -> r.path
         idx = paths.indexOf 'root-tripled-bthen0-bthen1'
+        idx = 0 if idx is -1
         results[idx]
       .finally 'end',   (c, res) ->
         chai.expect(res).to.eql [15]
@@ -938,7 +940,7 @@
         tree.deliver data
         tree.then "#{multiplier}", (c, d) ->
           c.branch 'tripled', (b, data) ->
-            data is b.attributes.items.length
+            data is b.availableItems().length
       t = Root()
       t.deliver
         config:
@@ -949,11 +951,12 @@
           'item2'
           ]
       .then (c, d) ->
-        c.source.attributes.items.length
+        c.availableItems().length
       .contest "contest-multiply", [
         multiply.bind @, 2
       ], (c, results) ->
         results[0]
       .finally 'enfin-fini', (c, res) ->
         chai.expect(res[0]).to.be.true
-        done()
+        chai.expect(c.availableItems().length).to.equal 2
+        done()


provider already keyed

provider already keyed

--- resources/assets/coffee/react/beatmapset-page/scoreboard-table.coffee
+++ resources/assets/coffee/react/beatmapset-page/scoreboard-table.coffee
@@ -75,7 +75,6 @@

     tr
       className: osu.classWithModifiers("#{bn}__body-row", classMods),
-      key: index,

       td className: osu.classWithModifiers(cell, ['rank']), "##{index+1}"


Add test for `git.relativize`

Add test for `git.relativize`

--- spec/git-spec.coffee
+++ spec/git-spec.coffee
@@ -23,3 +23,8 @@

     it "returns a submodule when given file is in a submodule of a project repo", ->
       expect(git.getSubmodule(pathToSubmoduleFile)).toBeTruthy()
+
+  describe "git.relativize", ->
+    it "returns relativized filepath for files in repo", ->
+      expect(git.relativize pathToRepoFile).toBe 'lib/git.coffee'
+      expect(git.relativize pathToSubmoduleFile).toBe 'foo.txt'


Remove stray test lines

Remove stray test lines

--- services/web/test/UnitTests/coffee/Project/ProjectControllerTests.coffee
+++ services/web/test/UnitTests/coffee/Project/ProjectControllerTests.coffee
@@ -495,8 +495,6 @@
 			]

 		it 'should produce the expected results', ->
-			result = @ids.map (i) =>
-				@ProjectController._isInPercentageRollout('abcd', i, 50)
 			expect(
 				@ids.map (i) =>
 					@ProjectController._isInPercentageRollout('abcd', i, 50)


JGroup: Permissions: read group activity is required for guests

--- workers/social/lib/social/models/group/index.coffee
+++ workers/social/lib/social/models/group/index.coffee
@@ -49,7 +49,7 @@
         public                            : ['moderator', 'member']
         private                           : ['moderator', 'member']
       'read group activity'               :
-        public                            : ['member', 'moderator']
+        public                            : ['guest', 'member', 'moderator']
         private                           : ['member', 'moderator']
       'create groups'                     : ['moderator']
       'edit groups'                       : ['moderator']


Set comment elements from elementRefs

Set comment elements from elementRefs

--- test-integration/helpers/test-element.coffee
+++ test-integration/helpers/test-element.coffee
@@ -52,7 +52,8 @@

 class TestHelper extends TestItemHelper
-  constructor: (test, testElementLocator, commonElements = {}, options) ->
+  constructor: (test, testElementLocator, commonElements, options) ->
+    commonElements ||= _.result(@, 'elementRefs', {})
     defaultOptions =
       loadingLocator:
         css: '.is-loading'


[➦] Merged changes.

[➦] Merged changes.

--- vendor/assets/javascripts/jquery/plugins/roofify/roofy/section.js.coffee
+++ vendor/assets/javascripts/jquery/plugins/roofify/roofy/section.js.coffee
@@ -21,9 +21,10 @@
     @roofy   = roofy
     @options = $.extend @defaults, options

-    @id        = @section.data 'id'
+    id = @section.data 'id'
+
     @backstage = @roofy.backstage
-    @pointer   = @roofy.controlPanel.find "> a.control[data-id='#{@id}']"
+    @pointer   = @roofy.controlPanel.find "> a.control[data-id='#{id}']"
     @close     = @section.find 'a.close'

     initialize.call @


InputView: Fix setValue method for checkbox and radio.

--- lib/components/inputs/inputview.coffee
+++ lib/components/inputs/inputview.coffee
@@ -235,14 +235,21 @@
   ###*
    * Set the value of this input field.
   ###
-  setValue:(value)->
-    $el = @$()
-    el  = $el[0]
-    if @getOption("type") in ["checkbox", "radio"]
+  setValue: (value) ->
+
+    $el    = @$()
+    [ el ] = $el
+
+    if @getOption('type') in [ 'checkbox', 'radio' ]
       if value
-      then el.setAttribute "checked", "checked"
-      else el.removeAttribute "checked"
+        el.setAttribute 'checked', 'checked'
+        el.checked = yes
+      else
+        el.removeAttribute 'checked'
+        el.checked = no
+
     else $el.val value
+

   setCase:(forceCase)->
     cb = =>


Fix closure variable capture bug

Fix closure variable capture bug


fixes in taxons.js.coffee

fixes in taxons.js.coffee


Describe share popup option setting procedure

--- client/app/lib/navigation/navigationmachineitem.coffee
+++ client/app/lib/navigation/navigationmachineitem.coffee
@@ -176,6 +176,34 @@

   popups = {}

+  ###
+
+  This function determines what sort of machine share popup should be
+  displayed based on given options and registered invitations in
+  `MachineShareManager`.
+
+  If an invitation found for machine given to `NavigationMachineItem`
+  instance then share popup is displayed in invitation type for the
+  shared workspace attached in invitation object.
+
+  Default behavior of `SidebarMachineSharePopup` instance satisfies
+  `shared machine` invitations.
+
+  If an invitation is not found then state of invitations deduced by
+  checking related properties.
+
+  If user is a permanent user then approve state of `JMachine`
+  determines type of share popup.
+
+  If user is not a permanent user then share popup type is set to
+  `collaboration`.  If a workspace identifier is given in options then
+  associated `JWorkspace` is found.  Channel identifier is set from
+  matching workspace object.
+
+  Collaboration invitation is displayed if user is not a participant
+  of associated channel.
+
+  ###
   showSharePopup: (options = {}) ->

     show = (options) =>


client: make sure brand is slugified

client: make sure brand is slugified

Signed-off-by: Umut Sirin <4055abbc0e40a1254e715b952ccd414607e0b365@gmail.com>

--- client/app/lib/redux/modules/payment/creditcard.coffee
+++ client/app/lib/redux/modules/payment/creditcard.coffee
@@ -1,3 +1,4 @@
+kd = require 'kd'
 _ = require 'lodash'
 immutable = require 'app/util/immutable'

@@ -56,7 +57,7 @@

   selector = valueSelector(state)

-  brand = selector 'brand', (brand) -> brand.toLowerCase()
+  brand = selector 'brand', (brand) -> kd.utils.slugify brand.toLowerCase()
   number = selector 'last4', (last4) ->
     if brand is 'amex'
     then "•••• •••••• •#{last4}"


client: home: remove placeholders from the 2fa view

--- client/home/lib/account/homeaccountsecurityview.coffee
+++ client/home/lib/account/homeaccountsecurityview.coffee
@@ -121,11 +121,9 @@
       cssClass             : 'AppModal-form'
       fields               :
         tfcode             :
-          placeholder      : 'Enter the verification code'
           name             : 'tfcode'
           label            : 'Verification Code'
         password           :
-          placeholder      : 'Enter your Koding password'
           name             : 'password'
           type             : 'password'
           label            : 'Password'


Add option to accept search of regex

Add option to accept search of regex

--- client/ide/views/contentsearch/idecontentsearch.coffee
+++ client/ide/views/contentsearch/idecontentsearch.coffee
@@ -40,15 +40,15 @@
               itemClass     : KodingSwitch
               defaultValue  : no
               cssClass      : 'tiny switch'
-            # regExpToggle    :
-            #   label         : 'Use filename regexp'
-            #   itemClass     : KodingSwitch
-            #   defaultValue  : no
-            #   cssClass      : 'tiny switch'
-            #   nextElement   :
-            #     regExpValue :
-            #       itemClass : KDInputView
-            #       type      : 'text'
+             regExpToggle    :
+               label         : 'Use filename regexp'
+               itemClass     : KodingSwitch
+               defaultValue  : no
+               cssClass      : 'tiny switch'
+               nextElement   :
+                 regExpValue :
+                   itemClass : KDInputView
+                   type      : 'text'
             warningView     :
               itemClass     : KDView
               cssClass      : 'hidden notification'
@@ -63,15 +63,23 @@
     @rootPath       = Encoder.XSSEncode @whereInput.getValue()
     isCaseSensitive = @caseToggle.getValue()
     isWholeWord     = @wholeWordToggle.getValue()
-    # isRegExp        = @regExpToggle.getValue()
+    isRegExp        = @regExpToggle.getValue()

     exts            = IDE.settings.editor.getAllExts()
     include         = "\\*{#{exts.join ','}}"
     exclureDirs     = Object.keys IDE.settings.editor.ignoreDirectories
     exclureDirs     = " --exclude-dir=#{exclureDirs.join ' --exclude-dir='}"

-    @searchText     = @searchText.replace new RegExp "\\\'", "g", "'\\''"
-    @searchText     = @searchText.replace /-/g, "\\-"
+    searchText = @searchText
+
+    if not isRegExp
+      splitText = searchText.split "\\n"
+      splitText = splitText.map grepEscapeRegExp
+      searchText = splitText.join "\\n"
+
+    searchText     = searchText.replace new RegExp "\\\'", "g", "'\\''"
+    searchText     = searchText.replace /-/g, "\\-"
+
     flags           = [
       '-s'                           # Silent mode
       '-r'                           # Recursively search subdirectories listed.
@@ -87,7 +95,7 @@
     flags.splice flags.indexOf('-i'), 1  if isCaseSensitive
     flags.splice flags.indexOf('-w'), 1  unless isWholeWord

-    query = "grep #{flags.join ' '} #{exclureDirs} --include=#{include} '#{@searchText}' \"#{@escapeShell @rootPath}\""
+    query = "grep #{flags.join ' '} #{exclureDirs} --include=#{include} '#{searchText}' \"#{@escapeShell @rootPath}\""

     vmController.run query, (err, res) =>
       if (err or res.stderr) and not res.stdout
@@ -95,8 +103,14 @@

       @formatOutput res.stdout, @bound 'createResultsView'

+  escapeRegExp: (str) ->
+    str.replace(/([.*+?\^${}()|\[\]\/\\])/g, "\\$1");
+
   escapeShell: (str) ->
     str.replace /([\\"'`$\s\(\)<>])/g, "\\$1"
+
+  grepEscapeRegExp: (str) ->
+    str.replace(/[[\]{}()*+?.,\\^$|#\s"']/g, "\\$&");

   formatOutput: (output, callback = noop) ->
     # Regexes


Fixed issue #986 - Zammad sends reply to itself.

--- app/assets/javascripts/app/controllers/ticket_zoom/article_actions.coffee
+++ app/assets/javascripts/app/controllers/ticket_zoom/article_actions.coffee
@@ -336,8 +336,7 @@
           articleNew.to = ticket.customer.email

       else
-        user = App.User.find(article.created_by_id)
-        if article.sender.name is 'Agent' && !article.from.match(user.email)
+        if article.sender.name is 'Agent'
           articleNew.to = article.to
         else
           if article.reply_to


BACKOFFICE never change election namespce

--- app/assets/javascripts/backoffice/views/elections/election_item.js.coffee
+++ app/assets/javascripts/backoffice/views/elections/election_item.js.coffee
@@ -41,7 +41,7 @@
     @election.save {}, data: $.param
       election:
         name: electionName
-        namespace: electionName.replace /\s+/g, '-' # TODO: should be compute by API
+        #namespace: electionName.replace /\s+/g, '-' # TODO: should be compute by API

   cancelRenameForm: ->
     @render()


Better checking if the corpus has headword_search

--- app/assets/javascripts/rglossa/components/centre/search_inputs/cwb_search_inputs.jsx.coffee
+++ app/assets/javascripts/rglossa/components/centre/search_inputs/cwb_search_inputs.jsx.coffee
@@ -140,7 +140,7 @@
           React.createElement(component, {
             showRemoveRow: searchQueries.length > 1,
             hasPhoneticForm: corpus.has_phonetic,
-            hasHeadwordSearch: corpus.headword_search && searchQueries.length == 1,
+            hasHeadwordSearch: !!corpus.headword_search && searchQueries.length == 1,
             searchQuery: searchQuery,
             corpus: corpus,
             handleQueryChanged: handleQueryChanged.bind(null, index),


Draw age chart

Draw age chart


Remove unused helpers

Remove unused helpers

--- assets/scripts/app/helpers/handlebars.coffee
+++ assets/scripts/app/helpers/handlebars.coffee
@@ -89,57 +89,6 @@
   Ember.Handlebars.helpers.view.call(this, view, options)
 )

-Travis.SettingsMultiplierView = Ember.CollectionView.extend()
-
-createObjects = (path, offset) ->
-  segments = path.split('.')
-  if segments.length > offset
-    for i in [1..(segments.length - offset)]
-      path = segments.slice(0, i).join('.')
-      if Ember.isNone(Ember.get(this, path))
-        Ember.set(this, path, {})
-
-  return segments
-
-Ember.Handlebars.registerHelper('settings-multiplier', (path, options) ->
-  template   = options.fn
-  delete options.fn
-
-  parentsPath = getSettingsPath(options.data.view)
-  if parentsPath && parentsPath != ''
-    path = parentsPath + '.' + path
-
-  createObjects.call(this, path, 1)
-
-  if Ember.isNone(@get(path))
-    collection = [{}]
-    @set(path, collection)
-
-
-  itemViewClass = Ember.View.extend(
-    template: template,
-    controller: this,
-    tagName: 'li',
-    multiplier: true
-  )
-
-  view = Travis.SettingsMultiplierView.create(
-    contentBinding: 'controller.' + path
-    controller: this
-    tagName: 'ul'
-    itemViewClass: itemViewClass
-    fields: []
-    settingsPath: path
-  )
-
-  view.addObserver('content.length', ->
-    if @get('content.length') == 0
-      @get('content').pushObject({})
-  )
-
-  Ember.Handlebars.helpers.view.call(this, view, options)
-)
-
 Travis.FormSettingsView = Ember.View.extend Ember.TargetActionSupport,
   target: Ember.computed.alias('controller')
   actionContext: Ember.computed.alias('context'),
@@ -174,130 +123,6 @@
   delete options.fn

   Ember.Handlebars.helpers.view.call(this, view, options)
-)
-
-Ember.Handlebars.helper('settings-select', (options) ->
-  view = options.data.view
-  optionValues = options.hash.options
-  delete options.hash.options
-
-  originalPath = options.hash.value
-
-  parentsPath = getSettingsPath(view)
-  #TODO: such checks should also check parents, not only current context view
-  if !view.get('multiplier') && parentsPath && parentsPath != ''
-    originalPath = parentsPath + '.' + originalPath
-
-  fullPath = originalPath
-
-  if view.get('multiplier')
-    fullPath = 'view.content.' + fullPath
-
-  createObjects.call(this, fullPath, 1)
-
-  # TODO: setting a value here does not work and we still need
-  #       a valueBinding in the view, I'm not sure why
-  options.hash.value = fullPath
-
-  selectView = Ember.Select.create(
-    content: [''].pushObjects(optionValues.split(','))
-    controller: this
-    valueBinding: 'controller.' + fullPath
-  )
-
-  Ember.Handlebars.helpers.view.call(this, selectView, options)
-)
-
-
-
-Ember.Handlebars.helper('settings-remove-link', (options) ->
-  view = Ember.View.extend(
-    tagName: 'a'
-    attributeBindings: ['href', 'style']
-    href: '#'
-    style: (->
-      # TODO: do not assume that we're direct child
-      if @get('parentView.parentView.content.length') == 1
-        'display: none'
-    ).property('parentView.parentView.content.length')
-    template: Ember.Handlebars.compile('remove')
-    controller: this
-    click: (event) ->
-      event.preventDefault()
-
-      if content = @get('parentView.content')
-        @get('parentView.parentView.content').removeObject(content)
-  ).create()
-
-  Ember.Handlebars.helpers.view.call(this, view, options)
-)
-
-Ember.Handlebars.registerHelper('settings-add-link', (path, options) ->
-  parentsPath = getSettingsPath(options.data.view)
-  if parentsPath && parentsPath != ''
-    path = parentsPath + '.' + path
-
-  view = Ember.View.create(
-    tagName: 'a'
-    attributeBindings: ['href']
-    href: '#'
-    template: options.fn
-    controller: this
-    click: (event) ->
-      event.preventDefault()
-
-      if collection = @get('controller.' + path)
-        collection.pushObject({})
-  )
-
-  Ember.Handlebars.helpers.view.call(this, view, options)
-)
-
-getSettingsPath = (view) ->
-  settingsPaths = []
-  if settingsPath = view.get('settingsPath')
-    settingsPaths.pushObject settingsPath
-
-  parent = view
-  while parent = parent.get('parentView')
-    if settingsPath = parent.get('settingsPath')
-      settingsPaths.pushObject settingsPath
-
-  return settingsPaths.reverse().join('.')
-
-Ember.Handlebars.helper('settings-input', (options) ->
-  view = options.data.view
-
-  if options.hash.type == 'checkbox'
-    originalPath = options.hash.checked
-  else
-    originalPath = options.hash.value
-
-  parentsPath = getSettingsPath(view)
-  #TODO: such checks should also check parents, not only current context view
-  if !view.get('multiplier') && parentsPath && parentsPath != ''
-    originalPath = parentsPath + '.' + originalPath
-
-  fullPath = originalPath
-
-  if view.get('multiplier')
-    fullPath = 'view.content.' + fullPath
-
-  if options.hash.type != 'password'
-    createObjects.call(this, fullPath, 1)
-  else
-    createObjects.call(view, fullPath, 2)
-    content = view.get('content')
-    fullPath += ".value"
-    if Ember.isNone(Ember.get(content, originalPath))
-      Ember.set(content, originalPath, {})
-    Ember.set(content, originalPath + ".type", 'password')
-
-  if options.hash.type == 'checkbox'
-    options.hash.checked = fullPath
-  else
-    options.hash.value = fullPath
-  Ember.Handlebars.helpers.input.call(this, options)
 )

 Handlebars.registerHelper 'tipsy', (text, tip) ->


Remove broken/unused button wizard button from timeline

--- app/assets/javascripts/components/timeline/timeline.cjsx
+++ app/assets/javascripts/components/timeline/timeline.cjsx
@@ -110,7 +110,6 @@

Timeline

-        <CourseLink to='wizard', text='Open Wizard', className='button large dark' />
         {@props.controls(controls)}

@@ -121,4 +120,4 @@

 )

-module.exports = DDContext(HTML5Backend)(Timeline)+module.exports = DDContext(HTML5Backend)(Timeline)


[ISSUE-3348] LC: Fix moment.js deprecation warning

--- app/assets/javascripts/darkswarm/filters/dates.js.coffee
+++ app/assets/javascripts/darkswarm/filters/dates.js.coffee
@@ -4,7 +4,7 @@

 Darkswarm.filter "sensible_timeframe", (date_in_wordsFilter)->
   (date) ->
-    if moment().add('days', 2) < moment(date)
+    if moment().add(2, 'days') < moment(date)
       t 'orders_open'
     else
       t('closing') + date_in_wordsFilter(date)


Specify API date format when converting date to string in JS

--- app/assets/javascripts/darkswarm/filters/dates.js.coffee
+++ app/assets/javascripts/darkswarm/filters/dates.js.coffee
@@ -1,10 +1,15 @@
+@API_DATETIME_FORMAT = "YYYY-MM-DD HH:mm:SS Z"
+
 Darkswarm.filter "date_in_words", ->
-  (date) ->
-    moment(date).fromNow()
+  (date, dateFormat) ->
+    dateFormat ?= @API_DATETIME_FORMAT
+    moment(date, dateFormat).fromNow()

 Darkswarm.filter "sensible_timeframe", (date_in_wordsFilter)->
-  (date) ->
-    if moment().add(2, 'days') < moment(date)
+  (date, dateFormat) ->
+    dateFormat ?= @API_DATETIME_FORMAT
+
+    if moment().add(2, 'days') < moment(date, dateFormat)
       t 'orders_open'
     else
       t('closing') + date_in_wordsFilter(date)


Don't continuously re-post data on cart error

--- app/assets/javascripts/darkswarm/services/cart.js.coffee
+++ app/assets/javascripts/darkswarm/services/cart.js.coffee
@@ -50,7 +50,6 @@
         @popQueue() if @update_enqueued

       .error (response, status)=>
-        @scheduleRetry(status)
         @update_running = false

     compareAndNotifyStockLevels: (stockLevels) =>
@@ -86,13 +85,6 @@
           quantity: li.quantity
           max_quantity: li.max_quantity
       {variants: variants}
-
-    scheduleRetry: (status) =>
-      console.log "Error updating cart: #{status}. Retrying in 3 seconds..."
-      $timeout =>
-        console.log "Retrying cart update"
-        @orderChanged()
-      , 3000

     saved: =>
       @dirty = false


corrected location of delete button

corrected location of delete button

--- app/assets/javascripts/components/mark/tools/rectangle-tool/index.cjsx
+++ app/assets/javascripts/components/mark/tools/rectangle-tool/index.cjsx
@@ -7,8 +7,8 @@

 MINIMUM_SIZE = 5
 DELETE_BUTTON_ANGLE = 45
-DELETE_BUTTON_DISTANCE_X = 5
-DELETE_BUTTON_DISTANCE_Y = 12
+DELETE_BUTTON_DISTANCE_X = 12
+DELETE_BUTTON_DISTANCE_Y = 0
 DEBUG = false

 module.exports = React.createClass
@@ -73,8 +73,6 @@

   componentWillReceiveProps:(newProps)->
     x1 = newProps.mark.x
-
-    console.log "newProps.mark.width", newProps.mark.width
     x2 = x1 + newProps.mark.width
     y1 = newProps.mark.y
     y2 = y1 + newProps.mark.height
@@ -82,7 +80,6 @@
     @setState pointsHash: @createRectangleObjects(x1, x2, y1, y2)

   createRectangleObjects: (x1 , x2, y1, y2) ->
-    console.log "x1 , x2, y1, y2: #{x1} , #{x2}, #{y1}, #{y2}"
     if x1 < x2
       LX = x1
       HX = x2
@@ -150,7 +147,7 @@
   getDeleteButtonPosition: ()->
     points = @state.pointsHash["handleHLDrag"]
     x = points[0] + DELETE_BUTTON_DISTANCE_X / @props.xScale
-    y = points[1] / @props.yScale
+    y = points[1] + DELETE_BUTTON_DISTANCE_Y / @props.yScale
     {x, y}

   getMarkButtonPosition: ()->


Also copy the `accept` attribute when recreating element, fix #2057

--- src/resources-packaged/ops/javascript/orbeon/xforms/control/Upload.coffee
+++ src/resources-packaged/ops/javascript/orbeon/xforms/control/Upload.coffee
@@ -106,6 +106,7 @@
         newInputElement.setAttribute "name", inputElement.name
         newInputElement.setAttribute "size", inputElement.size
         newInputElement.setAttribute "unselectable", "on" # The server sets this, so we have to set it again
+        newInputElement.setAttribute "accept", inputElement.accept
         parentElement.replaceChild newInputElement, inputElement

 Page.registerControlConstructor Upload, (container) -> YD.hasClass container, "xforms-upload"


[PUBDEV-3903] `x-h2o-context-path` check

This will make `x-h2o-context-path` header check case insensitive and resolve [PUBDEV-3903](https://0xdata.atlassian.net/browse/PUBDEV-3903)

--- src/core/flow.coffee
+++ src/core/flow.coffee
@@ -15,7 +15,7 @@
         url: window.referrer
         type: 'GET'
         success: (data, status, xhr) ->
-            if xhr.getAllResponseHeaders().indexOf("X-h2o-context-path") != -1
+            if xhr.getAllResponseHeaders().search(/x-h2o-context-path/i) != -1
                 window.Flow.ContextPath = xhr.getResponseHeader('X-h2o-context-path')
         async: false


[skip] Increased the padding at the end of roadmaps to give room for new milestones (4m)

--- app/assets/javascripts/houston/roadmap/views/thumbnail_roadmap_view.coffee
+++ app/assets/javascripts/houston/roadmap/views/thumbnail_roadmap_view.coffee
@@ -69,10 +69,10 @@
   update: ->
     if @milestones.length > 0
       @startDate = 3.weeks().before d3.min(@milestones.pluck('startDate'))
-      @endDate = 6.weeks().after d3.max(@milestones.pluck('endDate'))
+      @endDate = 12.weeks().after d3.max(@milestones.pluck('endDate'))
     else
       @startDate = 3.weeks().ago()
-      @endDate = 2.years().after(startDate)
+      @endDate = 12.weeks().fromNow()

     @x = d3.time.scale()
       .domain([@startDate, @endDate])


Added test for destroy

Added test for destroy

--- test/spec/sync/flat/convenience.tests.coffee
+++ test/spec/sync/flat/convenience.tests.coffee
@@ -125,6 +125,20 @@
           assert.equal(models.length, BASE_COUNT, 'counted expected number of albums')
           done()

+    describe 'destroy', ->
+      it 'Has a short hand for id', (done) ->
+        Flat.findOne (err, model) ->
+          assert.ifError(err)
+          assert.ok(model, 'found a model')
+
+          Flat.destroy id = model.id, (err) ->
+            assert.ifError(err)
+
+            Flat.findOne id, (err, model) ->
+              assert.ifError(err)
+              assert.ok(!model, 'model was destroyed')
+              done()
+
     describe 'exists', ->
       it 'Handles an exist with no query', (done) ->
         Flat.exists (err, exists) ->


add app Name.

add app Name.

--- assets/js/app.coffee
+++ assets/js/app.coffee
@@ -20,7 +20,7 @@
   Trello.deauthorize()
   updateLoggedIn()

-Trello.authorize interactive:false, success: onAuthorize
+Trello.authorize interactive:false, success: onAuthorize, name: "KanbanFu.com"

 $("#connectLink").bind 'click', () ->
   Trello.authorize(type: "popup", success: onAuthorize, name: "KanbanFu.com", scope: { write: true, read: true })


develop_areas: minor: bug fix: Bootstrap Modal immediately disappearing.

--- app/assets/javascripts/c80_map_floors.js.coffee
+++ app/assets/javascripts/c80_map_floors.js.coffee
@@ -1,6 +1,6 @@
 #= require history_jquery
 #= require bootstrap/transition
-#= require bootstrap/modal
+# require bootstrap/modal # Bootstrap Modal immediately disappearing: http://stackoverflow.com/a/13670437 # т.к. 101км это первый проект и там уже много нахуеверчено, в том числе: bootstrap.min.js лежит в папке lib/, то эту строку комментируем (только для 101km)
 #= require bootstrap/tooltip
 #= require bootstrap/alert
 #= require bootstrap/dropdown


Add test for token parsing of datetime type.

--- test/unit/token/row-token-parser-test.coffee
+++ test/unit/token/row-token-parser-test.coffee
@@ -74,12 +74,10 @@
 module.exports.intN = (test) ->
   colMetaData = [type: dataTypeByName.IntN]

-  value = 0
-
   buffer = new WritableBuffer(0)

   buffer.writeUInt8(TYPE.ROW)
-  buffer.writeUInt8(value)
+  buffer.writeUInt8(0)
   buffer = buffer.data
   #console.log(buffer)

@@ -92,3 +90,27 @@
   test.ok(token.columns[0].isNull)

   test.done()
+
+module.exports.datetime = (test) ->
+  colMetaData = [type: dataTypeByName.DateTime]
+
+  days = 2                                        # 3rd January 1900
+  threeHundredthsOfSecond = 45 * 300              # 45 seconds
+
+  buffer = new WritableBuffer(0)
+
+  buffer.writeUInt8(TYPE.ROW)
+  buffer.writeInt32LE(days)
+  buffer.writeUInt32LE(threeHundredthsOfSecond)
+  buffer = buffer.data
+  #console.log(buffer)
+
+  token = parser(buffer, 1, colMetaData)
+  #console.log(token)
+
+  test.strictEqual(token.length, buffer.length - 1)
+  test.strictEqual(token.columns.length, 1)
+  test.ok(!token.columns[0].isNull)
+  test.strictEqual(token.columns[0].value.getTime(), new Date('January 3, 1900 00:00:45').getTime())
+
+  test.done()


Focus the first text input on every page.

--- app/assets/javascripts/document_ready.js.coffee
+++ app/assets/javascripts/document_ready.js.coffee
@@ -0,0 +1,2 @@
+$(document).ready ->
+  $('input:text').filter(':first').focus()


activity: reformat `CommentView` class definition

--- client/Social/Activity/views/comments/commentview.coffee
+++ client/Social/Activity/views/comments/commentview.coffee
@@ -1,26 +1,23 @@
 class CommentView extends KDView

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

-    super
+    options.cssClass = KD.utils.curry "comment-container", options.cssClass

-    @setClass "comment-container"
+    super options, data
+
     @createSubViews data
     @resetDecoration()
     @attachListeners()

-    {fixedHeight} = @getOptions()
+    @setFixedHeight fixedHeight  if {fixedHeight} = options

-    fixedHeight or= no

-    @setFixedHeight fixedHeight  if fixedHeight
+  setFixedHeight: (maxHeight) ->

-  render:->
-    @resetDecoration()
-
-  setFixedHeight: (maxHeight)->
     @setClass "fixed-height"
     @commentList.$().css {maxHeight}
+

   createSubViews: (data) ->

@@ -45,56 +42,77 @@
       input.setFocus()
       input.setValue value

-    @commentList.on "OwnCommentWasSubmitted", ->
-      @getDelegate()?.emit "RefreshTeaser"
+    @commentList.on "OwnCommentWasSubmitted", -> @getDelegate()?.emit "RefreshTeaser"

     @commentList.on "OwnCommentHasArrived", ->
+
       showMore.ownCommentArrived()
       @getDelegate()?.emit "RefreshTeaser"

-    @commentList.on "CommentIsDeleted", -> showMore.ownCommentDeleted()
+    @commentList.on "CommentIsDeleted", ->

-    @on "RefreshTeaser",->
+      showMore.ownCommentDeleted()
+
+    @on "RefreshTeaser", ->
+
       @parent?.emit "RefreshTeaser"

     @commentList.emit "BackgroundActivityFinished"

-  attachListeners:->
+
+  attachListeners: ->
+
     @commentList.on "commentInputReceivedFocus", @bound "decorateActiveCommentState"
+    @commentList.on "CommentViewShouldReset", @bound "resetDecoration"

     @commentList.on "CommentLinkReceivedClick", (event) =>
+
       @commentForm.makeCommentFieldActive()
       @commentForm.input.setFocus()

     @commentList.on "CommentCountClicked", =>
+
       @commentList.emit "AllCommentsLinkWasClicked"

-    @commentList.on "CommentViewShouldReset", @bound "resetDecoration"

-  resetDecoration:->
-    post = @getData()
-    if post.repliesCount is 0
-      @decorateNoCommentState()
-    else
-      @decorateCommentedState()
+  decorateNoCommentState: ->

-  decorateNoCommentState:->
     @unsetClass "active-comment"
     @unsetClass "commented"
     @setClass "no-comment"

-  decorateCommentedState:->
+
+  decorateCommentedState: ->
+
     @unsetClass "active-comment"
     @unsetClass "no-comment"
     @setClass "commented"

-  decorateActiveCommentState:->
+
+  decorateActiveCommentState: ->
+
     @unsetClass "no-comment"
     @setClass "active-comment"

-  decorateItemAsLiked:(likeObj)->
+
+  decorateItemAsLiked: (likeObj) ->
+
     if likeObj?.results?.likeCount > 0
       @setClass "liked"
     else
       @unsetClass "liked"
     @ActivityActionsView.setLikedCount likeObj
+
+
+  resetDecoration: ->
+
+    if @getData().repliesCount
+    then @decorateCommentedState()
+    else @decorateNoCommentState()
+
+
+  render: ->
+
+    super
+
+    @resetDecoration()


activity: remove unnecessary prop

activity: remove unnecessary prop

--- client/activity/lib/components/threadheader/index.coffee
+++ client/activity/lib/components/threadheader/index.coffee
@@ -17,7 +17,6 @@
     onUpdatePurpose            : kd.noop
     onLeaveChannel             : kd.noop
     onShowNotificationSettings : kd.noop
-    onVideoStart               : kd.noop

   constructor: (props) ->


ResourceListItem: move destroy flow to it's own handler

--- client/admin/lib/views/resources/resourcelistitem.coffee
+++ client/admin/lib/views/resources/resourcelistitem.coffee
@@ -26,9 +26,6 @@
       click    : @getDelegate().lazyBound 'toggleDetails', this

     resource = @getData()
-    delegate = @getDelegate()
-
-    { computeController } = kd.singletons

     @details = new kd.CustomHTMLView
       cssClass : 'hidden'
@@ -48,15 +45,23 @@
     @details.addSubView new kd.ButtonView
       title    : 'Delete'
       cssClass : 'solid small red fr'
-      callback : ->
-        computeController.ui.askFor 'forceDeleteStack', {}, (status) ->
-          return  unless status.confirmed
-          resource.forceDelete (err) ->
-            delegate.emit 'ReloadItems'  unless showError err
+      callback : @bound 'handleDelete'

     @ownerView = new AvatarView {
       size: { width: 25, height: 25 }
     }, resource.owner
+
+
+  handleDelete: ->
+
+    resource              = @getData()
+    delegate              = @getDelegate()
+    { computeController } = kd.singletons
+
+    computeController.ui.askFor 'forceDeleteStack', {}, (status) ->
+      return  unless status.confirmed
+      resource.maintenance destroyStack: yes,  (err) ->
+        delegate.emit 'ReloadItems'  unless showError err

   toggleDetails: ->


SidebarMachineBox: Remove collapseList from box deselect.

--- client/app/lib/activity/sidebar/sidebarmachinebox.coffee
+++ client/app/lib/activity/sidebar/sidebarmachinebox.coffee
@@ -150,8 +150,6 @@
   deselect: ->

     @unsetClass 'selected'
-
-    @collapseList()
     @deselectWorkspaces()


actions: update search stack scripts call to accept another endpoint

--- client/app/lib/flux/environment/actions.coffee
+++ client/app/lib/flux/environment/actions.coffee
@@ -829,22 +829,20 @@
   reactor.dispatch actions.LOAD_EXPANDED_MACHINE_LABEL_SUCCESS, { label }

-searchStackScript = (text) ->
-
-  { reactor } = kd.singletons
+searchStackScript = (query, markdown = no) ->
+
+  url = if markdown then "/-/stack/getContent/#{query}"
+  else "/-/stack/search/#{query}"
+
   new Promise (resolve, reject) ->
-    opt =
+    options =
       type: 'GET'
-      url: "https://runkit.io/hakankaradis/terraform-yaml/branches/master?query=#{text}"
       contentType: 'application/json'
-      success: (data) ->
-        reactor.dispatch actions.LOAD_STACK_SCRIPTS_SUCCESS, { data }
-        resolve()
-      error: (jqXHR, textStatus, errorThrown) ->
-        reactor.dispatch actions.LOAD_STACK_SCRIPTS_FAIL, {}
-        reject()
-
-    $.ajax opt
+      url: url
+      success: (data) -> resolve JSON.parse data
+      error: (jqXHR, textStatus, errorThrown) -> reject()
+
+    $.ajax options

 module.exports = {


Fix bug on some field not displayed on edit view

--- app/assets/javascripts/cocoon/iceberg.js.coffee
+++ app/assets/javascripts/cocoon/iceberg.js.coffee
@@ -120,6 +120,14 @@
       E.toggleValidateButton(@line)

     toggleInputVisibility: ->
+      @line.find('input[data-input-to-show]').each (index, input) =>
+        if $(input).is("input[type='checkbox']")
+          if $(input).is(':checked') == $(input).data('with-value')
+            @line.find($(input).data('input-to-show')).removeClass('hidden')
+        else if $(input).is("input[type='radio']:checked")
+          debugger
+          if $(input).val() == $(input).data('with-value')
+            @line.find($(input).data('input-to-show')).removeClass('hidden')
       @line.find('input[data-input-to-show]').click (event) =>
         element = $(event.target)
         if element.is("input[type='checkbox']")


ParticipantView: Removed more annotation for change list.

--- client/ide/views/modals/participantview.coffee
+++ client/ide/views/modals/participantview.coffee
@@ -26,11 +26,10 @@
         partial  : 'Working on: '
         cssClass : 'open-panes'

-      changes = rtm.getFromModel(realTimeDoc, participant.nickname).values()
-      subset  = changes.slice 0, 4
-      missing = changes.length - subset.length
+      changes = rtm.getFromModel(realTimeDoc, "#{participant.nickname}Snapshot").values()
+      terminalCounter = 1

-      subset.forEach (change, i) ->
+      changes.forEach (change, i) ->
         return if not change.type or not change.context

         {type, context: { file, paneType, hash }} = change
@@ -40,11 +39,6 @@
             tagName: 'span'
             partial: FSHelper.getFileNameFromPath file.path

-      if missing
-        state.addSubView new KDCustomHTMLView
-          tagName  : 'span'
-          cssClass : 'info'
-          partial  : "and #{missing} more"

       @addSubView @watchButton = new KDButtonView
         title      : 'Watch'


Remove unnecessary js.coffee file

Remove unnecessary js.coffee file

--- app/assets/javascripts/file_templates.js.coffee
+++ app/assets/javascripts/file_templates.js.coffee
@@ -1,3 +0,0 @@
-# Place all the behaviors and hooks related to the matching controller here.
-# All this logic will automatically be available in application.js.
-# You can use CoffeeScript in this file: http://coffeescript.org/


added styles that mercury needs to configuration

--- app/assets/javascripts/mercury/config.js.coffee
+++ app/assets/javascripts/mercury/config.js.coffee
@@ -234,3 +234,19 @@
   # and
   # Mercury.Toolbar.ButtonGroup.contexts
   #
+
+
+  # Styles
+  #
+  # Mercury tries to stay as much out of your code as possible, but because regions appear within your document we need
+  # to include a few styles to indicate regions, as well as the different states of them (eg. focused and active).  The
+  # following styles are injected into your document, and as simple as they might be, you may want to change them.  You
+  # can do so here.
+  #
+  injectedStyles:
+    '''
+    .mercury-region, .mercury-textarea { min-height: 10px; outline: 1px dotted #09F }
+    .mercury-region:focus, .mercury-region.focus, .mercury-textarea.focus { outline: none; -webkit-box-shadow: 0 0 10px #09F, 0 0 1px #045; box-shadow: 0 0 10px #09F, 0 0 1px #045 }
+    .mercury-region:after { content: '\00a0'; display: block; visibility: hidden; clear: both; height: 0; overflow: hidden; }
+    .mercury-snippet { width:200px; height:100px; border: 1px solid red; }
+    '''


Fixed #261.

Fixed #261.

--- client/lib/annotator/pdf-text-highlight.coffee
+++ client/lib/annotator/pdf-text-highlight.coffee
@@ -153,7 +153,7 @@
         $(target).trigger e
         e.type = 'mouseout'

-  _mouseenterHandler: (e) =>
+  _mouseenterHandler: (e, noControl) =>
     # We have to check if highlight already is marked as hovered because of mouse events forwarding
     # we use, which makes the event be send twice, once when mouse really hovers the highlight, and
     # another time when user moves from a highlight to a control - in fact mouseover handler above
@@ -164,33 +164,33 @@
     @_$highlight.addClass 'hovered'
     @_drawHover()
     # When mouseenter handler is called by _annotationMouseenterHandler we do not want to show control
-    @_showControl() if e
+    @_showControl() unless noControl

     # We do not want to create a possible cycle, so trigger only if not called by _annotationMouseenterHandler
-    $('.annotations-list .annotation').trigger 'highlightMouseenter', [@annotation._id] if e
+    $('.annotations-list .annotation').trigger 'highlightMouseenter', [@annotation._id] if noControl

     return # Make sure CoffeeScript does not return anything

-  _mouseleaveHandler: (e) =>
+  _mouseleaveHandler: (e, noControl) =>
     # Probably not really necessary to check if highlight already marked as hovered but to match check above
     return unless @_$highlight.hasClass 'hovered'

     @_$highlight.removeClass 'hovered'
     @_hideHover()
     # When mouseleave handler is called by _annotationMouseleaveHandler we do not want to show control
-    @_hideControl() if e
+    @_hideControl() unless noControl

     # We do not want to create a possible cycle, so trigger only if not called by _annotationMouseleaveHandler
-    $('.annotations-list .annotation').trigger 'highlightMouseleave', [@annotation._id] if e
+    $('.annotations-list .annotation').trigger 'highlightMouseleave', [@annotation._id] if noControl

     return # Make sure CoffeeScript does not return anything

   _annotationMouseenterHandler: (e, annotationId) =>
-    @_mouseenterHandler() if annotationId in _.pluck @annotation.annotations, '_id'
+    @_mouseenterHandler null, true if annotationId in _.pluck @annotation.annotations, '_id'
     return # Make sure CoffeeScript does not return anything

   _annotationMouseleaveHandler: (e, annotationId) =>
-    @_mouseleaveHandler() if annotationId in _.pluck @annotation.annotations, '_id'
+    @_mouseleaveHandler null, true if annotationId in _.pluck @annotation.annotations, '_id'

   _createHighlight: =>
     scrollLeft = $(window).scrollLeft()
@@ -263,7 +263,7 @@

     # We fake mouse leaving if highlight was hovered by any chance
     # (this happens when you remove a highlight through a control).
-    @_mouseleaveHandler()
+    @_mouseleaveHandler null

     $(@_$highlight).remove()


#150 mode switch buttons don't get foxus

--- app/assets/javascripts/oxalis/controller.coffee
+++ app/assets/javascripts/oxalis/controller.coffee
@@ -150,6 +150,7 @@
         id = @modeMapping[ $(button).attr("id") ]
         do (id) ->
           $(button).on "click", ->
+            $(this).blur()
             _controller.setMode( id )

         if not (id in @allowedModes)
@@ -238,7 +239,7 @@
     else # newMode not allowed or invalid
       return

-
+
     for button in $("#view-mode .btn-group").children()

       $(button).removeClass("btn-primary")


#2 update texture if any bucket was loaded

--- app/assets/javascripts/oxalis/controller.coffee
+++ app/assets/javascripts/oxalis/controller.coffee
@@ -75,6 +75,10 @@
       @setMode(constants.MODE_PLANE_TRACING)
       #@setMode(constants.MODE_VOLUME)

+      for binaryName of @model.binary
+        @model.binary[binaryName].cube.on "bucketLoaded" : =>
+          @model.flycam.update()
+
       if constants.MODE_PLANE_TRACING not in @allowedModes
         if constants.MODE_ARBITRARY in @allowedModes
           @setMode(constants.MODE_ARBITRARY)


Rename constant (2)

Rename constant (2)

--- app/assets/javascripts/oxalis/controller.coffee
+++ app/assets/javascripts/oxalis/controller.coffee
@@ -28,7 +28,7 @@
     _.extend(@, new EventMixin())

     @fullScreen = false
-    @mode = constants.MODE_OXALIS
+    @mode = constants.MODE_PLANE_TRACING

     @model = new Model()

@@ -59,7 +59,7 @@
       @initMouse()
       @initKeyboard()

-      @propagateMode(constants.MODE_OXALIS)
+      @propagateMode(constants.MODE_PLANE_TRACING)

       if constants.ALLOWED_OXALIS not in @allowedModes
         if constants.ALLOWED_ARBITRARY in @allowedModes
@@ -145,14 +145,14 @@

   toggleArbitraryView : ->

-    if @mode is constants.MODE_OXALIS and constants.ALLOWED_ARBITRARY in @allowedModes
+    if @mode is constants.MODE_PLANE_TRACING and constants.ALLOWED_ARBITRARY in @allowedModes
       @planeController.stop()
       @arbitraryController.start()
       @propagateMode(constants.MODE_ARBITRARY)
     else if @mode is constants.MODE_ARBITRARY and constants.ALLOWED_OXALIS in @allowedModes
       @arbitraryController.stop()
       @planeController.start()
-      @propagateMode(constants.MODE_OXALIS)
+      @propagateMode(constants.MODE_PLANE_TRACING)

   propagateMode : (mode) ->
@@ -227,7 +227,7 @@

   centerActiveNode : ->

-    if @mode is constants.MODE_OXALIS
+    if @mode is constants.MODE_PLANE_TRACING
       @planeController.centerActiveNode()
     else
       @arbitraryController.centerActiveNode()


Add Handlebar helper for appRoot

Add Handlebar helper for appRoot

--- SingularityUI/app/lib/view_helper.coffee
+++ SingularityUI/app/lib/view_helper.coffee
@@ -1,3 +1,5 @@
+Handlebars.registerHelper 'appRoot', -> constants.appRoot
+
 Handlebars.registerHelper 'ifEqual', (v1, v2, options) -> if v1 is v2 then options.fn @ else options.inverse @
 Handlebars.registerHelper 'ifLT', (v1, v2, options) -> if v1 < v2 then options.fn @ else options.inverse @
 Handlebars.registerHelper 'ifGT', (v1, v2, options) -> if v1 > v2 then options.fn @ else options.inverse @
@@ -19,4 +21,4 @@
         item._sixthed = if (i + 1) % 6 is 0 then true else false
         _.isFunction(options.hash.fn) and options.hash.fn.apply options, [item, i, items]
         options.fn(item)
-    ).join('')
+    ).join('')


Simplified _handleKeyDown

Simplified _handleKeyDown

--- src/masked_input.cjsx
+++ src/masked_input.cjsx
@@ -88,24 +88,6 @@
     true while --pos >= 0 && not @_getPattern(pos)?
     pos

-  _shiftLeft: (begin, end) ->
-    @_resetBuffer(begin, end)
-    return if begin < 0
-
-    next = @_seekNext(end - 1)
-    for i in [begin...@props.mask.length]
-      pattern = @_getPattern(i)
-      if pattern?
-        if next < @props.mask.length && pattern.test(@_buffer[next])
-          @_buffer[i] = @_buffer[next]
-          @_buffer[next] = @_getFormatChar(next)
-        else
-          break
-
-        next = @_seekNext(next)
-
-    @_cursorPos = Math.max(begin, @_firstNonMaskIdx)
-
   _callOnComplete: (value) ->
     return unless @props.onComplete?
     for i in [0...@props.mask.length]
@@ -116,7 +98,6 @@
   _setValue: (value) ->
     @props.onChange?(target: {value}) if value isnt @state.value
     @setState {value}
-    value

   _handleFocus: (e) ->
     setTimeout =>
@@ -130,14 +111,22 @@
       {begin, end} = @_getSelection()

       if begin is end
-        if e.key is 'Delete'
-          begin = @_seekNext(begin - 1)
-          end = @_seekNext(begin)
-        else
-          begin = @_seekPrev(begin)
+        begin = if e.key is 'Delete' then @_seekNext(begin - 1) else @_seekPrev(begin)
+        end = @_seekNext(begin)

-      @_shiftLeft(begin, end)
-      @_setValue @_buffer.join('')
+      pattern = @_getPattern(begin)
+      if pattern?.test(@_buffer[end])
+        input = @state.value.substring(0, begin) + @state.value.substring(end)
+        value = @_maskedValue(input)
+        # input = @state.value.substring(end)
+        # value = @_maskedValue(input, begin)
+      else
+        @_resetBuffer(begin, end)
+        value = @_buffer.join('')
+
+      @_setValue(value)
+
+      @_cursorPos = Math.max(begin, @_firstNonMaskIdx)

       e.preventDefault()

@@ -148,7 +137,7 @@
     @_setValue value
     @_callOnComplete value

-  _maskedValue: (input) ->
+  _maskedValue: (input, begin=0) ->
     for i in [0...@props.mask.length]
       break if @_buffer[i] isnt input[i]


clio-36232 whitelist prev and next button classes (#194)


Fix a bug which linked URL is invalid

Fix a bug which linked URL is invalid

--- app/assets/javascripts/common/components/body.js.coffee
+++ app/assets/javascripts/common/components/body.js.coffee
@@ -8,8 +8,8 @@
   methods:
     filter: (text) ->
       text = escape text
+      text = linkify text
       text = newLine text
-      text = linkify text
       text

   mounted: ->


When reading a whole folder, client-side pagination is implemented. The servers's response pagination is not yet implemented.

--- app/assets/javascripts/ng-services/ng-ReadSvc.js.coffee
+++ app/assets/javascripts/ng-services/ng-ReadSvc.js.coffee
@@ -8,8 +8,6 @@

   #--------------------------------------------
   # PRIVATE FUNCTION: Load a feed's entries via AJAX in the root scope.
-  # Receives as arguments the feed object and a boolean to indicate whether
-  # to load all entries (true) or only unread ones (false).
   #--------------------------------------------
   load_feed = (feed)->
     # If busy, do nothing
@@ -29,7 +27,7 @@
     # Include read entries in the results, or only unread ones?
     include_read = if $rootScope.load_read_entries then true else false

-    $http.get("/feeds/#{feed.id}.json?include_read=#{include_read}&page=#{$rootScope.entries_page}")
+    $http.get("/feeds/#{feed.id}.json?include_read=#{include_read}&page=#{entriesPaginationSvc.get_entries_page()}")
     .success (data)->
       entriesPaginationSvc.set_busy false
       $rootScope.entries = $rootScope.entries.concat data["entries"]
@@ -38,6 +36,41 @@
         $rootScope.loading_entries = false
         # On first page load, update unread entries count in the feed
         feed.unread_entries = data["unread_entries"]
+    .error (data,status)->
+      $rootScope.loading_entries = false
+      entriesPaginationSvc.set_busy false
+      if status == 404
+        entriesPaginationSvc.set_more_entries_available false
+        timerFlagSvc.start 'error_no_entries' if entriesPaginationSvc.is_first_page()
+      else
+        currentFeedSvc.unset()
+        timerFlagSvc.start 'error_loading_entries'
+
+  #--------------------------------------------
+  # PRIVATE FUNCTION: Load a folder's entries via AJAX in the root scope.
+  #--------------------------------------------
+  load_folder = (folder)->
+    # If busy, do nothing
+    return if entriesPaginationSvc.is_busy()
+    # If no folder is passed, do nothing
+    return if !folder
+    # If a 404 has been received in a previous page (no more entries available), do nothing
+    return if !entriesPaginationSvc.more_entries_available()
+
+    # Increment the results page
+    entriesPaginationSvc.increment_entries_page()
+    # During the first page load show the "loading..." message
+    $rootScope.loading_entries = true if entriesPaginationSvc.is_first_page()
+    # Indicate that AJAX request/response cycle is busy so no more calls are done until finished
+    entriesPaginationSvc.set_busy true
+
+    $http.get("/folders/#{folder.id}.json?page=#{entriesPaginationSvc.get_entries_page()}")
+    .success (data)->
+      entriesPaginationSvc.set_busy false
+      $rootScope.entries = $rootScope.entries.concat data["entries"]
+      if entriesPaginationSvc.is_first_page()
+        # "Loading..." message is only shown while loading the first page of results
+        $rootScope.loading_entries = false
     .error (data,status)->
       $rootScope.loading_entries = false
       entriesPaginationSvc.set_busy false
@@ -68,24 +101,6 @@
       load_feed currentFeedSvc.get()

     #--------------------------------------------
-    # Load a folder's unread entries
-    #--------------------------------------------
-    read_folder: (folder)->
-      currentFolderSvc.set folder
-      $rootScope.loading_entries = true
-
-      $http.get("/folders/#{folder.id}.json")
-      .success (data)->
-        $rootScope.loading_entries = false
-        $rootScope.entries = data["entries"]
-      .error (data,status)->
-        $rootScope.loading_entries = false
-        if status == 404
-          timerFlagSvc.start 'error_no_entries'
-        else
-          timerFlagSvc.start 'error_loading_entries'
-
-    #--------------------------------------------
     # Refresh a feed and load its unread entries
     #--------------------------------------------
     refresh_feed: ->


add >> text to current track in mobile sidebar

--- app/assets/javascripts/objects/mobile_sidebar.js.coffee
+++ app/assets/javascripts/objects/mobile_sidebar.js.coffee
@@ -1,8 +1,8 @@
 @Curri.MobileSidebar =
   init: ->
+    @hideLinks()
     @buildSelector()
     @buildOptions()
-    @hideLinks()
     @onSubmit()

   buildSelector: ->
@@ -16,9 +16,10 @@
   buildOptions: ->
     $('#sidebar-links a').each ->
       el = $(this)
+      highlight = el.closest('.row').hasClass('highlight')
       $("<option />", {
            "value"   : el.attr("href"),
-           "text"    : el.text()
+           "text"    : if highlight then '>> ' + el.text() else el.text()
        }).appendTo("#sidebar-links select")

   hideLinks: ->


Try to fix scroll issue.

Try to fix scroll issue.

--- app/assets/javascripts/web/views/message_view.js.coffee
+++ app/assets/javascripts/web/views/message_view.js.coffee
@@ -7,25 +7,25 @@
   shouldScrollToMessage: false

   willInsertElement: () ->
-    if @get('parentView').state == "inDOM"
-      distance = @get('parentView.desiredScroll')
-      @get('parentView').scrollToFromBottom(distance) if distance
-      @set('shouldScrollToMessage', !@get('parentView').isReadingHistory())
+    # if @get('parentView').state == "inDOM"
+    #   distance = @get('parentView.desiredScroll')
+    #   @get('parentView').scrollToFromBottom(distance) if distance
+    #   @set('shouldScrollToMessage', !@get('parentView').isReadingHistory())

     @_super()

   didInsertElement: ->
-    @get('parentView').scrollToBottom( force: @get('shouldScrollToMessage') ) if @get('parentView')
-    setTimeout =>
-      @get('parentView').scrollToBottom( force: @get('shouldScrollToMessage') ) if @get('parentView')
-      @set('shouldScrollToMessage', false)
-    , 100
+    # @get('parentView').scrollToBottom( force: @get('shouldScrollToMessage') ) if @get('parentView')
+    # setTimeout =>
+    #   @get('parentView').scrollToBottom( force: @get('shouldScrollToMessage') ) if @get('parentView')
+    #   @set('shouldScrollToMessage', false)
+    # , 100

-    if @get('context').get('hasSameAuthorAsPrevious')
-      @.$().prevAll('.message').first().removeClass('message-last')
+    # if @get('context').get('hasSameAuthorAsPrevious')
+    #   @.$().prevAll('.message').first().removeClass('message-last')

-    if @get('context').get('hasSameAuthorAsNext')
-      @.$().nextAll('.message').first().removeClass('message-first')
+    # if @get('context').get('hasSameAuthorAsNext')
+    #   @.$().nextAll('.message').first().removeClass('message-first')

     @.$('a[internal]').on('click', (e) =>
       event.preventDefault()


cleaned up references to proper elements in settings header mode buttons

--- cms/static/coffee/src/views/module_edit.coffee
+++ cms/static/coffee/src/views/module_edit.coffee
@@ -86,5 +86,5 @@

   clickModeButton: (event) ->
     event.preventDefault()
-    @$el.removeClass('not-set')
-    @$el.addClass('is-set')
+    @$el.find("a").removeClass('not-set')
+    @$el.find("a").addClass('is-set')


fixes #3

fixes #3

--- src/hubot-cah.coffee
+++ src/hubot-cah.coffee
@@ -57,14 +57,7 @@
   cardIndex = Math.floor(Math.random()*whiteCards.length)
   return whiteCards[cardIndex]

-db = {
-  scores:         {},                   # {<name>: <score>, ...}
-  activePlayers:  [],                   # [<player name>, ...]
-  blackCard:      random_black_card(),  # <card text>
-  czar:           null,                 # <player name>
-  hands:          {},                   # {<name>: [<card text>, <card text>, ...], ...}
-  answers:        [],                   # [ [<player name>, [<card text>, ...]], ... ]
-}
+db = {}

 # prune inactive player hands, ensure everyone has five cards
 fix_hands = () ->
@@ -199,26 +192,36 @@

 module.exports = (robot) ->

+  db = robot.brain.get 'cah' || {
+    scores:         {},                   # {<name>: <score>, ...}
+    activePlayers:  [],                   # [<player name>, ...]
+    blackCard:      random_black_card(),  # <card text>
+    czar:           null,                 # <player name>
+    hands:          {},                   # {<name>: [<card text>, <card text>, ...], ...}
+    answers:        [],                   # [ [<player name>, [<card text>, ...]], ... ]
+  }
+  robot.brain.set 'cah', db
+
   robot.hear /^cah help$/i, (msg) ->
     msg.send helpSummary

-  robot.hear /cah join$/i, (msg) ->
+  robot.hear /^cah join$/i, (msg) ->
     name = sender(msg)
     add_player(name)
     msg.reply "You are now an active CAH player."

-  robot.hear /cah leave$/i, (msg) ->
+  robot.hear /^cah leave$/i, (msg) ->
     name = sender(msg)
     remove_player(name)
     msg.reply "You are no longer a CAH player. Your score will be preserved should you decide to play again."

-  robot.hear /cah czar$/i, (msg) ->
+  robot.hear /^cah czar$/i, (msg) ->
     if db.czar?
       msg.send db.czar
     else
       msg.send "No Card Czar yet, waiting for players."

-  robot.hear /cah players$/i, (msg) ->
+  robot.hear /^cah players$/i, (msg) ->
     if db.activePlayers.length < 1
       msg.send "Waiting for players."
     else
@@ -227,7 +230,7 @@
         responseString += ", #{db.activePlayers[i]}"
       msg.send responseString

-  robot.hear /cah leaders$/i, (msg) ->
+  robot.hear /^cah leaders$/i, (msg) ->
     scoreTuples = []
     for name,score of db.scores
       scoreTuples.push([name,score])
@@ -243,14 +246,14 @@
       responseString += "\n#{scoreTuples[i][1]} #{scoreTuples[i][0]}"
     msg.send responseString

-  robot.hear /cah score$/i, (msg) ->
+  robot.hear /^cah score$/i, (msg) ->
     score = db.scores[sender(msg)]
     if score?
       msg.reply score
     else
       msg.reply "No CAH score on record."

-  robot.hear /cah (hand|cards)$/i, (msg) ->
+  robot.hear /^cah (hand|cards)$/i, (msg) ->
     cards = db.hands[sender(msg)]
     responseString = "Your white CAH cards:"
     if cards?
@@ -259,7 +262,7 @@
     responseString += "\nCurrent black card: *#{db.blackCard}*"
     robot.messageRoom sender(msg), responseString

-  robot.hear /cah (submit|play)(?: ([0-4]+))+$/i, (msg) ->
+  robot.hear /^cah (submit|play)(?: ([0-4]+))+$/i, (msg) ->
     if sender(msg) == db.czar
       msg.reply "You are currently the Card Czar!"
       return
@@ -287,7 +290,7 @@
       submit_answer(sender(msg), nums)
       msg.reply "Submission accepted."

-  robot.hear /cah answers$/i, (msg) ->
+  robot.hear /^cah answers$/i, (msg) ->
     if sender(msg) != db.czar
       msg.reply "Only the Card Czar may see the white card submissions."
     else
@@ -296,9 +299,9 @@
       for i in [0...answers.length] by 1
         cards = answers[i][1]
         responseString += "\n#{i}: #{generate_phrase(db.blackCard, cards)}"
-      msg.reply responseString
-
-  robot.hear /cah (choose|pick) ([0-9]+)$/i, (msg) ->
+      robot.messageRoom sender(msg), responseString
+
+  robot.hear /^cah (choose|pick) ([0-9]+)$/i, (msg) ->
     if sender(msg) != db.czar
       msg.reply "Only the Card Czar may choose a winner."
     else if db.answers.length == 0
@@ -310,8 +313,8 @@
       else
         msg.send czar_choose_winner num

-  robot.hear /cah (status|question)$/i, (msg) ->
+  robot.hear /^cah (status|question)$/i, (msg) ->
     msg.send game_state_string()

-  robot.hear /cah skip$/i, (msg) ->
+  robot.hear /^cah skip$/i, (msg) ->
     msg.send czar_choose_winner -1


Small topic details UI change

Small topic details UI change

--- static/js/topic-details.coffee
+++ static/js/topic-details.coffee
@@ -20,7 +20,7 @@
         for group in @filter_groups
             grp_el = $('<div class="btn-group" />')
             for f in group.filters
-                el = $("<button class='btn btn-small' type='button' />")
+                el = $("<button class='btn btn-small btn-default' type='button' />")
                 if f.icon
                     el.append $("<i class='typcn typcn-#{f.icon}' />")
                     el.attr 'title', f.name


fix some typos in comments about memberships

--- salvus/schema.coffee
+++ salvus/schema.coffee
@@ -751,11 +751,11 @@

 membership.premium =    # a user that has a premium membership
     cores       : 10
-    disk_quota  : 50000      # 5 GB
-    memory      : 20000      # 2 GB
+    disk_quota  : 50000      # 50 GB
+    memory      : 20000      # 20 GB
     mintime     : 240*3600   # 10 days
-    network     : 50         # 5 projects
-    member_host : 20         # 2 projects
+    network     : 50         # 50 projects
+    member_host : 20         # 20 projects

 membership.standard =   # a user that has a standard membership
     cores       : 1


corrected other sutupid syntax rerror

corrected other sutupid syntax rerror


Trim whitespace

Trim whitespace

--- core/app/backbone/views/auto_complete/search_view.coffee
+++ core/app/backbone/views/auto_complete/search_view.coffee
@@ -1,7 +1,7 @@
 class window.AutoCompleteSearchView extends Backbone.Marionette.Layout
   initializeChildViews: (opts)->
     @search_collection = opts.search_collection()
-
+
     @initSearchModel()
     @initTextInputView opts.placeholder
     @initFilteredSearchCollection opts.search_collection, opts.filter_on
@@ -24,7 +24,7 @@
     if search_collection? and filter_on?
       @filtered_search_collection = collectionDifference(search_collection(),
         filter_on, @search_collection, @collection)
-    else
+    else
       @filtered_search_collection = @search_collection

   initSearchListView: (search_list_view) ->


some more coverage

some more coverage

--- test/pagerv2_commands_test.coffee
+++ test/pagerv2_commands_test.coffee
@@ -362,7 +362,6 @@
           .reply(200, require('./fixtures/oncall_list-ok.json'))
           .post('/schedules/42/overrides')
           .reply(200, require('./fixtures/override_create-ok.json'))
-
         afterEach ->
           nock.cleanAll()

@@ -383,7 +382,6 @@
           .reply(200, require('./fixtures/override_get-ok.json'))
           .delete('/schedules/42/overrides/PQ47DCP')
           .reply(200, require('./fixtures/override_get-ok.json'))
-
         afterEach ->
           nock.cleanAll()

@@ -393,6 +391,37 @@
             .to.eql 'Ok, momo! Aurelio Rice override is cancelled.'

     # ----------------------------------------------------------------------------------------------
+    describe '".pd me now"', ->
+      context 'when something goes wrong,', ->
+        beforeEach ->
+          nock('https://api.pagerduty.com')
+          .get('/oncalls?time_zone=UTC&schedule_ids%5B%5D=42&earliest=true')
+          .reply 503, { error: { code: 503, message: "it's all broken!" } }
+        afterEach ->
+          room.robot.brain.data.pagerv2 = { }
+          nock.cleanAll()
+
+        say 'pd me now', ->
+          it 'returns the error message', ->
+            expect(hubotResponse())
+            .to.eql "503 it's all broken!"
+
+      context 'when everything goes right,', ->
+        beforeEach ->
+          nock('https://api.pagerduty.com')
+          .get('/oncalls?time_zone=UTC&schedule_ids%5B%5D=42&earliest=true')
+          .reply(200, require('./fixtures/oncall_list-ok.json'))
+          .post('/schedules/42/overrides')
+          .reply(200, require('./fixtures/override_create-ok.json'))
+        afterEach ->
+          nock.cleanAll()
+
+        say 'pd me now', ->
+          it 'returns name of who is on call', ->
+            expect(hubotResponse())
+            .to.eql 'Rejoice Aurelio Rice! momo is now on call.'
+
+    # ----------------------------------------------------------------------------------------------
     describe '".pd incident 1234"', ->
       context 'when something goes wrong,', ->
         beforeEach ->
@@ -414,7 +443,6 @@
           nock('https://api.pagerduty.com')
           .get('/incidents/1234')
           .reply(200, require('./fixtures/incident_get-ok.json'))
-
         afterEach ->
           nock.cleanAll()

@@ -447,7 +475,6 @@
           .get('/incidents?time_zone=UTC&include%5B%5D=first_trigger_log_entry&date_range=all' +
                '&statuses%5B%5D=triggered&statuses%5B%5D=acknowledged')
           .reply(200, require('./fixtures/incident_list-ok.json'))
-
         afterEach ->
           nock.cleanAll()

@@ -481,7 +508,6 @@
           .reply(200, require('./fixtures/incident_list-ok.json'))
           .put('/incidents')
           .reply(200, require('./fixtures/incident_manage-ok.json'))
-
         afterEach ->
           nock.cleanAll()

@@ -496,7 +522,6 @@
           .get('/incidents?time_zone=UTC&include%5B%5D=first_trigger_log_entry&date_range=all&' +
                'statuses%5B%5D=triggered')
           .reply(200, require('./fixtures/incident_list-empty.json'))
-
         afterEach ->
           nock.cleanAll()

@@ -526,7 +551,6 @@
           nock('https://api.pagerduty.com')
           .put('/incidents')
           .reply(200, require('./fixtures/incident_manage-ok.json'))
-
         afterEach ->
           nock.cleanAll()

@@ -575,7 +599,6 @@
           .get('/incidents?time_zone=UTC&include%5B%5D=first_trigger_log_entry&date_range=all&' +
                'statuses%5B%5D=acknowledged')
           .reply(200, require('./fixtures/incident_list-empty.json'))
-
         afterEach ->
           nock.cleanAll()

@@ -605,7 +628,6 @@
           nock('https://api.pagerduty.com')
           .put('/incidents')
           .reply(200, require('./fixtures/incident_manage-ok.json'))
-
         afterEach ->
           nock.cleanAll()

@@ -654,7 +676,6 @@
           .get('/incidents?time_zone=UTC&include%5B%5D=first_trigger_log_entry&date_range=all' +
                '&statuses%5B%5D=triggered&statuses%5B%5D=acknowledged')
           .reply(200, require('./fixtures/incident_list-empty.json'))
-
         afterEach ->
           nock.cleanAll()

@@ -684,7 +705,6 @@
           nock('https://api.pagerduty.com')
           .put('/incidents')
           .reply(200, require('./fixtures/incident_manage-ok.json'))
-
         afterEach ->
           nock.cleanAll()

@@ -733,7 +753,6 @@
           .get('/incidents?time_zone=UTC&include%5B%5D=first_trigger_log_entry&date_range=all' +
                '&statuses%5B%5D=triggered&statuses%5B%5D=acknowledged')
           .reply(200, require('./fixtures/incident_list-empty.json'))
-
         afterEach ->
           nock.cleanAll()

@@ -763,7 +782,6 @@
           nock('https://api.pagerduty.com')
           .post('/incidents/PT4KHLK/snooze')
           .reply(200, require('./fixtures/incident_snooze-ok.json'))
-
         afterEach ->
           nock.cleanAll()

@@ -793,7 +811,6 @@
           nock('https://api.pagerduty.com')
           .post('/incidents/PT4KHLK/notes')
           .reply(200, require('./fixtures/note_create-ok.json'))
-
         afterEach ->
           nock.cleanAll()

@@ -823,7 +840,6 @@
           nock('https://api.pagerduty.com')
           .get('/incidents/PT4KHLK/notes')
           .reply(200, require('./fixtures/notes_list-ok.json'))
-
         afterEach ->
           nock.cleanAll()

@@ -853,7 +869,6 @@
           nock('https://api.pagerduty.com')
           .get('/maintenance windows?filter=ongoing')
           .reply(200, require('./fixtures/maintenance_list-ok.json'))
-
         afterEach ->
           nock.cleanAll()

@@ -883,7 +898,6 @@
           nock('https://api.pagerduty.com')
           .post('/maintenance windows')
           .reply(200, require('./fixtures/maintenance_create-ok.json'))
-
         afterEach ->
           nock.cleanAll()

@@ -913,7 +927,6 @@
           nock('https://api.pagerduty.com')
           .delete('/maintenance windows/PW98YIO')
           .reply(200, { })
-
         afterEach ->
           nock.cleanAll()


+ ExpressionStack: tested initial stackId

--- test/unit/expression-stack.coffee
+++ test/unit/expression-stack.coffee
@@ -8,6 +8,9 @@

   beforeEach ->
     testedStack = new ExpressionStack()
+
+  it ".stackId is 0", ->
+    testedStack.stackId.should.equal 0

   it ".stackName is 'bottom'", ->
     testedStack.stackName.should.equal "bottom"


avoid redraw of the container for auto fitting

Former-commit-id: 44d1e9602dbc30c579321ab404b61cbc1bdfa709 [formerly 62a6600fe6cecb5dea38429b647dbb7eedb435ec]
Former-commit-id: 4126d5905d32a01ea52db2e2c80ebdf1f09a83e1

--- js/msa/zoomer.coffee
+++ js/msa/zoomer.coffee
@@ -6,6 +6,8 @@
       @maxLabelLength = 20
       @setZoomLevel 2
       @len = 0
+
+      @_setWidth()

     setZoomLevel: (value) ->
       @level = value
@@ -34,25 +36,30 @@
       stepSize = 20  if @columnWidth is 1
       stepSize

+    _setWidth: ->
+      # totally slow - draws the entire container
+      _rect = @msa.container.getBoundingClientRect()
+      @_width = _rect.right - _rect.left
+
+
     guessZoomLevel:(tSeqs) ->
-      width = @msa.container.offsetWidth
       @len = @getMaxLength tSeqs
       @maxLabelLength =  @getMaxLabelLength tSeqs

       level = 2

-      if @len > width
+      if @len > @_width
         # go to minzoom
         return 1
       else
         # increase as long as possible
         @setZoomLevel level
-        while @msa.stage.width(@len) < width or level is 200
+        while @msa.stage.width(@len) < @_width or level is 200
           level++
           @setZoomLevel level

         if level is 2
-          console.log "len: #{@len} - width: #{width}"
+          console.log "len: #{@len} - width: #{@_width}"
           console.log "stage: #{@msa.stage.width(@len)}"
           console.log "stage: #{@msa.container.id}"
         return level - 1


Add test for ordering

Add test for ordering

--- spec/projects-list-view-spec.coffee
+++ spec/projects-list-view-spec.coffee
@@ -8,13 +8,13 @@
   data =
     testproject1:
       title: "Test project 1"
-      group: "Test"
       paths: ["/Users/project-1"]
     testproject2:
       title: "Test project 2"
       paths: ["/Users/project-2"]
       template: "test-template"
       icon: "icon-bug"
+      group: "Test"

   projects = ->
     array = []
@@ -27,12 +27,13 @@
     workspaceElement = atom.views.getView(atom.workspace)
     listView = new ProjectsListView
     {list, filterEditorView} = listView
-    listView.show(projects())

   it "will list all projects", ->
+    listView.show(projects())
     expect(list.find('li').length).toBe 2

   it "will add the correct icon to each project", ->
+    listView.show(projects())
     icon1 = list.find('li[data-project-title="Test project 1"]').find('.icon')
     icon2 = list.find('li[data-project-title="Test project 2"]').find('.icon')
     expect(icon1.attr('class')).toContain 'icon-chevron-right'
@@ -40,6 +41,7 @@

   describe "When the text of the mini editor changes", ->
     beforeEach ->
+      listView.show(projects())
       listView.isOnDom = -> true # Fix this somehow

     it "will only list projects with the correct title", ->
@@ -74,4 +76,15 @@

       expect(listView.getFilterKey()).toBe listView.defaultFilterKey
       expect(listView.getFilterQuery()).toBe '1'
-      expect(list.find('li').length).toBe 1+      expect(list.find('li').length).toBe 1
+
+  describe "It sorts the projects in correct order", ->
+    it "sorts after title", ->
+      atom.config.set('project-manager.sortBy', 'title')
+      listView.show(projects())
+      expect(list.find('li:eq(0)').data('projectTitle')).toBe "Test project 1"
+
+    it "sort after group", ->
+      atom.config.set('project-manager.sortBy', 'group')
+      listView.show(projects())
+      expect(list.find('li:eq(0)').data('projectTitle')).toBe "Test project 2"


Reduce indentation.

Reduce indentation.

--- src/noreferrer.coffee
+++ src/noreferrer.coffee
@@ -1,5 +1,5 @@
 `/**
-  @license noreferrer.js, version 0.1.2
+  @license noreferrer.js, version 0.1.3
   https://github.com/knu/noreferrer

   Copyright (c) 2011 Akinori MUSHA
@@ -50,17 +50,17 @@
         return

       Event.observe a, 'mouseup', (ev = window.event) ->
-        if Event.isMiddleClick(ev) && middlebutton
-          kill_href()
-          Event.stop(ev)
-          middlebutton = false
-          setTimeout (->
-            alert '''
-              Middle clicking on this link is disabled to keep the browser from sending a referrer.
-              '''
-            restore_href()
-            return
-          ), 500
+        return unless Event.isMiddleClick(ev) && middlebutton
+        kill_href()
+        Event.stop(ev)
+        middlebutton = false
+        setTimeout (->
+          alert '''
+            Middle clicking on this link is disabled to keep the browser from sending a referrer.
+            '''
+          restore_href()
+          return
+        ), 500
         return

       body = """


Added type and dates (EURO FORMAT).

Added type and dates (EURO FORMAT).

--- src/numbersapi.coffee
+++ src/numbersapi.coffee
@@ -14,11 +14,20 @@
 #   Víctor San Martín

 module.exports = (robot) ->
-  robot.respond /numbersapi ([0-9]+)/i, (msg) ->
+  robot.respond /number ([0-9]+|random)\s?(trivia|math|date|year)?/i, (msg) ->
     msg
-      .http("http://numbersapi.com/" + msg.match[1])
+      .http("http://numbersapi.com/" + msg.match[1] + "/" + ( msg.match[2] || "" ))
       .get() (err, res, body) ->
         if err?
           throw err
         else
-          msg.send body+          msg.reply body
+
+  robot.respond /number ([0-9]+)\/([0-9]+)\s?(trivia|math|date|year)?/i, (msg) ->
+    msg
+      .http("http://numbersapi.com/" + msg.match[2] + "/" + msg.match[1] + "/" + ( msg.match[3] || "" ))
+      .get() (err, res, body) ->
+        if err?
+          throw err
+        else
+          msg.reply body


Don't specify listener as attribute, is overwrote by inheritance

--- lib/generators/nas_extjs/templates/public/app/ux/CustomComboBox.coffee
+++ lib/generators/nas_extjs/templates/public/app/ux/CustomComboBox.coffee
@@ -3,16 +3,20 @@
     extend: 'Ext.form.field.ComboBox'

     getSelectedRecord: ->
-        v = this.getValue();
-        this.findRecord( this.valueField || this.displayField, v)
+        v = this.getRawValue()
+        this.findRecord( this.valueField, v) || this.findRecord( this.displayField, v)

-    listeners:
-        select:(cb,recs,opts)->
-            if ( form = cb.up('form') ) && ( editor = form.editingPlugin ) && editor.grid
-                editor.grid.fireEvent( 'combobox_select', recs[0], {
-                    combobox:cb
-                    record: editor.getEditor().getRecord()
-                    form: form.getForm()
-                    editor: editor
-                    grid: editor.grid
-                })
+    _onSelect: (cb,recs,opts)->
+        if ( form = cb.up('form') ) && ( editor = form.editingPlugin ) && editor.grid
+            editor.grid.fireEvent( 'combobox_select', recs[0], {
+                combobox:cb
+                record: editor.getEditor().getRecord()
+                form: form.getForm()
+                editor: editor
+                grid: editor.grid
+            })
+
+
+    initComponent: ->
+        this.callParent()
+        this.on( 'select', this._onSelect )


Language is now saved between sessions

Language is now saved between sessions

--- coffee/_l10n.coffee
+++ coffee/_l10n.coffee
@@ -2,7 +2,7 @@
 class L10n
   constructor: (defaultLang) ->
     @cachedStrings = {}
-    @currentLang = defaultLang or 'en'
+    @currentLang = Settings.get("lang") or defaultLang or 'en'
     @folder = 'l10n/'
     @l10nFileSuffix = '.ini'
     @metadataPath = 'metadata.json'
@@ -98,6 +98,7 @@
   changeLang: (lang) ->
     if lang
       @currentLang = lang
+      Settings.set("lang", lang);

     @fetchIniData(() =>
       @callbacks.forEach((callback) ->


add a comment

add a comment

--- coffee/index.coffee
+++ coffee/index.coffee
@@ -24,6 +24,7 @@
             port = parseInt data
             resolve port
     .catch ->
+        # the api.port may not exist
         true
     .then (oldPort)->
         new Promise (resolve, reject)->


Removes nonscrolling class making x-scroll on iOS devices

--- coffee/panel.coffee
+++ coffee/panel.coffee
@@ -31,10 +31,6 @@
       if navigator.userAgent.match(/(iPad|iPhone|iPod)/g)
         $('.panel-content').css 'overflow':'visible'

-    toggle_scroll: ->
-      @snapper.on 'close', ->
-        $('html, body').toggleClass 'noscroll'
-
     append_menu_to_panel: ->
       $('.panel-left').html(@menu.html())

@@ -58,10 +54,5 @@
   $(document).on 'click', '[data-toggle="panel"]', (e) ->
     e.preventDefault()
     $('.panel-content').panel 'toggle'
-    $('html, body').toggleClass 'noscroll'
-
-  $(document).ready ->
-    $('.panel-content').panel 'toggle_scroll'
-

 ) window.jQuery, window


comments

comments

--- js/umobi.page.coffee
+++ js/umobi.page.coffee
@@ -80,16 +80,19 @@
         if isBothFixed
           $c = c.jQuery()

+          # create ui-content container for scrolling
           $c.wrap('<div class="ui-content-container"/>')
           $contentContainer = $c.parent()

           # Initialize touch scroller with 3D translate if it's on mobile
-          # device
+          # device and the touchScroll option is enabled.
           if umobi.support.touchEnabled and umobi.config.touchScroll
             umobi.scroller.create(c.get(0))
             document.documentElement.style.overflow = "hidden"
             $contentContainer.addClass("ui-content-scroll")

+          # if touchScroll option is not enabled, we should just
+          # adjust cotnent padding to keep space for header and footer.
           if not umobi.config.touchScroll
             AdjustContentPadding = () ->
               console.log "pagereveal", h.height(), f.height()


Adjusting soil map to work with new fitbounds function

--- public/scripts/views/SoilLocationView.coffee
+++ public/scripts/views/SoilLocationView.coffee
@@ -35,7 +35,7 @@
         View Measurements

       """)
       .addTo @markers
-      do @fitBounds
+      @fitBounds @markers

   ###
   Event handler for  clicks in leaflet popups. Open a detailed sensor view


fix howe fading

fix howe fading

--- app/vis.coffee
+++ app/vis.coffee
@@ -770,6 +770,8 @@

     parent = new THREE.Object3D()
     parent.updateMatrixWorld(true)
+    parent.scale.multiplyScalar(@scaleText)
+    @scene.add(parent)

     x = (Math.random() * 1000.0)
     y = (Math.random() * 1000.0)
@@ -777,6 +779,8 @@
     rz = Math.random() * Math.PI * 2.0
     lh = Math.random() * 150
     numlines = 0
+
+    lines = []

     for line in text
       lineobj = @getLineObject(line)
@@ -795,16 +799,19 @@
       lineobj.translateX(x)
       lineobj.translateY(y)
       numlines = numlines + 1
-      parent.add(lineobj)
-
-
-    parent.scale.multiplyScalar(@scaleText)
+      lines.push(lineobj)

     @scene.add(parent)
-    @fadeAll(parent)
-
-    bbox = @getBBox parent
-    x = bbox.center().x
-    y = bbox.center().y
-    z = bbox.center().z + @getZoomDistanceFromBox bbox, 2.5
-    @panCameraToPosition3 new THREE.Vector3(x,y,z), 1000, true
+
+    reduction = (prev, curr) =>
+      prev.then =>
+        parent.add(curr)
+        @fadeToArray(1, 1000) curr.children
+        bbox = @getBBox parent
+        x = bbox.center().x
+        y = bbox.center().y
+        z = bbox.center().z + @getZoomDistanceFromBox bbox, 2.5
+
+        return @panCameraToPosition3 new THREE.Vector3(x,y,z), 1000, true
+
+    promise = lines.reduce reduction, Promise.resolve()


Commenting options that are not available yet.

--- src/polvo/cli.coffee
+++ src/polvo/cli.coffee
@@ -13,24 +13,27 @@
     usage += "  polvo [#{'options'.green}] [#{'path'.green}]\n\n"

     usage += "#{'Examples:'}\n"
-    usage += "  polvo -n myawsomeapp   (#{'required'.red})\n"
-    usage += "  polvo -i [myawsomeapp] (#{'optional'.green})\n"
+    # usage += "  polvo -n myawsomeapp   (#{'required'.red})\n"
+    # usage += "  polvo -i [myawsomeapp] (#{'optional'.green})\n"
     usage += "  polvo -c [myawsomeapp] (#{'optional'.green})\n"
+    usage += "  polvo -cs [myawsomeapp] (#{'optional'.green})\n"
     usage += "  polvo -w [myawsomeapp] (#{'optional'.green})\n"
-    usage += "  polvo -wa [myawsomeapp] (#{'optional'.green})\n"
+    usage += "  polvo -ws [myawsomeapp] (#{'optional'.green})\n"
+    usage += "  polvo -r [myawsomeapp] (#{'optional'.green})\n"
+    usage += "  polvo -rs [myawsomeapp] (#{'optional'.green})\n"

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

-      .alias('i', 'init')
-      .describe('i', "Create a config (polvo.coffee) file for existing projects.")
+      # .alias('i', 'init')
+      # .describe('i', "Create a config (polvo.coffee) file for existing projects.")

       .alias('w', 'watch')
       .describe('w', "Start watching/compiling in dev mode.")

       .alias('c', 'compile')
-      .describe('c', "Compile project in dev mode.")
+      .describe('c', "Compile project in development mode.")

       .alias('r', 'release')
       .describe('r', "Compile project in release mode.")


added stuff to help with win condition... i think?

--- ng-modules/game.coffee
+++ ng-modules/game.coffee
@@ -39,6 +39,8 @@
         # TODO: move this...
         shopFunc = ()=>
             @scope.$broadcast('switchToModule', 'shop')
+        winFunc = ()=>
+            @scope.$broadcast('switchToModule', 'you-win')
         @locations = [
             new Location("iss", DIST_ISS, PIX_2_AU_ISS, "station", shopFunc),
             new Location("moon-maneuver", DIST_MOON_MANU, PIX_2_AU_MOON, "maneuver"),
@@ -48,7 +50,9 @@
             new Location("ceres-maneuver", DIST_CERES_MANU, PIX_2_AU_CERES, "maneuver"),
             new Location("ceres", DIST_CERES, PIX_2_AU_CERES, "station", shopFunc),
             new Location("europa-maneuver", DIST_EUROPA_MANU, PIX_2_AU_EUROPA, "maneuver"),
-            new Location("europa", DIST_EUROPA, PIX_2_AU_EUROPA, "station", shopFunc)
+            new Location("jupiter", DIST_EUROPA-DIST_MOON, PIX_2_AU_EUROPA-PIX_2_AU_MOON, "maneuver"),
+            new Location("europa", DIST_EUROPA, PIX_2_AU_EUROPA, "station", winFunc)
+            new Location("END_OF_UNIVERSE", DIST_EUROPA+DIST_ISS, PIX_2_AU_EUROPA+PIX_2_AU_ISS, "maneuver")
         ]

         @distanceTraveled = 0


Use the collections' url for the paginator

--- core/app/backbone/collections/followers.coffee
+++ core/app/backbone/collections/followers.coffee
@@ -6,7 +6,7 @@

   paginator_core:
     dataType: "json",
-    url: -> "/#{@user.get('username')}/followers"
+    url: -> @url()

   paginator_ui:
     perPage: 3


added support from adding activities from the top

--- core/app/backbone/views/activities_view.coffee
+++ core/app/backbone/views/activities_view.coffee
@@ -26,24 +26,42 @@
     @collection.each( @add, this );
     @renderChildren()

-  add: (model) ->
-    last = _.last(@childViews);
+  add: (model, collection, options) ->
+    index = options.index

-    if (last && (last.appendable(model)))
-      appendTo = last
-    else
+    appendableCandidate =
+      if index == 0
+        _.first(@childViews)
+      else
+        _.last(@childViews);
+
+    appendTo =
+      if (appendableCandidate && (appendableCandidate.appendable(model)))
+        appendableCandidate
+      else
+        @createNewAppendable(model, index)
+
+    appendTo.collection.add(model, at: index);
+
+  createNewAppendable: (model, index) ->
       appendTo = @newChildView(model)
-      @childViews.push(appendTo)
-      @appendHtml(this, appendTo)
+      if index == 0
+        @childViews.unshift(appendTo)
+      else
+        @childViews.push(appendTo)
+      @appendHtml(this, appendTo, index)
+      appendTo

-    appendTo.collection.add(model);

   beforeClose: ->
     childView.close() for childView in @childViews

-  appendHtml: (collectionView, childView) ->
+  appendHtml: (collectionView, childView, index) ->
     childView.render()
-    @$(".list").append(childView.$el)
+    if index == 0
+      @$(".list").prepend(childView.$el)
+    else
+      @$(".list").append(childView.$el)

   newChildView: (model) ->
     ch = @collection.channel


disable search_url and fetchPosts in talk-connector (currently not implemented)

--- app/assets/javascripts/components/forum-connectors/talk-connector.cjsx
+++ app/assets/javascripts/components/forum-connectors/talk-connector.cjsx
@@ -9,32 +9,34 @@

     # this method doesn't yet do anytying
     fetchPosts: (type, id, callback) ->
-      url = '/proxy/forum'
-      url += '/search.json?search=' + id
-      $.ajax
-        url: url
-        dataType: "json"
-        success: ((resp) =>
-          # console.log 'FETCHED posts: ', resp
-
-          posts = resp.topic_list?.topics ? []
-          base_url = @options.base_url
-          posts = posts.map (p) ->
-            title: p.title
-            url: base_url + '/t/' + p.slug
-            updated_at: p.last_posted_at
-          resp = {}
-          resp[type] = posts
-          callback resp
-
-        ).bind(this)
-        error: ((xhr, status, err) ->
-          console.error "Error loading posts: ", url, status, err.toString()
-        ).bind(this)
+      null
+      # url = '/proxy/forum'
+      # url += '/search.json?search=' + id
+      # $.ajax
+      #   url: url
+      #   dataType: "json"
+      #   success: ((resp) =>
+      #     # console.log 'FETCHED posts: ', resp
+      #
+      #     posts = resp.topic_list?.topics ? []
+      #     base_url = @options.base_url
+      #     posts = posts.map (p) ->
+      #       title: p.title
+      #       url: base_url + '/t/' + p.slug
+      #       updated_at: p.last_posted_at
+      #     resp = {}
+      #     resp[type] = posts
+      #     callback resp
+      #
+      #   ).bind(this)
+      #   error: ((xhr, status, err) ->
+      #     console.error "Error loading posts: ", url, status, err.toString()
+      #   ).bind(this)

     create_url: (props) ->
       url = "https://www.zooniverse.org/projects/#{@options.account_name}/old-weather-whaling/talk/subjects/#{props.subject.meta_data.zooniverse_id}/"

     # this method doesn't yet do anytying
     search_url: (term) ->
-      @options.base_url + "/search?search=#{term}"
+      # @options.base_url + "/search?search=#{term}"
+      null


add h2 ccgt to profitability table

add h2 ccgt to profitability table

--- app/assets/javascripts/lib/views/plant_profitability_table_view.coffee
+++ app/assets/javascripts/lib/views/plant_profitability_table_view.coffee
@@ -57,6 +57,7 @@
     energy_power_combined_cycle_ccs_network_gas: 'gas_ccgt_ccs'
     energy_power_combined_cycle_coal: 'coal_igcc'
     energy_power_combined_cycle_network_gas: 'gas_ccgt'
+    energy_power_combined_cycle_hydrogen: 'hydrogen_ccgt'
     energy_power_engine_diesel: 'diesel_engine'
     energy_power_engine_network_gas: 'gas_engine'
     energy_power_nuclear_gen2_uranium_oxide: 'nuclear_ii'


switched to fluid table

switched to fluid table

--- app/assets/javascripts/trade/helpers/sandbox_shipments_table.js.coffee
+++ app/assets/javascripts/trade/helpers/sandbox_shipments_table.js.coffee
@@ -57,6 +57,8 @@
   rowHeight: 30
   shipments: null
   selection: null
+  fluidTable: yes
+
   columnNames: [
       'appendix', 'speciesName', 'termCode', 'quantity', 'unitCode',
       'tradingPartner', 'countryOfOrigin', 'importPermit', 'exportPermit',
@@ -66,43 +68,43 @@
   columns: Ember.computed ->
     columnProperties =
       appendix:
-        width: 50
+        width: '4%'
         header: 'Appdx'
       speciesName:
-        width: 200
+        width: '15%'
         header: 'Species Name'
       termCode:
-        width: 50
+        width: '5%'
         header: 'Term'
       quantity:
-        width: 50
+        width: '6%'
         header: 'Qty'
       unitCode:
-        width: 50
+        width: '4%'
         header: 'Unit'
       tradingPartner:
-        width: 100
+        width: '5%'
         header: 'Trading partner'
       countryOfOrigin:
-        width: 100
+        width: '5%'
         header: 'Ctry of Origin'
       importPermit:
-        width: 150
+        width: '13%'
         header: 'Import Permit'
       exportPermit:
-        width: 150
+        width: '13%'
         header: 'Export Permit'
       originPermit:
-        width: 150
+        width: '13%'
         header: 'Origin Permit'
       purposeCode:
-        width: 50
+        width: '4%'
         header: 'Purpose'
       sourceCode:
-        width: 50
+        width: '4%'
         header: 'Source'
       year:
-        width: 50
+        width: '5%'
         header: 'Year'

     columns = @get('columnNames').map (key, index) ->
@@ -113,8 +115,8 @@
         getCellContent: (row) -> row.get(key)
         setCellContent: (row, value) -> row.set(key, value)
     deleteColumn = Ember.Table.ColumnDefinition.create
-      columnWidth: 50
-      headerCellName: 'Delete'
+      columnWidth: '4%'
+      headerCellName: 'Del'
       tableCellViewClass: 'Trade.SandboxShipmentsTable.CheckboxTableCell'
       getCellContent: (row) -> row.get('_destroyed')
       setCellContent: (row, value) ->