Fixed type compilation and printing

Fixed type compilation and printing

--- src/js/app/compilers/teascript/compiler.coffee
+++ src/js/app/compilers/teascript/compiler.coffee
@@ -712,7 +712,7 @@
       typeFn typesCompile ctx, args
     else
       arity = args.length
-      applyKindFn (new TypeConstr "[#{arity}]", kindFn arity), typesCompile ctx, args
+      applyKindFn (new TypeConstr name, kindFn arity), typesCompile ctx, args
   else
     malformed op, 'Should use a type constructor here'

@@ -2303,59 +2303,48 @@
   new ForAll kinds, (substitute quantifiedVars, type)

 star = '*'
-arrowType = new TypeConstr '->', kindFn 2
+arrowType = new TypeConstr 'Fn', kindFn 2
 arrayType = new TypeConstr 'Array', kindFn 1

-
 printType = (type) ->
-  (flattenType type) or
-    if type instanceof TypeVariable
-      type.name
-    else if type instanceof QuantifiedVar
-      type.var
-    else if type instanceof TypeConstr
-      type.name
-    else if type instanceof TypeApp
-      types = collectArgs type
-      if types.length is 1
-        types[0]
-      else
-        "(Fn #{types.join ' '})"
-    else if type instanceof ForAll
-      "(∀ #{printType type.type})"
-    else if type instanceof TempType
-      "(. #{printType type.type})"
-    else if Array.isArray type
-      "\"#{listOf type}\""
-    else if type is undefined
-      "undefined"
-    else
-      throw new Error "Unrecognized type in printType"
+  if type instanceof TypeVariable
+    type.name
+  else if type instanceof QuantifiedVar
+    type.var
+  else if type instanceof TypeConstr
+    type.name
+  else if type instanceof TypeApp
+    flattenType collectArgs type
+  else if type instanceof ForAll
+    "(∀ #{printType type.type})"
+  else if type instanceof TempType
+    "(. #{printType type.type})"
+  else if Array.isArray type
+    "\"#{listOf type}\""
+  else if type is undefined
+    "undefined"
+  else
+    throw new Error "Unrecognized type in printType"

 collectArgs = (type) ->
-  if type.op?.op?.name is '->'
-    join [printType type.op.arg], collectArgs type.arg
-  else
-    [printType type]
-
-flattenType = (type) ->
-  if type instanceof TypeConstr and match = type.name.match /^\[(\d)\]$/
-    {
-      arity: parseInt match[1]
-      types: []
-    }
-  else if type instanceof TypeApp
-    flattenedOp = flattenType type.op
-    if flattenedOp?.arity
-      if flattenedOp.arity is flattenedOp.types.length + 1
-        "[#{(join flattenedOp.types, [printType type.arg]).join ' '}]"
-      else
-        flattenedOp.types.push printType type.arg
-        flattenedOp
-    else
-      undefined
-  else
-    undefined
+  if type instanceof TypeApp
+    op = collectArgs type.op
+    arg = collectArgs type.arg
+    if (Array.isArray op) and (Array.isArray arg) and
+        op[0] is 'Fn' and arg[0] is 'Fn'
+      join op, arg[1..]
+    else
+      join (if Array.isArray op then op else [op]),
+        [if Array.isArray arg then flattenType arg else arg]
+  else
+    printType type
+
+flattenType = (types) ->
+  log types
+  if types[0].match /^\[\d+\]$/
+    "[#{types[1..].join ' '}]"
+  else
+    "(#{types.join ' '})"

 library = """
 var $listize = function (list) {


Tweaking updating display

Tweaking updating display

--- src/js/app/compilers/teascript/compiler.coffee
+++ src/js/app/compilers/teascript/compiler.coffee
@@ -1557,8 +1557,9 @@

     # Register type
     params = _terms paramTuple
+    paramNames = map _symbol, params
     ctx.declare macroName,
-      arity: (map _symbol, params)
+      arity: paramNames
       type: quantifyUnbound ctx, typeConstrainedCompile ctx, type

     #macroFn = transform call
@@ -1566,6 +1567,7 @@
       (termCompile ctx, call_ (token_ 'fn'), (join [paramTuple], rest))
     # log compiledMacro
     ctx.addMacro macroName, simpleMacro eval compiledMacro
+    params = (map token_, paramNames) # freshen

     fn_ params, call_ (token_ macroName), params

@@ -2586,10 +2588,6 @@
     # .replace(/\./g, 'dot_')
     .replace(/\&/g, 'and_')
     .replace(/\?/g, 'p_')
-    .replace(/^const$/, 'const_')
-    .replace(/^default$/, 'default_')
-    .replace(/^with$/, 'with_')
-    .replace(/^in$/, 'in_')

 # graphToWheres = (graph) ->


Fixed small issue with latency calculation in lockstep client.

--- benchmarks/framework/client/lockstep_client.coffee
+++ benchmarks/framework/client/lockstep_client.coffee
@@ -14,7 +14,7 @@

     sendOneEvent: () ->
         @currentEventStart = Date.now()
-        @socket.emit('processEvent', @event, @numSent++)
+        @socket.emit('processEvent', @event, ++@numSent)

     countEvent: (eventId) ->
         @latencySum += Date.now() - @currentEventStart


Add a _get_size method for Label

Add a _get_size method for Label

This is tricky to unit test well. Testing with the label screenshot test.

--- bokehjs/src/coffee/models/annotations/label.coffee
+++ bokehjs/src/coffee/models/annotations/label.coffee
@@ -95,6 +95,18 @@
       @_canvas_text()
     else
       @_css_text()
+
+  _get_size: () ->
+    ctx = @plot_view.canvas_view.ctx
+    @visuals.text.set_value(ctx)
+
+    side = @model.panel.side
+    if side == "above" or side == "below"
+      height = ctx.measureText(@_text[0]).ascent / 1.175
+      return height
+    if side == 'left' or side == 'right'
+      width = ctx.measureText(@_text[0]).width
+      return width

   _canvas_text: () ->
     ctx = @plot_view.canvas_view.ctx


Add async as a base dep (bower)

Add async as a base dep (bower)

--- library/membrane/preflight.coffee
+++ library/membrane/preflight.coffee
@@ -61,6 +61,7 @@
     @bower "eventemitter2"
     @bower "bootstrap#3"
     @bower "lodash"
+    @bower "async"

     # A directive to mark the certain remote class or object to be
     # included in the `Screenplay` context that is going to be emited


fix bug in worker cleanup

fix bug in worker cleanup

--- services/spelling/app/coffee/ASpellWorkerPool.coffee
+++ services/spelling/app/coffee/ASpellWorkerPool.coffee
@@ -16,7 +16,7 @@
 			return null
 		worker = new ASpellWorker(language, @options)
 		worker.pipe.on 'exit', () =>
-			@cleanup
+			@cleanup()
 		@PROCESS_POOL.push(worker)
 		return worker


Don't set config unless needed in directive

Updates mathjax directive to only set config if it is needed. The main
config is now set in base.coffee so isn't needed

--- services/web/public/coffee/directives/mathjax.coffee
+++ services/web/public/coffee/directives/mathjax.coffee
@@ -4,23 +4,16 @@
 	App.directive "mathjax", () ->
 		return {
 			link: (scope, element, attrs) ->
-				mathjaxConfig =
-					extensions: ["Safe.js"]
-					messageStyle: "none"
-					imageFont:null
-					"HTML-CSS": { availableFonts: ["TeX"] },
-					TeX:
-						equationNumbers: { autoNumber: "AMS" },
-						useLabelIDs: false
-					skipStartupTypeset: true
-					tex2jax:
-						processEscapes: true,
-						inlineMath: [ ["\\(","\\)"] ],
-						displayMath: [ ['$$','$$'], ["\\[","\\]"] ]
 				if attrs.delimiter != 'no-single-dollar'
-					mathjaxConfig.tex2jax.inlineMath.push(['$','$']);
+					inlineMathConfig = MathJax?.Hub?.config?.tex2jax.inlineMath
+					alreadyConfigured = _.find inlineMathConfig, (c) ->
+						c[0] == '$' and c[1] == '$'

-				MathJax?.Hub?.Config(mathjaxConfig);
+					if !alreadyConfigured?
+						MathJax?.Hub?.Config(
+							tex2jax:
+								inlineMath: inlineMathConfig.concat([['$', '$']])
+						)

 				setTimeout () ->
 					MathJax?.Hub?.Queue(["Typeset", MathJax?.Hub, element.get(0)])


Bind to swipe only when mouse not present

--- app/assets/javascripts/slider.js.coffee
+++ app/assets/javascripts/slider.js.coffee
@@ -48,3 +48,4 @@
       $(".slider-nav .right").click()
     swipeRight: (event, direction, distance, duration, fingerCount) ->
       $(".slider-nav .left").click()
+    fallbackToMouseEvents: false


Increase animation duration

Increase animation duration

--- app/assets/javascripts/static.js.coffee
+++ app/assets/javascripts/static.js.coffee
@@ -12,7 +12,7 @@
     $this.text(starting_point)
     $this.counter = starting_point

-    tween = createjs.Tween.get($this).to( {counter: $target_count}, 3000 )
+    tween = createjs.Tween.get($this).to( {counter: $target_count}, 10000)

     tween.addEventListener 'change', (event) ->
       $this.text(Math.round($this.counter).toString().replace(/\B(?=(\d{3})+(?!\d))/g, ","))


fix deps bug

fix deps bug

--- app/templates/gulp/tasks/scripts.coffee
+++ app/templates/gulp/tasks/scripts.coffee
@@ -2,6 +2,9 @@
 gulp = require "gulp"
 through2 = require "through2"
 helpers = require "../helpers"
+notifier = require "node-notifier"
+libpath = require "path"
+
 $ = helpers.gulpLoad [
   'if'
   'coffee'


修改上传模块时，出现两个相同的id

修改上传模块时，出现两个相同的id

--- lib/module/publish-module-view.coffee
+++ lib/module/publish-module-view.coffee
@@ -361,11 +361,12 @@
           if object is null
             return
           length = length + 1
+          module_id = $(btn2).val()
           if object.name?
             object.name = object.name #+ "(#{object.id})"
           else
             object.name = object.id #+ "(#{object.id})"
-          options = options + "

<input type='checkbox' class='hide' id='#{object.id}_#{length}' value='#{object.id}' />
#{object.name}
"
+          options = options + "

<input type='checkbox' class='hide' id='#{module_id}_#{object.id}_#{length}' value='#{object.id}' />
#{object.name}
"
         printAppList object for object in data
         options = options + "
<button name='hideAppListbtn' class='btn'>取消</button><button class='btn' name='uploadMApp'>确认</button>
"
         if length == 0


Pass message through

Pass message through

--- plugins/email/index.coffee
+++ plugins/email/index.coffee
@@ -8,10 +8,10 @@
     sidekiq = config.sidekiq
     delete config.sidekiq

-    sidekiq.enqueue SIDEKIQ_WORKER, [event.trigger.type, event.error.id, config],
+    sidekiq.enqueue SIDEKIQ_WORKER, [event.trigger.type, event.error.id, config, event.trigger.message],
       retry: false
       queue: SIDEKIQ_QUEUE

     callback null

-module.exports = Email+module.exports = Email


Slack commit

Slack commit

--- plugins/slack/index.coffee
+++ plugins/slack/index.coffee
@@ -21,13 +21,22 @@
         attachment.color = "#FD9149"
       when "info"
         attachment.color = "#20A6DF"
+    if event.comment
+      attachment.fields.push
+        title: 'Comment'
+        value: event.comment.message.truncate(80)
+
     attachment

   @receiveEvent = (config, event, callback) ->
     # Build the notification title
     projectName = event.project.name.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">")

-    if event.trigger.type == 'projectSpiking'
+    if event.trigger.type == 'comment'
+
+      title = ["#{event.user.name} commented on #{(event.error.exceptionClass + (if event.error.message then ": #{event.error.message}")).truncate(85)}"]
+      title.push("<#{event.error.url}|(details)>")
+    else if event.trigger.type == 'projectSpiking'
       title = ["Spike of #{event.trigger.rate} exceptions/minute from <#{event.project.url}|#{projectName}>"]

     else


GroupsController: Should handle the NaviagationLinkTitleClick

--- client/Main/maincontroller/groupscontroller.coffee
+++ client/Main/maincontroller/groupscontroller.coffee
@@ -15,11 +15,11 @@
     @groups           = {}
     @currentGroupData = new GroupData

-    # mainController.on 'NavigationLinkTitleClick', (pageInfo)=>
-    #   return unless pageInfo.path
-    #   if pageInfo.topLevel
-    #   then router.handleRoute "#{pageInfo.path}"
-    #   else router.handleRoute "#{pageInfo.path}", {entryPoint}
+    mainController.on 'NavigationLinkTitleClick', (pageInfo)=>
+      return unless pageInfo.path
+      if pageInfo.topLevel
+      then router.handleRoute "#{pageInfo.path}"
+      else router.handleRoute "#{pageInfo.path}", {entryPoint}

   getCurrentGroup:->
     throw 'FIXME: array should never be passed'  if Array.isArray @currentGroupData.data


unbound save queue parallelism

unbound save queue parallelism

--- test/spec/sync/relational/has_many.tests.coffee
+++ test/spec/sync/relational/has_many.tests.coffee
@@ -98,7 +98,7 @@

       # link and save all
       queue.defer (callback) ->
-        save_queue = new Queue(1)
+        save_queue = new Queue()

         link_tasks = []
         for owner in MODELS.owner


minor: code styling

minor: code styling

--- client/ide/lib/videocollaborationcontroller.coffee
+++ client/ide/lib/videocollaborationcontroller.coffee
@@ -1,5 +1,5 @@
 VideoCollaborationModel = require 'app/videocollaboration/model'
-socialHelpers = require './collaboration/helpers/social'
+socialHelpers           = require './collaboration/helpers/social'

 module.exports = VideoCollaborationController =


added missing err check

added missing err check

--- services/docstore/app/coffee/DocManager.coffee
+++ services/docstore/app/coffee/DocManager.coffee
@@ -67,6 +67,7 @@
 			return callback(error) if error?
 			return callback new Errors.NotFoundError("No such project/doc: #{project_id}/#{doc_id}") if !doc?
 			MongoManager.upsertIntoDocCollection project_id, doc_id, doc.lines, doc.rev, (error) ->
+				return callback(error) if error?
 				MongoManager.markDocAsDeleted doc_id, (error) ->
 					return callback(error) if error?
 					callback()


call callback when error returned from getign status of file

--- services/filestore/app/coffee/s3Wrapper.coffee
+++ services/filestore/app/coffee/s3Wrapper.coffee
@@ -99,6 +99,7 @@
 		request options, (err, res)->
 			if err?
 				logger.err err:err, res:res, bucketName:bucketName, key:key, "something went wrong checking file in aws"
+				return callback(err)
 			if !res?
 				logger.err err:err, res:res, bucketName:bucketName, key:key, "no response object returned when checking if file exists"
 				err = new Error("no response from s3 #{bucketName} #{key}")


fix failing spec due to model dependency

--- spec/javascripts/views/dashboard_view.spec.js.coffee
+++ spec/javascripts/views/dashboard_view.spec.js.coffee
@@ -11,10 +11,11 @@

 describe 'Results View', ->
   beforeEach ->
-    json = loadJSONFixtures 'query.json', 'queries/patient_results.json', 'users.json'
+    json = loadJSONFixtures 'query.json', 'queries/patient_results.json', 'users.json', 'submeasure.json'
     window.PopHealth.currentUser = new Thorax.Models.User $.extend(true, {}, json['users.json'][0])
     @providerId = json['queries/patient_results.json'][0].value.provider_performances[0].provider_id
-    @query = new Thorax.Models.Query $.extend(true, {}, json['query.json']), {parent: null}
+    submeasure = new Thorax.Models.Submeasure json['submeasure.json'], parse: true
+    @query = new Thorax.Models.Query $.extend(true, {}, json['query.json']), {parent: submeasure}
     @measureId = @query.get('measure_id')
     @resultsViewWithProvider = new Thorax.Views.ResultsView model: @query, id: @measureId, provider_id: @providerId
     @resultsViewWithProvider.render()


Remove note about the binding parser being non-blocking

--- src/view/binding_parser.coffee
+++ src/view/binding_parser.coffee
@@ -1,8 +1,6 @@
 #= require ../object

 # `Batman.BindingParser` will take a node and parse all recognized data attributes out of it and its children.
-# It is a continuation style parser, designed not to block for longer than 50ms at a time if the document
-# fragment is particularly long.
 class Batman.BindingParser extends Batman.Object
   constructor: (@view) ->
     super()


fix command pallete specs to reflect new classes

--- src/packages/command-palette/spec/command-palette-spec.coffee
+++ src/packages/command-palette/spec/command-palette-spec.coffee
@@ -16,15 +16,15 @@
   afterEach ->
     rootView.remove()

-  describe "when command-palette:toggle is triggered on the root view", ->
+  fdescribe "when command-palette:toggle is triggered on the root view", ->
     it "shows a list of all valid command descriptions, names, and keybindings for the previously focused element", ->
       keyBindings = _.losslessInvert(keymap.bindingsForElement(rootView.getActiveEditor()))
       for eventName, description of rootView.getActiveEditor().events()
         eventLi = palette.list.children("[data-event-name='#{eventName}']")
         if description
           expect(eventLi).toExist()
-          expect(eventLi.find('.event-name')).toHaveText(eventName)
-          expect(eventLi.find('.event-description')).toHaveText(description)
+          expect(eventLi.find('.label')).toHaveText(description)
+          expect(eventLi.find('.label').attr('title')).toBe(eventName)
           for binding in keyBindings[eventName] ? []
             expect(eventLi.find(".key-binding:contains(#{binding})")).toExist()
         else
@@ -39,8 +39,8 @@
         description = editorEvents[eventName] unless description
         if description
           expect(eventLi).toExist()
-          expect(eventLi.find('.event-name')).toHaveText(eventName)
-          expect(eventLi.find('.event-description')).toHaveText(description)
+          expect(eventLi.find('.label')).toHaveText(description)
+          expect(eventLi.find('.label').attr('title')).toBe(eventName)
         else
           expect(eventLi).not.toExist()


set period id

set period id

--- tutor/src/components/task-plan/builder/tasking-date-times.cjsx
+++ tutor/src/components/task-plan/builder/tasking-date-times.cjsx
@@ -94,7 +94,11 @@
     </BS.Col> if error

-    <BS.Col {...@props.bsSizes} className="tasking-date-times">
+    <BS.Col
+      {...@props.bsSizes}
+      className="tasking-date-times"
+      data-period-id={if period then period.id else 'all'}
+    >
       <DateTime
         {...commonDateTimesProps}
         disabled={isVisibleToStudents or not isEditable}


Check the start event again as well

Check the start event again as well

--- spec/NetworkLifecycle.coffee
+++ spec/NetworkLifecycle.coffee
@@ -211,7 +211,9 @@
         wasStarted = true
       checkEnd = ->
         chai.expect(wasStarted).to.equal true
-        if received.length <= expected.length
+        if received.length < expected.length
+          wasStarted = false
+          c.network.once 'start', checkStart
           c.network.once 'end', checkEnd
           g.addInitial 'world', 'Pc', 'in'
           return


CharCodeAt() is much faster with an int argument. - http://jsperf.com/default-to-0-vs-0/5

--- lib/algorhythmic.coffee
+++ lib/algorhythmic.coffee
@@ -15,7 +15,7 @@
       currentChar  = @getCharInt(currentChar)
       return @getNum(previousChar + currentChar)

-  getCharInt: (char) -> parseInt char.charCodeAt('0') or 0
+  getCharInt: (char) -> parseInt char.charCodeAt(0) or 0

   convert: (string) ->
     str = string.replace(/\.(png|jpg|gif|)$/g, "")


Fix old API hack

Fix old API hack

--- lib/autoprefixer.coffee
+++ lib/autoprefixer.coffee
@@ -43,12 +43,12 @@
   compile: (str, options = {}) ->
     fixed = { }
     for name, value of options
-      name == 'from' if name == 'file'
+      name = 'from' if name == 'file'
       fixed[name] = value

     console?.warn('autoprefixer: replace compile() to process(). ' +
                   'Method compile() is deprecated and will be removed in 1.1.')
-    @process(str, options).css
+    @process(str, fixed).css

   # Return PostCSS processor, which will add necessary prefixes
   postcss: (css) =>


:bug: Prevent error raised in color search

Part of the investigations for #8

--- lib/color-search.coffee
+++ lib/color-search.coffee
@@ -45,6 +45,11 @@
         # FIXME it should be handled way before, but it'll need a change
         # in how we test if a variable is a color.
         continue unless result.color?.isValid()
+        # FIXME Seems like, sometime the range of the result is undefined,
+        # we'll ignore that for now and log the faulting result.
+        unless result.range[0]?
+          console.warn "Color search returned a result with an invalid range", result
+          continue
         result.range[0][1] += result.matchText.indexOf(result.color.colorExpression)
         result.matchText = result.color.colorExpression


update scrollPastEnd for Atom 1.11 again let's see how often that particular API will change...

--- lib/console/view.coffee
+++ lib/console/view.coffee
@@ -145,7 +145,7 @@
     if @atomVersion[0] is 1 and @atomVersion[1] is 10
       item.editor.presenter.scrollPastEndOverride = false
     else if @atomVersion[0] is 1 and @atomVersion[1] >= 11
-      item.editor.setScrollPastEnd false
+      item.editor.update setScrollPastEnd: false
     item.editor.setLineNumberGutterVisible(false)
     item.editor.setSoftWrapped true
     @updateGrammar item


Fix broken image in marker indicator

Fix broken image in marker indicator

--- src/scripts/controllers/MarkerIndicator.coffee
+++ src/scripts/controllers/MarkerIndicator.coffee
@@ -45,12 +45,13 @@
       @species = species

       @circles?.remove()
-      @image.removeAttr 'src'
+      @image.css display: 'none'

       @step = -1

       if @species of @helpers
         @image.attr 'src', @helpers[@species].image
+        @image.css display: ''
         @image.one 'load', =>
           @paper.setSize @image.width(), @image.height()


fixing indentation

fixing indentation

--- src/scripts/helpers/backbone/views/base.coffee
+++ src/scripts/helpers/backbone/views/base.coffee
@@ -115,7 +115,7 @@
         appId: 940451435969487
         # Encode all of the shared values for a URI
       _.each share, (value, key, list) ->
-      list[key] = encodeURI(value)
+        list[key] = encodeURI(value)

     locationOriginPolyFillForIe: () ->


Ignore empty lines

Ignore empty lines

--- src/browser/squirrel-update.coffee
+++ src/browser/squirrel-update.coffee
@@ -64,9 +64,7 @@
 updatePath = (callback) ->
   getPath = (callback) ->
     spawnReg ['query', environmentKeyPath, '/v', 'Path'], (error, stdout) ->
-      console.log error
-      console.log stdout
-      lines = stdout.split(/[\r\n]+/)
+      lines = stdout.split(/[\r\n]+/).filter (line) -> line
       console.log lines
       segments = lines[lines.length - 1]?.split('    ')
       pathSegment = segments?[3..].join('    ')


fixing param passed to detail view

fixing param passed to detail view

--- source/javascripts/src/view_detail_mixins.coffee
+++ source/javascripts/src/view_detail_mixins.coffee
@@ -10,8 +10,8 @@
         </blockquote>
       </div>
       """
-    insertInDOM: (rowView$el)->
-      rowView$el.find(".row-content").eq(0).prepend(@$el)
+    insertInDOM: (rowView)->
+      rowView.$el.find(".row-content").eq(0).prepend(@$el)

     afterRender: ->
       @$el.find("blockquote").eq(0).editInPlace


Remove unused local variable

Remove unused local variable

--- source/server/infrastructure/commit_store.coffee
+++ source/server/infrastructure/commit_store.coffee
@@ -73,7 +73,6 @@
     @commitPublisher.publishChanges(changes, commitId)

   getEvents: (sourceId, versionOffset=1) ->
-    events = []
     withVersionOffset = {
       sourceId: sourceId.toString()
       version: $gte: versionOffset


Tabview: improvements for tabpane moving among tabs WIP

--- src/components/tabs/tabview.coffee
+++ src/components/tabs/tabview.coffee
@@ -80,7 +80,7 @@
         view       : tabHandleView
         closable   : closable
         sortable   : sortable
-        click      : (event)=> @handleMouseDownDefaultAction newTabHandle, event
+        click      : (event) => @handleClicked event, newTabHandle

       @addHandle newTabHandle

@@ -140,6 +140,8 @@
     @handles.splice index, 1

     if shouldDetach
+      @panes   = @panes.filter   (p)-> p isnt pane
+      @handles = @handles.filter (h)-> h isnt handle
       pane.detach()
       handle.detach()
     else
@@ -240,12 +242,16 @@
       @handleClicked index, event

   # DEFAULT ACTIONS
-  handleClicked:(index,event)->
-    pane = @getPaneByIndex index
-    if $(event.target).hasClass "close-tab"
+  handleClicked: (event, handle) ->
+
+    {pane} = handle.getOptions()
+
+    # fixme: make close icon a kdview and check the view instead.
+    if $(event.target).hasClass 'close-tab'
       @blockTabHandleResize = yes
       @removePane pane
       return no
+
     @showPane pane

   # DEFINE CUSTOM or DEFAULT tabHandleContainer


Fix behavior

Fix behavior

see #10


Fix leak

Fix leak

--- lib/linter-views.coffee
+++ lib/linter-views.coffee
@@ -72,8 +72,9 @@
     try @_messages.forEach (message) =>
       return unless message.currentFile
       return unless message.range?.containsPoint? point
-      @_bubble = activeEditor.decorateMarker(
-        activeEditor.markBufferRange(message.range, {invalidate: 'never'}),
+      @_bubble = activeEditor.markBufferRange(message.range, {invalidate: 'never'})
+      activeEditor.decorateMarker(
+        @_bubble
         {
           type: 'overlay',
           position: 'tail',


:bug: Fix panel visibility

:bug: Fix panel visibility

--- lib/linter-views.coffee
+++ lib/linter-views.coffee
@@ -32,7 +32,7 @@
     @subscriptions.add atom.workspace.onDidChangeActivePaneItem (paneItem) =>
       isTextEditor = paneItem?.getPath?
       @bottomContainer.setVisibility(isTextEditor)
-      @panel.visibility = @panel.visibility and isTextEditor
+      @panel.panelVisibility = atom.config.get('linter.showErrorPanel') and isTextEditor
     @subscriptions.add @linter.onDidChangeMessages =>
       @render()
     @subscriptions.add @bottomContainer.onDidChangeTab =>


:memo: Add documentation to the MinimapView

--- lib/minimap-view.coffee
+++ lib/minimap-view.coffee
@@ -7,11 +7,42 @@
 MinimapIndicator = require './minimap-indicator'
 MinimapOpenQuickSettingsView = require './minimap-open-quick-settings-view'

+# Public: A `MinimapView` instance is created for every `Editor` opened in Atom.
+# It provides delegation to many `Editor` and {MinimapRenderView} methods so
+# that in most case you can just substitute a {MinimapView} instance
+# instead of an `Editor`.
+#
+# The following methods are delegated to the {MinimapRenderView} instance:
+#
+# - [getLineHeight]{MinimapRenderView::getLineHeight}
+# - [getCharHeight]{MinimapRenderView::getCharHeight}
+# - [getCharWidth]{MinimapRenderView::getCharWidth}
+# - [getLinesCount]{MinimapRenderView::getLinesCount}
+# - [getMinimapHeight]{MinimapRenderView::getMinimapHeight}
+# - [getMinimapScreenHeight]{MinimapRenderView::getMinimapScreenHeight}
+# - [getMinimapHeightInLines]{MinimapRenderView::getMinimapHeightInLines}
+# - [getFirstVisibleScreenRow]{MinimapRenderView::getFirstVisibleScreenRow}
+# - [getLastVisibleScreenRow]{MinimapRenderView::getLastVisibleScreenRow}
+# - [pixelPositionForScreenPosition]{MinimapRenderView::pixelPositionForScreenPosition}
+# - [decorateMarker]{DecorationManagement::decorateMarker}
+# - [removeDecoration]{DecorationManagement::removeDecoration}
+# - [decorationsForScreenRowRange]{DecorationManagement::decorationsForScreenRowRange}
+# - [removeAllDecorationsForMarker]{DecorationManagement::removeAllDecorationsForMarker}
+#
+# The following methods are delegated to the `Editor` instance:
+#
+# - getSelection
+# - getSelections
+# - getLastSelection
+# - bufferRangeForBufferRow
+# - getTextInBufferRange
+# - getEofBufferPosition
+# - scanInBufferRange
+# - markBufferRange
 module.exports =
 class MinimapView extends View
   Debug('minimap').includeInto(this)
   Delegato.includeInto(this)
-

   @delegatesMethods 'getLineHeight', 'getCharHeight', 'getCharWidth', 'getLinesCount', 'getMinimapHeight', 'getMinimapScreenHeight', 'getMinimapHeightInLines', 'getFirstVisibleScreenRow', 'getLastVisibleScreenRow', 'pixelPositionForScreenPosition', 'decorateMarker', 'removeDecoration', 'decorationsForScreenRowRange', 'removeAllDecorationsForMarker', toProperty: 'renderView'

@@ -32,8 +63,19 @@

   isClicked: false

-  # VIEW CREATION/DESTRUCTION
-
+  ### Public ###
+
+  #    #### ##    ## #### ########
+  #     ##  ###   ##  ##     ##
+  #     ##  ####  ##  ##     ##
+  #     ##  ## ## ##  ##     ##
+  #     ##  ##  ####  ##     ##
+  #     ##  ##   ###  ##     ##
+  #    #### ##    ## ####    ##
+
+  # Creates a new {MinimapView}.
+  #
+  # editorView - The `EditorView` for which displaying a minimap.
   constructor: (@editorView) ->
     @editor = @editorView.getEditor()
     @paneView = @editorView.getPaneView()
@@ -60,6 +102,8 @@

     @updateMinimapView()

+  # Internal: Initializes the minimap view by registering to various events and
+  # by retrieving the base configuration.
   initialize: ->
     @on 'mousewheel', @onMouseWheel
     @on 'mousedown', @onMouseDown
@@ -103,20 +147,23 @@
       newOptionValue = atom.config.get 'minimap.displayCodeHighlights'
       @setDisplayCodeHighlights(newOptionValue)

+  # Internal: Computes the scale of the minimap display relatively to the
+  # corresponding editor view.
+  # The scale factor are used to map scrolling and offset from the minimap
+  # to the editor and vice versa.
   computeScale: ->
     originalLineHeight = parseInt(@editorView.find('.lines').css('line-height'))
     computedLineHeight = @getLineHeight()

     @scaleX = @scaleY = computedLineHeight / originalLineHeight

+  # Internal: Adjusts the position of the minimap so that it sticks to the
+  # editor view offset. This is needed as the minimap is positioned absolutely
+  # and the tree-view, or other packages, may affect the editor view position.
   adjustTopPosition: ->
     @offset top: (@offsetTop = @editorView.offset().top)

-  setDisplayCodeHighlights: (value) ->
-    if value isnt @displayCodeHighlights
-      @displayCodeHighlights = value
-      @renderView.forceUpdate()
-
+  # Destroys this view and release all its subobjects.
   destroy: ->
     @paneView.removeClass('with-minimap')
     @off()
@@ -128,76 +175,64 @@
     @renderView.destroy()
     @remove()

-  # MINIMAP DISPLAY MANAGEMENT
-
+  #    ########  ####  ######  ########  ##          ###    ##    ##
+  #    ##     ##  ##  ##    ## ##     ## ##         ## ##    ##  ##
+  #    ##     ##  ##  ##       ##     ## ##        ##   ##    ####
+  #    ##     ##  ##   ######  ########  ##       ##     ##    ##
+  #    ##     ##  ##        ## ##        ##       #########    ##
+  #    ##     ##  ##  ##    ## ##        ##       ##     ##    ##
+  #    ########  ####  ######  ##        ######## ##     ##    ##
+
+  # Toggles the display of the code highlights rendering.
+  #
+  # value - A {Boolean} of whether to render the code highlights or not.
+  setDisplayCodeHighlights: (value) ->
+    if value isnt @displayCodeHighlights
+      @displayCodeHighlights = value
+      @renderView.forceUpdate()
+
+  # Internal: Attaches the minimap view to the DOM.
   attachToPaneView: ->
     @paneView.append(this)
     @adjustTopPosition()

+  # Internal: Detaches the minimap view to the DOM.
   detachFromPaneView: ->
     @detach()

+  # Returns `true` when the minimap is actually attached to the DOM.
+  #
+  # Returns a {Boolean}.
   minimapIsAttached: -> @paneView.find('.minimap').length is 1

-  # EDITOR VIEW MANAGEMENT
-
-  unsubscribeFromEditor: ->
-    @unsubscribe @editor, '.minimap' if @editor?
-    @unsubscribe @scrollView, '.minimap' if @scrollView?
-
-  subscribeToEditor: ->
-    @subscribe @editor, 'scroll-top-changed.minimap', @updateScrollY
-    # Hacked scroll-left
-    @subscribe @scrollView, 'scroll.minimap', @updateScrollX
-
+  # Internal: Returns the bounds of the `EditorView`.
+  #
+  # Returns an {Object}.
   getEditorViewClientRect: -> @scrollView[0].getBoundingClientRect()

+  # Internal: Returns the bounds of the editor `ScrollView`.
+  #
+  # returns an {Object}.
   getScrollViewClientRect: -> @scrollViewLines[0].getBoundingClientRect()

+  # Returns the bounds of the minimap.
+  #
+  # Returns an {Object}
   getMinimapClientRect: -> @[0].getBoundingClientRect()

-  # UPDATE METHODS
-
-  updateMinimapRenderView: => @renderView.update()
-
-  updateMinimapSize: =>
-    return unless @indicator?
-
-    {width, height} = @getMinimapClientRect()
-    editorViewRect = @getEditorViewClientRect()
-    miniScrollViewRect = @renderView.getClientRect()
-
-    evw = editorViewRect.width
-    evh = editorViewRect.height
-
-    minimapVisibilityRatio = miniScrollViewRect.height / height
-
-    @miniScroller.height(evh / minimapVisibilityRatio)
-    @miniScroller.toggleClass 'visible', minimapVisibilityRatio > 1 and @miniScrollVisible
-
-    @miniWrapper.css {width}
-
-    # VisibleArea's size
-    @indicator.height = evh * @scaleY
-    @indicator.width = width / @scaleX
-
-    @miniVisibleArea.css
-      width : width / @scaleX
-      height: evh * @scaleY
-
-    msvw = miniScrollViewRect.width || 0
-    msvh = miniScrollViewRect.height || 0
-
-    # Minimap's size
-    @indicator.setWrapperSize width, Math.min(height, msvh)
-
-    # Minimap ScrollView's size
-    @indicator.setScrollerSize msvw, msvh
-
-    # Compute boundary
-    @indicator.updateBoundary()
-
-
+  #    ##     ## ########  ########     ###    ######## ########
+  #    ##     ## ##     ## ##     ##   ## ##      ##    ##
+  #    ##     ## ##     ## ##     ##  ##   ##     ##    ##
+  #    ##     ## ########  ##     ## ##     ##    ##    ######
+  #    ##     ## ##        ##     ## #########    ##    ##
+  #    ##     ## ##        ##     ## ##     ##    ##    ##
+  #     #######  ##        ########  ##     ##    ##    ########
+
+  # Updates the minimap view.
+  #
+  # The size, scrolling and view area are updated as well as the
+  # {MinimapRenderView} if the minimap own scrolling is changed during
+  # the update.
   updateMinimapView: =>
     return unless @editorView
     return unless @indicator
@@ -210,6 +245,51 @@
       @updateScroll()
       @frameRequested = false

+  # Calls the `update` method of the {MinimapRenderView}.
+  updateMinimapRenderView: => @renderView.update()
+
+  # Internal: Updates the size of the minimap according to the new
+  # size of the editor.
+  updateMinimapSize: =>
+    return unless @indicator?
+
+    {width, height} = @getMinimapClientRect()
+    editorViewRect = @getEditorViewClientRect()
+    miniScrollViewRect = @renderView.getClientRect()
+
+    evw = editorViewRect.width
+    evh = editorViewRect.height
+
+    minimapVisibilityRatio = miniScrollViewRect.height / height
+
+    @miniScroller.height(evh / minimapVisibilityRatio)
+    @miniScroller.toggleClass 'visible', minimapVisibilityRatio > 1 and @miniScrollVisible
+
+    @miniWrapper.css {width}
+
+    # VisibleArea's size
+    @indicator.height = evh * @scaleY
+    @indicator.width = width / @scaleX
+
+    @miniVisibleArea.css
+      width : width / @scaleX
+      height: evh * @scaleY
+
+    msvw = miniScrollViewRect.width || 0
+    msvh = miniScrollViewRect.height || 0
+
+    # Minimap's size
+    @indicator.setWrapperSize width, Math.min(height, msvh)
+
+    # Minimap ScrollView's size
+    @indicator.setScrollerSize msvw, msvh
+
+    # Compute boundary
+    @indicator.updateBoundary()
+
+  # Internal: Updates the vertical scrolling of the minimap.
+  #
+  # top - The scroll top offset {Number}.
   updateScrollY: (top) =>
     # Need scroll-top value when in find pane or on Vim mode(`gg`, `shift+g`).
     # Or we can find a better solution.
@@ -223,15 +303,20 @@
     @indicator.setY(overlayY * @scaleY)
     @updatePositions()

+  # Internal: Updates the horizontal scrolling of the minimap.
   updateScrollX: =>
     @indicator.setX(@scrollView[0].scrollLeft)
     @updatePositions()

+  # Internal: Updates the scroll of the minimap both horizontally and
+  # vertically.
   updateScroll: =>
     @indicator.setX(@scrollView[0].scrollLeft)
     @updateScrollY()
     @trigger 'minimap:scroll'

+  # Internal: Updates the position of the various elements of the minimap
+  # after a scroll changes.
   updatePositions: ->
     @transform @miniVisibleArea[0], @translate(0, @indicator.y)
     @renderView.scrollTop(@indicator.scroller.y * -1)
@@ -243,6 +328,7 @@

     @updateScrollerPosition()

+  # Internal: Updates the position of the scroller indicator of the minimap.
   updateScrollerPosition: ->
     height = @miniScroller.height()
     totalHeight = @height()
@@ -251,8 +337,31 @@

     @transform @miniScroller[0], @translate(0, @indicator.ratioY * scrollRange)

-  # EVENT CALLBACKS
-
+  #    ######## ##     ## ######## ##    ## ########  ######
+  #    ##       ##     ## ##       ###   ##    ##    ##    ##
+  #    ##       ##     ## ##       ####  ##    ##    ##
+  #    ######   ##     ## ######   ## ## ##    ##     ######
+  #    ##        ##   ##  ##       ##  ####    ##          ##
+  #    ##         ## ##   ##       ##   ###    ##    ##    ##
+  #    ########    ###    ######## ##    ##    ##     ######
+
+  ### Internal ###
+
+  # Internal: Subscribes from the `Editor events`.
+  subscribeToEditor: ->
+    @subscribe @editor, 'scroll-top-changed.minimap', @updateScrollY
+    # Hacked scroll-left
+    @subscribe @scrollView, 'scroll.minimap', @updateScrollX
+
+  # Internal: Unsubscribes from the `Editor events`.
+  unsubscribeFromEditor: ->
+    @unsubscribe @editor, '.minimap' if @editor?
+    @unsubscribe @scrollView, '.minimap' if @scrollView?
+
+  # Event callbacks called when the active editor of a pane view
+  # is changed.
+  #
+  # activeItem - The newly activated pane item.
   onActiveItemChanged: (activeItem) =>
     if activeItem is @editor
       @attachToPaneView() if @parent().length is 0


Changes editor scroll event registrations to subscriptions

Now, the unsubscribe call can also removes these subscriptions.

--- lib/minimap-view.coffee
+++ lib/minimap-view.coffee
@@ -78,10 +78,11 @@
     @scrollViewLines = @scrollView.find('.lines')

     # current editor bind scrollTop event
-    @editor.off 'scroll-top-changed.editor'
-    @editor.on 'scroll-top-changed.editor', @updateScroll
-    @editor.off 'scroll-left-changed.editor'
-    @editor.on 'scroll-left-changed.editor', @updateScroll
+    @unsubscribe @editor, 'scroll-top-changed.editor'
+    @unsubscribe @editor, 'scroll-left-changed.editor'
+
+    @subscribe @editor, 'scroll-top-changed.editor', @updateScroll
+    @subscribe @editor, 'scroll-left-changed.editor', @updateScroll

   getEditorView: -> @paneView.viewForItem(@activeItem)


Removed the debugger

Removed the debugger

--- src/gdn/v1/static/formatter.coffee
+++ src/gdn/v1/static/formatter.coffee
@@ -1,4 +1,3 @@
-
 # Original function by http://joncom.be/code/javascript-json-formatter/

 RealTypeOf = (v) ->
@@ -65,6 +64,5 @@
 	# return
 	return sHTML

-debugger
 elem = document.getElementById("js-code")
-elem.innerHTML = formatJSON(JSON.parse(elem.innerHTML))+elem.innerHTML = formatJSON(JSON.parse(elem.innerHTML))


Add rmosolgo's test.

Add rmosolgo's test.

--- tests/batman/controller/controller_test.coffee
+++ tests/batman/controller/controller_test.coffee
@@ -155,6 +155,11 @@
   @controller.redirect '/'
   ok Batman.navigator.redirect.called

+test 'redirecting with an object should add the current controller if not present', ->
+  Batman.navigator = {redirect: createSpy()}
+  @controller.redirect(action: 'show')
+  ok Batman.navigator.redirect.lastCallArguments = [{action: "show", controller: "test_controller"}]
+
 test 'filters specifying no restrictions should be called on all actions', ->
   spy = createSpy()
   class FilterController extends Batman.Controller


Randomize rental lengths and start times, check against quantity ordered.

--- tests/jasmine/server/integration/orders.coffee
+++ tests/jasmine/server/integration/orders.coffee
@@ -7,19 +7,51 @@
     it 'should reserve dates requested', (done) ->
       product = Factory.create 'rentalProduct'
       variant = product.variants[0]
+      daysTilRental = _.random 7, 30
+      rentalLength = _.random 1, 14
+      quantity = 1
       order = Factory.create 'rentalOrder', {
-        startTime: new Date('2015-09-22T06:00:00.000Z'),
-        endTime: new Date('2015-09-27T06:00:00.000Z'),
+        startTime: moment().startOf('day').add(daysTilRental, 'days').toDate(),
+        endTime: moment().startOf('day').add(
+          daysTilRental + rentalLength, 'days').toDate(),
         items: [
           _id: Random.id()
           productId: product._id
           variants: variant
-          quantity: 1
+          quantity: quantity
         ]
       }
+
+      preInventoryAvailable = Meteor.call(
+        'checkInventoryAvailability',
+        product._id,
+        variant._id,
+        {
+          startTime: moment().startOf('day').add(
+            daysTilRental, 'days').toDate(),
+          endTime: moment().startOf('day').add(
+            daysTilRental + rentalLength, 'days').toDate()
+        },
+        quantity)

       Meteor.call 'rentalInventoryAdjust', order._id
       product = Products.findOne(product._id)
       variant = product.variants[0]
-      expect(variant.unavailableDates.length).toEqual 6
+      expect(variant.unavailableDates.length).toEqual (rentalLength + 1)
+
+      postInventoryAvailable = Meteor.call(
+        'checkInventoryAvailability',
+        product._id,
+        variant._id,
+        {
+          startTime: moment().startOf('day').add(
+            daysTilRental, 'days').toDate(),
+          endTime: moment().startOf('day').add(
+            daysTilRental + rentalLength, 'days').toDate()
+        },
+        quantity)
+
+      expect(postInventoryAvailable.length + quantity).toEqual(
+        preInventoryAvailable.length)
+
       done()


add plot pane and workspace to julia menu

--- lib/package/menu.coffee
+++ lib/package/menu.coffee
@@ -51,6 +51,11 @@

       {type: 'separator'}

+      {label: 'Open Plot Pane', command: 'julia-client:open-plot-pane'}
+      {label: 'Open Workspace', command: 'julia-client:open-workspace'}
+
+      {type: 'separator'}
+
       {label: 'Settings...', command: 'julia-client:settings'}
     ]
   }]


fix(remove-from-view): Missing invocation for non-Gmail

--- internal_packages/thread-list/lib/thread-list.cjsx
+++ internal_packages/thread-list/lib/thread-list.cjsx
@@ -56,7 +56,8 @@
     Actions.setFocus(collection: 'thread', item: item)

   _keymapHandlers: ->
-    'application:remove-from-view': => @_onRemoveFromView
+    'application:remove-from-view': =>
+      @_onRemoveFromView()
     'application:gmail-remove-from-view': =>
       @_onRemoveFromView(CategoryRemovalTargetRulesets.Gmail)
     'application:archive-item': @_onArchiveItem


Wait for hdfs before running client test

--- hdp/hdfs_client.coffee
+++ hdp/hdfs_client.coffee
@@ -34,8 +34,12 @@
 module.exports.push name: 'HDP HDFS Client # Check', timeout: -1, callback: (ctx, next) ->
   {hadoop_conf_dir, hdfs_site} = ctx.config.hdp
   port = hdfs_site['dfs.datanode.address']?.split('.')[1] or 1019
-  datanodes = ctx.hosts_with_module 'phyla/hdp/hdfs_dn'
-  ctx.waitForConnection datanodes, port, (err) ->
+  # # DataNodes must all be started
+  # datanodes = ctx.hosts_with_module 'phyla/hdp/hdfs_dn'
+  # ctx.waitForConnection datanodes, port, (err) ->
+  #   return next err if err
+  # User "test" should be created
+  ctx.waitForExecution "hdfs dfs -test -d /user/test", (err) ->
     return next err if err
     ctx.execute
       cmd: mkcmd.test ctx, """


fix hash jump

fix hash jump

--- src/scripts/modules/media/body/body.coffee
+++ src/scripts/modules/media/body/body.coffee
@@ -449,8 +449,7 @@
           @fragmentReloaded = true

           hash = window.location.hash
-          window.location.hash = ''
-          window.location.hash = hash
+          window.location.replace(hash)

       $target = $(window.location.hash)
       if $target.prop('tagName')?.toLowerCase() is 'iframe'


Tweak Atom config

Tweak Atom config

--- home/.atom/config.cson
+++ home/.atom/config.cson
@@ -3,6 +3,7 @@
     autoloadPaths: [
       "vendor/autoload.php"
     ]
+    binComposer: "composer"
     classMapFiles: [
       "vendor/composer/autoload_classmap.php"
     ]


Use a method to get the current file path

--- lib/python-isort.coffee
+++ lib/python-isort.coffee
@@ -27,11 +27,13 @@
       statusBarElement.removeClass("text-error")

     statusBarElement.text(message)
+
+  getFilePath: ->
     editor = atom.workspace.getActiveEditor()
-    filePath = editor.getPath()
+    return editor.getPath()

-    params = [filePath, "-c"]
     isortpath = atom.config.get "python-isort.isortpath"
+    params = [@getFilePath(), "-c", "-vb"]

     if not fs.existsSync(isortpath)
       @updateStatusbarText("unable to open " + isortpath, false)
@@ -49,10 +51,8 @@
   sortImports: ->
     if not @checkForPythonContext
       return
-    editor = atom.workspace.getActiveEditor()
-    filePath = editor.getPath()

-    params = [filePath, "-vb"]
+    params = [@getFilePath(), "-vb"]
     isortpath = atom.config.get "python-isort.isortpath"

     if not fs.existsSync(isortpath)


Added verbose check

Added verbose check

--- source/Commander.coffee
+++ source/Commander.coffee
@@ -10,6 +10,10 @@
 # Fetch arguments
 components = require('minimist')(process.argv.slice(2))

+# Check verbose mode
+winston.level = 'error'
+winston.level = 'info' if components['verbose']
+
 # Combine arguments to single string
 specs = components['_'].join(' ')


rename callback methods to be more specific

--- tutor/src/components/course-calendar/month.cjsx
+++ tutor/src/components/course-calendar/month.cjsx
@@ -87,7 +87,7 @@
     calendarWeeks = calendarDuration.split(1, 'week')
     {calendarDuration, calendarWeeks}

-  handleClick: (dayMoment, mouseEvent) ->
+  handleDayClick: (dayMoment, mouseEvent) ->
     @refs.addOnDay.updateState(dayMoment, mouseEvent.pageX, mouseEvent.pageY)
     @setState({
       activeAddDate: dayMoment
@@ -135,7 +135,7 @@
       ".course-plan-#{@state.editingPlanId}"
     )

-  onHover: (day) ->
+  onDragHover: (day) ->
     @setState(hoveredDay: day)

   onSidebarToggle: (isOpen) ->
@@ -151,8 +151,8 @@
       {
         component: [ 'day' ],
         events:
-          onClick: @handleClick
-          onDragEnter: @onHover
+          onClick: @handleDayClick
+          onDragEnter: @onDragHover
       }
     ]


added missing socket for disconnetion

added missing socket for disconnetion

--- lib/socketServer.coffee
+++ lib/socketServer.coffee
@@ -53,7 +53,7 @@

         socket.on 'disconnect', ->
           console.log 'disconnect'
-          @emit types.clientDisconnected
+          @emit types.clientDisconnected, socket

         socket.on 'data', (transform) =>
           switch transform.type


firefox -- found missing "event" object, which causes javascript errors when browsing project listing.

--- salvus/page/project.coffee
+++ salvus/page/project.coffee
@@ -352,7 +352,7 @@
             if (event.metaKey or event.ctrlKey) and event.keyCode == 79
                 @display_tab("project-editor")
                 return false
-            @update_file_search()
+            @update_file_search(event)

     clear_file_search: () =>
         @_file_search_box.val('')
@@ -361,7 +361,7 @@
         if not IS_MOBILE
             @_file_search_box.focus()

-    update_file_search: () =>
+    update_file_search: (event) =>
         search_box = @_file_search_box
         include = 'project-listing-search-include'
         exclude = 'project-listing-search-exclude'
@@ -393,7 +393,7 @@
             fullpath = entry.data('name')
             filename = misc.path_split(fullpath).tail
             if match(filename, entry.hasClass('project-directory-link'))
-                if first and event.keyCode == 13 # enter -- select first match (if any)
+                if first and event?.keyCode == 13 # enter -- select first match (if any)
                     entry.click()
                     first = false
                 if v != ""
@@ -401,7 +401,7 @@
             else
                 if v != ""
                     entry.addClass(exclude); entry.removeClass(include)
-        if first and event.keyCode == 13
+        if first and event?.keyCode == 13
             # No matches at all, and user pressed enter -- maybe they want to create a file?
             @display_tab("project-new-file")
             @new_file_tab_input.val(search_box.val())


delete some console.log messages...

delete some console.log messages...

--- salvus/page/syncdoc.coffee
+++ salvus/page/syncdoc.coffee
@@ -877,14 +877,14 @@
                                 log("BUG: error rendering output: '#{s}' -- #{e}")

             else if x.indexOf(MARKERS.output) != -1
-                console.log("correcting merge/paste issue with output marker line (line=#{line})")
+                #console.log("correcting merge/paste issue with output marker line (line=#{line})")
                 ch = x.indexOf(MARKERS.output)
                 cm.replaceRange('\n', {line:line, ch:ch})
                 @process_sage_updates(line)
                 return

             else if x.indexOf(MARKERS.cell) != -1
-                console.log("correcting merge/paste issue with cell marker (line=#{line})")
+                #console.log("correcting merge/paste issue with cell marker (line=#{line})")
                 ch = x.indexOf(MARKERS.cell)
                 cm.replaceRange('\n', {line:line, ch:ch})
                 @process_sage_updates(line)
@@ -898,7 +898,6 @@

     # hide_input: hide input part of cell that has start marker at the given line.
     hide_input: (line) =>
-        console.log("hide_input 0")
         end = line+1
         cm = @codemirror
         while end < cm.lineCount()


852: Made recipient_ids show/hide based on recipient_selection

--- app/assets/javascripts/backbone/views/broadcasts_view.js.coffee
+++ app/assets/javascripts/backbone/views/broadcasts_view.js.coffee
@@ -3,15 +3,21 @@

   initialize: ->
     @medium_changed()
+    @recipient_selection_changed()
     @$("#broadcast_recipient_ids").select2()

   events:
     'change #broadcast_medium': 'medium_changed'
+    'change #broadcast_recipient_selection': 'recipient_selection_changed'
     'keyup #broadcast_body': 'update_char_limit'
+
+  recipient_selection_changed: (e) ->
+    specific = @$('#broadcast_recipient_selection').val() == 'specific_users'
+    @$('.form_field.broadcast_recipient_ids')[if specific then 'show' else 'hide']()

   medium_changed: (e) ->
     selected = @$('#broadcast_medium').val()
-    sms_possible = selected != "email_only" && selected != ""
+    sms_possible = selected != 'email_only' && selected != ''

     # Hide/show char limit and subject
     if sms_possible


check both bounds for resizing after cropping

--- app/assets/javascripts/uploadcare/ui/crop/crop-widget.js.coffee
+++ app/assets/javascripts/uploadcare/ui/crop/crop-widget.js.coffee
@@ -101,8 +101,10 @@
           if notTouched and not @__options.scale
             opts.modifiers = ''
           else
-            downscale = @__options.scale and coords.width > @__options.preferedSize[0]
-            upscale = @__options.upscale and coords.width < @__options.preferedSize[0]
+            [pw, ph] = @__options.preferedSize
+            downscale = @__options.scale and (coords.width > pw or coords.height > ph)
+            upscale = @__options.upscale and (coords.width < pw or coords.height < ph)
+
             if downscale or upscale
               resized = @__options.preferedSize
             else


Shift the initial @fromDate to be the Monday 2 weeks prior to the actual day.

--- app/assets/javascripts/views/_shared/date_driven_view.js.coffee
+++ app/assets/javascripts/views/_shared/date_driven_view.js.coffee
@@ -1,13 +1,13 @@
 class window.StaffPlan.Views.Shared.DateDrivenView extends Support.CompositeView
   initialize: ->
-    today = new XDate()
-    if today.getDay() == 1
-      today = today.addDays(-5)
-    else if today.getDay() > 2
-      while today.getDay() >= 2
-        today = today.addDays( -1 )
-
-    @fromDate = today
+    today = new XDate().addDays(5)
+    if today.getDay() == 0 # sunday
+      today = today.addDays(-6)
+    else if today.getDay() > 1
+      while today.getDay() > 1
+        today = today.addDays(-1)
+
+    @fromDate = today.addWeeks(-2) # move back two weeks to start

     setTimeout =>
       $( window ).bind 'resize', @onWindowResized


call reset riboon on route change

call reset riboon on route change

--- BackofficeBundle/Resources/public/coffee/backboneRouter.coffee
+++ BackofficeBundle/Resources/public/coffee/backboneRouter.coffee
@@ -34,12 +34,12 @@
     if link.length == 0
       Backbone.history.navigate('', {trigger: true})
       return false
+    OpenOrchestra.RibbonButton.ribbonFormButtonView.resetAll('.ribbon-form-button')
     @afterRouteChanges(selector)
     displayLoader()
     return true

   afterRouteChanges: (selector) ->
-    OpenOrchestra.RibbonButton.ribbonFormButtonView.resetAll('.ribbon-form-button')
     $('#left-panel nav li:has(a' + selector + ')').addClass 'active'
     $('#left-panel nav li.current').removeClass 'current'
     $('#left-panel nav li:has(>a' + selector + ')').addClass 'current'


fixed auto completion

fixed auto completion

--- settings/language-sqf.cson
+++ settings/language-sqf.cson
@@ -3,8 +3,8 @@
     'commentStart': '// '
     'increaseIndentPattern': '^\\s*(else|elseif|for|(local\\s+)?function|if|repeat|until|while)\\b((?!end).)*$|\\{\\s*$'
     'decreaseIndentPattern': '^\\s*(else|end|\\})\\s*'
-    # Generated from https://community.bistudio.com/wiki/Category:Scripting_Commands_Arma_3
     'completions': [
+        # Generated from https://community.bistudio.com/wiki/Category:Scripting_Commands_Arma_3
         '_forEachIndex',
         '_this',
         '_x',
@@ -1806,13 +1806,8 @@
         'worldSize',
         'worldToModel',
         'worldToModelVisual',
-        'worldToScreen'
-
-    ]
-
-'.source.sqf .string.quoted':
-  'editor':
-    'completions': [
+        'worldToScreen',
+
         'CfgMods',
         'CfgExperience',
         'CfgAISkill',
@@ -1938,8 +1933,7 @@
         'CfgSecOps',
         'CfgOO',
         'CfgTalkSentences_E',
-
-      # Generated from https://community.bistudio.com/wiki/Arma_3:_Event_Handlers
+        # Generated from https://community.bistudio.com/wiki/Arma_3:_Event_Handlers
         'AnimChanged',
         'AnimDone',
         'AnimStateChanged',
@@ -2015,12 +2009,8 @@
         'Action',
         'NextAction',
         'MusicStart',
-        'MusicStop'
-    ]
-
-'.source.sqf':
-  'editor':
-    'completions': [
+        'MusicStop',
+
         # default Macros
         '#include',
         '#define',


Attempt to pass last failing test

Attempt to pass last failing test

--- test/spec/test_reactive.coffee
+++ test/spec/test_reactive.coffee
@@ -100,8 +100,8 @@
     it 'should have the set attributes', ->
       expect(elt.getAttribute('x')).toBe('10')
     it 'should have the given child contents', ->
-      cont = elt.contents()
-      child = cont.last()
+      cont = elt.childNodes()
+      child = cont[0]
       expect(cont.length).toBe(1)
       expect(cont.last().is('animatetransform')).toBe(true)


:white_check_mark: for `z u` and `z space` and cleanup spec

--- spec/scroll-spec.coffee
+++ spec/scroll-spec.coffee
@@ -47,7 +47,15 @@
         expect(editor.getFirstVisibleScreenRow()).toBe 1
         expect(editor.getLastVisibleScreenRow()).toBe 6

-  describe "scroll cursor keybindings", ->
+  describe "redraw-cursor-line keybindings", ->
+    _ensure = (keystroke, {scrollTop, moveToFirstChar}) ->
+      ensure(keystroke)
+      expect(editorElement.setScrollTop).toHaveBeenCalledWith(scrollTop)
+      if moveToFirstChar
+        expect(editor.moveToFirstCharacterOfLine).toHaveBeenCalled()
+      else
+        expect(editor.moveToFirstCharacterOfLine).not.toHaveBeenCalled()
+
     beforeEach ->
       editor.setText [1..200].join("\n")
       editorElement.style.lineHeight = "20px"
@@ -61,41 +69,18 @@
       spyOn(editor, 'getLastVisibleScreenRow').andReturn(110)
       spyOn(editorElement, 'pixelPositionForScreenPosition').andReturn({top: 1000, left: 0})

-    describe "the z<CR> keybinding", ->
-      it "moves the screen to position cursor at the top of the window and moves cursor to first non-blank in the line", ->
-        ensure 'z enter'
-        expect(editorElement.setScrollTop).toHaveBeenCalledWith(960)
-        expect(editor.moveToFirstCharacterOfLine).toHaveBeenCalled()
-
-    describe "the zt keybinding", ->
-      it "moves the screen to position cursor at the top of the window and leave cursor in the same column", ->
-        ensure 'z t'
-        expect(editorElement.setScrollTop).toHaveBeenCalledWith(960)
-        expect(editor.moveToFirstCharacterOfLine).not.toHaveBeenCalled()
-
-    describe "the z. keybinding", ->
-      it "moves the screen to position cursor at the center of the window and moves cursor to first non-blank in the line", ->
-        ensure 'z .'
-        expect(editorElement.setScrollTop).toHaveBeenCalledWith(900)
-        expect(editor.moveToFirstCharacterOfLine).toHaveBeenCalled()
-
-    describe "the zz keybinding", ->
-      it "moves the screen to position cursor at the center of the window and leave cursor in the same column", ->
-        ensure 'z z'
-        expect(editorElement.setScrollTop).toHaveBeenCalledWith(900)
-        expect(editor.moveToFirstCharacterOfLine).not.toHaveBeenCalled()
-
-    describe "the z- keybinding", ->
-      it "moves the screen to position cursor at the bottom of the window and moves cursor to first non-blank in the line", ->
-        ensure 'z -'
-        expect(editorElement.setScrollTop).toHaveBeenCalledWith(860)
-        expect(editor.moveToFirstCharacterOfLine).toHaveBeenCalled()
-
-    describe "the zb keybinding", ->
-      it "moves the screen to position cursor at the bottom of the window and leave cursor in the same column", ->
-        ensure 'z b'
-        expect(editorElement.setScrollTop).toHaveBeenCalledWith(860)
-        expect(editor.moveToFirstCharacterOfLine).not.toHaveBeenCalled()
+    describe "at top", ->
+      it "without move cursor", ->   _ensure 'z t',     scrollTop: 960, moveToFirstChar: false
+      it "with move to 1st char", -> _ensure 'z enter', scrollTop: 960, moveToFirstChar: true
+    describe "at upper-middle", ->
+      it "without move cursor", ->   _ensure 'z u',     scrollTop: 950, moveToFirstChar: false
+      it "with move to 1st char", -> _ensure 'z space', scrollTop: 950, moveToFirstChar: true
+    describe "at middle", ->
+      it "without move cursor", ->   _ensure 'z z',     scrollTop: 900, moveToFirstChar: false
+      it "with move to 1st char", -> _ensure 'z .',     scrollTop: 900, moveToFirstChar: true
+    describe "at bottom", ->
+      it "without move cursor", ->   _ensure 'z b',     scrollTop: 860, moveToFirstChar: false
+      it "with move to 1st char", -> _ensure 'z -',     scrollTop: 860, moveToFirstChar: true

   describe "horizontal scroll cursor keybindings", ->
     beforeEach ->


Fixed bug: .focus() on searchable select won't focus visible input field.

--- app/assets/javascripts/app/lib/app_post/searchable_select.coffee
+++ app/assets/javascripts/app/lib/app_post/searchable_select.coffee
@@ -4,6 +4,7 @@
     'input .js-input':       'onInput'
     'blur .js-input':        'onBlur'
     'focus .js-input':       'onFocus'
+    'focus .js-shadow':      'onShadowFocus'
     'click .js-option':      'selectItem'
     'click .js-enter':       'navigateIn'
     'click .js-back':        'navigateOut'
@@ -351,6 +352,10 @@
     @input.prop('selectionStart', textEnd)
     @input.prop('selectionEnd', textEnd)

+  # propergate focus to our visible input
+  onShadowFocus: ->
+    @input.focus()
+
   onInput: (event) =>
     @toggle() if not @isOpen


fixed messed up rebase

fixed messed up rebase

--- new-www.mock-server.com/docpad.coffee
+++ new-www.mock-server.com/docpad.coffee
@@ -12,22 +12,6 @@
 		# Specify some site properties
 		site:
 			# The production url of our website
-<<<<<<< HEAD
-			url: "http://website.com"
-
-			# Here are some old site urls that you would like to redirect from
-			oldUrls: [
-				'www.website.com',
-				'website.herokuapp.com'
-			]
-
-			# The default title of our website
-			title: "Your Website"
-
-			# The website description (for SEO)
-			description: """
-				When your website appears in search results in say Google, the text here will be shown underneath your website's title.
-=======
 			url: "http://www.mock-server.com"

 			# Here are some old site urls that you would like to redirect from
@@ -41,24 +25,15 @@
 			# The website description (for SEO)
 			description: """
 				An API to easily mock any system or service you integrate with via HTTP or HTTPS from either Java or JavaScript.
->>>>>>> added first cut of layout and build process for new website with an improved structure
 				"""

 			# The website keywords (for SEO) separated by commas
 			keywords: """
-<<<<<<< HEAD
-				place, your, website, keywoards, here, keep, them, related, to, the, content, of, your, website
-				"""
-
-			# The website author's name
-			author: "Your Name"
-=======
 				mockserver, mock server, mock http server, http mock server, mock-server, mock rest service, mock server java, mock api, java mock http server, server mock, java mock server, mock rest server, java mock web service, api mock, mock web service java, mock web server, mock service, mock rest api, mock http response, mock http server java, mock api server, json mock service, api mocking
 				"""

 			# The website author's name
 			author: "James D Bloom"
->>>>>>> added first cut of layout and build process for new website with an improved structure

 			# The website author's email
 			email: "your@email.com"
@@ -66,23 +41,15 @@
 			# Styles
 			styles: [
 				"http://yui.yahooapis.com/pure/0.5.0/pure-min.css"
-<<<<<<< HEAD
-=======
         "//fonts.googleapis.com/css?family=Lato|Averia+Sans+Libre:300normal,300italic,400normal,400italic,700normal,700italic|Amatic+SC:400normal|Belleza:400normal|Belgrano:400normal|Open+Sans:400normal|Dosis:400normal|Codystar:400normal|Concert+One:400normal|Oswald:400normal|Economica:400normal|Duru+Sans:400normal&subset=all"
->>>>>>> added first cut of layout and build process for new website with an improved structure
 				"/styles/style.css"
 			]

 			# Scripts
-<<<<<<< HEAD
-			scripts: []
-
-=======
 			scripts: [
         "/scripts/toggle_menu.js"
         "/scripts/google_analytics.js"
       ]
->>>>>>> added first cut of layout and build process for new website with an improved structure

 		# -----------------------------


StatusBar: Show avatars when creating a new participant avatar.

--- client/ide/views/statusbar/statusbar.coffee
+++ client/ide/views/statusbar/statusbar.coffee
@@ -41,14 +41,12 @@
       click    : (event) ->
         KD.utils.stopDOMEvent event
         appManager.tell 'IDE', 'showChat'
-        # @hide()

     @addSubView @avatars = new KDCustomHTMLView
       cssClass : 'avatars fr hidden'
       click    : (event) ->
         KD.utils.stopDOMEvent event
         appManager.tell 'IDE', 'showChat'
-        # @hide()

   showInformation: ->
@@ -102,6 +100,8 @@
     else
       @createParticipantAvatar nickname, yes

+    @avatars.show()
+

   handleCollaborationEnded: ->


FSItem: Added webm file type to video file type list.

--- client/landing/app/MainApp/fs/fsitem.coffee
+++ client/landing/app/MainApp/fs/fsitem.coffee
@@ -138,7 +138,7 @@
       ]
       video   : [
         "avi","mp4","h264","mov","mpg","ra","ram","mpg","mpeg","m4a"
-        "3gp","wmv","flv","swf","wma","rm","rpm","rv"
+        "3gp","wmv","flv","swf","wma","rm","rpm","rv","webm"
       ]
       sound   : ["aac","au","gsm","mid","midi","snd","wav","3g2","mp3","asx","asf"]
       app     : ["kdapp"]


Remove dead code

Remove dead code

--- client/skr/components/PrintFormChooser.cjsx
+++ client/skr/components/PrintFormChooser.cjsx
@@ -20,20 +20,10 @@
     render: ->
         choices = @props.choices || @props.model.constructor.Templates
         value = @props.value or @props.model[@props.name]
-        console.log @props.model.form, @props
-
         <LC.FieldWrapper {...@props} value={value}>
-
             <Lanes.Vendor.ReactWidgets.DropdownList
                 data={choices}
                 value={value}
                 onChange={@onChange}
             />
         </LC.FieldWrapper>
-        # value = @props.value or @props.model[@props.name]
-        # props = _.omit(@props, 'choices', 'name')
-        # <LC.FormGroup editing={@isEditingRecord()}
-        #     className="field" {...props}
-        # >
-        #     {if @isEditingRecord() then @renderEdit(value) else @renderValue(value)}
-        # </LC.FormGroup>


remove fixed header from fullscreen articles

--- components/article/client/fullscreen.coffee
+++ components/article/client/fullscreen.coffee
@@ -47,14 +47,14 @@

   setupArticleWaypoints: ->
     $fullscreenVideo = @$('.article-fullscreen')
-
     return unless $fullscreenVideo.length

     selector = if $('body').hasClass('body-fullscreen-article') then '.article-content.article-fullscreen-content' else '.article-section-container:first'
+    @$el.removeClass 'body-header-fixed'
     @$(".article-container[data-id=#{@article.get('id')}] #{selector}").waypoint (direction) =>
       if direction == 'down'
         $fullscreenVideo.addClass 'hidden'
-        @$el.removeClass 'body-transparent-header body-transparent-header-white'
+        @$el.addClass('body-header-fixed').removeClass 'body-transparent-header body-transparent-header-white'
       else
         $fullscreenVideo.removeClass 'hidden'
-        @$el.addClass 'body-transparent-header body-transparent-header-white'
+        @$el.removeClass('body-header-fixed').addClass 'body-transparent-header body-transparent-header-white'


Added missing bind.

Added missing bind.

--- src/ProjectUtils.coffee
+++ src/ProjectUtils.coffee
@@ -172,7 +172,7 @@
   # Updating project or models in the project will update the modified date of a project.

   getCurrentDate = -> moment().toDate()
-  updateProjectModifiedDate = _.throttle (projectId, userId) ->
+  updateProjectModifiedDate = _.throttle Meteor.bindEnvironment (projectId, userId) ->
     Projects.update projectId, $set: {dateModified: getCurrentDate(), userModified: userId}
   , 5000


widget mobile scale

widget mobile scale

--- public/views/widget_view.coffee
+++ public/views/widget_view.coffee
@@ -5,15 +5,15 @@

   template: _.template """

-

-

+

+

-

-

+

+

-

+

 """


Modified in browser at pixie.strd6.com

Modified in browser at pixie.strd6.com

--- src/approachable.coffee
+++ src/approachable.coffee
@@ -6,9 +6,9 @@
     for name, cooldownOptions of I.cooldowns
       {target, appraochBy} = cooldownOptions

-      I.cooldowns[name] = I.cooldowns.approach(target, approachBy)
+      I.cooldowns[name].value = I.cooldowns[name].value.approach(target, approachBy)

-  addCooldown: (name, options={target: 0, approachBy: 1}) ->
+  addCooldown: (name, options={target: 0, approachBy: 1, value: 100}) ->
     unless I.cooldowns[name]
       I.cooldowns[name] = options


No need to retrieve blocks by indices.

No need to retrieve blocks by indices.

--- src/block-editor.coffee
+++ src/block-editor.coffee
@@ -97,9 +97,6 @@
         controller: ($scope) ->
             _rollbackStorage = {}

-            getIdx = (block) ->
-                return _.indexOf $scope.blocks, block
-
             updateMovementToggles = ->
                 _.each $scope.blocks, (b, idx) ->
                     b.canMoveUp = idx > 0
@@ -111,15 +108,13 @@

             this.editBlock = (block) ->
                 _rollbackStorage[block.$$hashKey] = _.cloneDeep block
-                $scope.blocks[getIdx(block)].editing = yes
+                block.editing = yes

             this.submitBlockEdit = (block) ->
-                block = $scope.blocks[getIdx block]
                 block.saved = yes
                 block.editing = no

             this.rollbackBlockEdit = (block) ->
-                block = $scope.blocks[getIdx block]

                 # If block wasn't previously saved, delete it right away
                 if not block.saved
@@ -137,7 +132,7 @@

             this.moveUp = (block) ->
                 if block.canMoveUp
-                    index = getIdx block
+                    index = _.indexOf $scope.blocks, block

                     if index > 0
                         current = $scope.blocks[index]
@@ -147,7 +142,7 @@

             this.moveDown = (block) ->
                 if block.canMoveDown
-                    index = getIdx block
+                    index = _.indexOf $scope.blocks, block

                     if index < $scope.blocks.length - 1
                         current = $scope.blocks[index]


Sidebar: Decorate shared environment

Sidebar: Decorate shared environment

--- workers/social/lib/social/models/sidebar.coffee
+++ workers/social/lib/social/models/sidebar.coffee
@@ -20,7 +20,9 @@

   @fetchEnvironment$ = secure (client, callback) ->

-    data = own: []
+    data =
+      own: []
+      shared: []

     client.connection.delegate.fetchUser (err, user) ->

@@ -78,6 +80,8 @@
       addNodeFn = switch
         when isMachineOwner user, machine
           addOwnFn
+        when isMachineShared user, machine
+          addSharedFn

       addNodeFn {machine}

@@ -111,6 +115,14 @@
             if isMachineOwner user, machine
             then successFn()
             else failureFn()
+
+          ->
+
+            successFn = makeSuccessFn addSharedFn
+
+            if isMachineShared user, machine
+            then successFn()
+            else failureFn()
         ]

         dash filterQueue, -> workspaceQueue.fin()
@@ -130,7 +142,7 @@
   isMachineShared = (user, machine) ->

     for u in machine.users
-      if u.id.equals user.getId() and u.permanent
+      if (u.id.equals user.getId()) and u.permanent
         return yes

     return no


Added __getattribute__ for dict

Added __getattribute__ for dict

--- src/builtin/dict.coffee
+++ src/builtin/dict.coffee
@@ -43,8 +43,11 @@
   __ge__: (otherDict) ->
     return new Bool(@__gt__(otherDict).value or @__eq__(otherDict).value)

-  # **Unimplemented**
   __getattribute__: (attr) ->
+    if @__proto__[attr.value]?
+      return @__proto__[attr.value]
+    else
+      raise new AttributeError("'dict' object has no attribute '#{str(attr).value}'")

   # Gets the item from this: like `x[key]`
   __getitem__: (key) ->


Change style of level

Change style of level

--- views/components/main/parts/teitoku-panel.cjsx
+++ views/components/main/parts/teitoku-panel.cjsx
@@ -27,9 +27,9 @@

         <OverlayTrigger placement="bottom" overlay={
             if state.level == 120
+              <Tooltip>Total. {state.exp}</Tooltip>
+            else
               <Tooltip>Next. {state.nextExp}</Tooltip>
-            else
-              <Tooltip>Total. {state.exp}</Tooltip>
           }>
           Lv. {state.level}
         </OverlayTrigger>
@@ -138,14 +138,7 @@
     window.removeEventListener 'game.response', @handleResponse
   render: ->
     <Panel bsStyle="default" className="teitoku-panel">
-      <OverlayTrigger placement="bottom" overlay={if @state.level == 120
-                                                    <Tooltip>Exp. {@state.exp}</Tooltip>
-                                                  else
-                                                    <Tooltip>Next. {@state.nextExp}</Tooltip>}>
-

-          {getHeader @state}
-

-      </OverlayTrigger>
+      {getHeader @state}
     </Panel>

 module.exports = TeitokuPanel


#2702 -- remove more dead code

#2702 -- remove more dead code

--- nodes.coffee
+++ nodes.coffee
@@ -582,11 +582,6 @@
       @superReference(o) + ".call(#{@superThis(o)}#{ args and ', ' + args })"
     else
       (if @isNew then 'new ' else '') + @variable.compile(o, LEVEL_ACCESS) + "(#{args})"
-
-  # `super()` is converted into a call against the superclass's implementation
-  # of the current function.
-  compileSuper: (args, o) ->
-    "#{@superReference(o)}.call(#{@superThis(o)}#{ if args.length then ', ' else '' }#{args})"

   # If you call a function with a splat, it's converted into a JavaScript
   # `.apply()` call to allow an array of arguments to be passed.


JDomain: remove ancient function

JDomain: remove ancient function

--- workers/social/lib/social/models/domain.coffee
+++ workers/social/lib/social/models/domain.coffee
@@ -318,20 +318,6 @@
         then console.error err  unless err.code is 11000
         else updateRelationship domainObj

-  @ensureDomainSettingsForVM = ({account, vm, type, nickname, group})->
-    domain = 'kd.io'
-    if type in ['user', 'expensed']
-      requiredDomains = ["#{nickname}.#{group}.#{domain}"]
-      if group in ['koding', 'guests']
-        requiredDomains.push "#{nickname}.#{domain}"
-    else
-      requiredDomains = ["#{group}.#{domain}", "shared.#{group}.#{domain}"]
-
-    {hostnameAlias} = vm
-    @createDomains {
-      account, hostnameAlias,
-      domains:requiredDomains, group
-    }

   bindVM: (client, params, callback)->
     domainName = @domain


changing how we check for edid/add

changing how we check for edid/add

--- client/controllers/incidentReports/suggestedIncidentModal.coffee
+++ client/controllers/incidentReports/suggestedIncidentModal.coffee
@@ -23,11 +23,10 @@
     previousModal:
       element: '#suggestedIncidentsModal'
       add: 'fade'
-
   @editIncident = (incident) =>
     method = 'addIncidentReport'
     action = 'added'
-    if @data.edit
+    if @incident._id
       method = 'editIncidentReport'
       action = 'updated'


Fix version check

Fix version check

--- test/lib/scaffolding/generator.spec.coffee
+++ test/lib/scaffolding/generator.spec.coffee
@@ -48,7 +48,7 @@
     it 'package.json should contain actual information', ->
       expect(helper.fileContains('package.json', '"name": "TestApp"')).to.be.true
       expect(helper.fileContains('package.json', '"version": "0.1.0"')).to.be.true
-      expect(helper.fileContains('package.json', '"bozon": "0.9.0-alpha.6')).to.be.true
+      expect(helper.fileContains('package.json', '"bozon": "0.9.0-beta.1')).to.be.true

     it 'logs generator steps', ->
       expect(bozon.log.getCall(0).args[0]).to.eq '  \u001b[32mcreate\u001b[39m .gitignore'


still returning login form after logout if auto-oauth is enabled


HUB-258 : Fix logger bug

HUB-258 : Fix logger bug

--- lib/actor/hactor.coffee
+++ lib/actor/hactor.coffee
@@ -120,7 +120,12 @@
   # @property {boolean} Wether listeners are already inited
   listenersInited: undefined

-
+  winston.loggers.add 'default', {
+    console:
+      level: "debug"
+      handleExceptions: true
+      colorize: true
+  }

   #
   # Actor's constructor
@@ -130,11 +135,11 @@
     # init logger
     if topology.log
       @log_properties = topology.log
-      @h_initLogger(topology.log.logLevel or "info", topology.log.logFile)
+      @h_initLogger(topology.log.logFile)
     else
       @log_properties =
         logLevel: "info"
-      @h_initLogger("info")
+      @h_initLogger()

     # setting up instance attributes
     if(validator.validateFullURN(topology.actor))
@@ -486,22 +491,32 @@
   # @param logLevel {string} the log level use by the actor
   # @param logFile {string} the file where the log will be write
   #
-  h_initLogger: (logLevel, logFile) ->
-    logLevels =
-      debug: 0,
-      info: 1,
-      warn: 2,
+  h_initLogger: (logFile) ->
+    if logFile
+      try
+        winston.loggers.add logFile, {
+          console:
+            level: "debug"
+            handleExceptions: true
+            colorize: true
+          file:
+            filename: logFile
+            level: "debug"
+            handleExceptions: true
+        }
+      catch err
+      @logger = winston.loggers.get(logFile)
+    else
+      @logger = winston.loggers.get('default')
+
+    @logger.setLevels({
+      debug: 0
+      info: 1
+      warn: 2
       error: 3
-    @logger = new winston.Logger({levels: logLevels})
+    })
     # Don't crash on uncaught exception
     @logger.exitOnError = false
-
-    # Set log display
-    @logger.add(winston.transports.Console, {handleExceptions: true, level: logLevel, colorize: true})
-    if logFile
-      try
-        @logger.add(winston.transports.File, {handleExceptions: true, filename: logFile, level: logLevel})
-      catch err

   #
   # Method that enrich a message with actor details and logs it to the console
@@ -509,18 +524,23 @@
   # @param message {object} the log message (with the actor which raise it)
   #
   log: (type, message) ->
+    logPriority = ["debug", "info", "warn", "error"]
     switch type
       when "debug"
-        @logger.debug "#{validator.getBareURN(@actor)} | #{message}"
+        if logPriority.indexOf(@log_properties.logLevel) is 0
+          @logger.debug "#{validator.getBareURN(@actor)} | #{message}"
         break
       when "info"
-        @logger.info "#{validator.getBareURN(@actor)} | #{message}"
+        if logPriority.indexOf(@log_properties.logLevel) <= 1
+          @logger.info "#{validator.getBareURN(@actor)} | #{message}"
         break
       when "warn"
-        @logger.warn "#{validator.getBareURN(@actor)} | #{message}"
+        if logPriority.indexOf(@log_properties.logLevel) <= 2
+          @logger.warn "#{validator.getBareURN(@actor)} | #{message}"
         break
       when "error"
-        @logger.error "#{validator.getBareURN(@actor)} | #{message}"
+        if logPriority.indexOf(@log_properties.logLevel) <= 3
+          @logger.error "#{validator.getBareURN(@actor)} | #{message}"
         break

   #


Make registerProviderForEditorView deprecated rather than just remove

--- lib/autocomplete.coffee
+++ lib/autocomplete.coffee
@@ -3,6 +3,7 @@
 Provider = require "./provider"
 Suggestion = require "./suggestion"
 semver = require "semver"
+{deprecate} = require 'grim'

 module.exports =
   config:
@@ -57,6 +58,10 @@
     @autocompleteViews.forEach (autocompleteView) -> autocompleteView.remove()
     @autocompleteViews = []

+  registerProviderForEditorView: (provider, editorView) ->
+    deprecate('Use of editorView is deprecated, use registerProviderForEditor instead')
+    @registerProviderForEditor(provider, editor.getModel())
+
   # Public: Finds the autocomplete view for the given TextEditor
   # and registers the given provider
   #


stop closing process.stderr by accident

stop closing process.stderr by accident

--- lib/commands/run.coffee
+++ lib/commands/run.coffee
@@ -413,7 +413,7 @@
       else
         outputStream.on 'end', ->
           try options.stdout.end() catch # ignore
-          try options.stderr.end() catch # ignore
+          try options.stderr !== process.stderr && options.stderr.end() catch # ignore

         # For non-TTY, we keep stdout and stderr separate, and pipe them appropriately to our
         # process's streams.


Do not export certain functions in renderer process

--- lib/flash-loader.coffee
+++ lib/flash-loader.coffee
@@ -137,8 +137,9 @@
     dbg.ex.flashLoader?.log flashPath
     app.commandLine.appendSwitch 'ppapi-flash-path', flashPath

+if process.type is 'browser'
+  exports.parseCLIArg = parseCLIArg
+  exports.loadFlashPlayer = load

-exports.parseCLIArg = parseCLIArg
-exports.loadFlashPlayer = load
 exports.getFlashPlayerVersion = getFlashVersion
 exports.getAllVersions = getAllVersions


Reset X position to start on new page (fix for columns)

--- lib/line_wrapper.coffee
+++ lib/line_wrapper.coffee
@@ -36,6 +36,7 @@
         @columns = options.columns or 1
         @columnGap = options.columnGap ? 18 # 1/4 inch
         @lineWidth =  (options.width - (@columnGap * (@columns - 1))) / @columns
+        @startX = @document.x
         @startY = @document.y
         @column = 1

@@ -124,12 +125,11 @@
         @emit 'sectionEnd', options, this

         if ++@column > @columns
-            x = @document.x
             @document.addPage()
             @column = 1
             @startY = @document.page.margins.top
             @maxY = @document.page.maxY()
-            @document.x = x
+            @document.x = @startX
             @document.fillColor @document._fillColor... if @document._fillColor
             @emit 'pageBreak', options, this


:art: Group setPanelVisibility with other setters

--- lib/linter-views.coffee
+++ lib/linter-views.coffee
@@ -36,6 +36,13 @@

   getMessages: ->
     @_messages
+
+# consumed in views/panel
+  setPanelVisibility: (Status) ->
+    if Status
+      @_panelWorkspace.show() unless @_panelWorkspace.isVisible()
+    else
+      @_panelWorkspace.hide() if @_panelWorkspace.isVisible()

   # Called in config observer of linter-plus.coffee
   setShowPanel: (showPanel) ->
@@ -105,13 +112,6 @@
       )
       throw null

-  # consumed in views/panel
-  setPanelVisibility: (Status) ->
-    if Status
-      @_panelWorkspace.show() unless @_panelWorkspace.isVisible()
-    else
-      @_panelWorkspace.hide() if @_panelWorkspace.isVisible()
-
   # This method is called when we get the status-bar service
   attachBottom: (statusBar) ->
     @_statusTiles.push statusBar.addLeftTile


Store tabs by element in TabBarView

Store tabs by element in TabBarView

--- lib/tab-bar-view.coffee
+++ lib/tab-bar-view.coffee
@@ -1,7 +1,7 @@
 BrowserWindow = null # Defer require until actually used
 {ipcRenderer} = require 'electron'

-{matches, closest, indexOf} = require './html-helpers'
+{matches, indexOf} = require './html-helpers'
 {CompositeDisposable} = require 'atom'
 _ = require 'underscore-plus'
 TabView = require './tab-view'
@@ -15,6 +15,7 @@

   initialize: (@pane) ->
     @tabs = []
+    @tabsByElement = new WeakMap
     @subscriptions = new CompositeDisposable

     @subscriptions.add atom.commands.add atom.views.getView(@pane),
@@ -101,6 +102,7 @@
     tabView = new TabView()
     tabView.initialize(item, @pane)
     tabView.terminatePendingState() if @isItemMovingBetweenPanes
+    @tabsByElement.set(tabView, tabView)
     @insertTabAtIndex(tabView, index)
     if atom.config.get('tabs.addNewTabsAtEnd')
       @pane.moveItem(item, @pane.getItems().length - 1) unless @isItemMovingBetweenPanes
@@ -128,8 +130,10 @@
   removeTabForItem: (item) ->
     tabIndex = @tabs.findIndex((t) -> t.item is item)
     if tabIndex isnt -1
-      @tabs[tabIndex].destroy()
+      tab = @tabs[tabIndex]
       @tabs.splice(tabIndex, 1)
+      @tabsByElement.delete(tab)
+      tab.destroy()
     tab.updateTitle() for tab in @getTabs()
     @updateTabBarVisibility()

@@ -235,7 +239,7 @@

     event.dataTransfer.setData 'atom-event', 'true'

-    element = closest(event.target, '.sortable')
+    element = @tabForElement(event.target)
     element.classList.add('is-dragging')
     element.destroyTooltip()

@@ -293,7 +297,7 @@

     @removeDropTargetClasses()

-    tabBar = @getTabBar(event.target)
+    tabBar = event.target.closest('.tab-bar')
     sortableObjects = tabBar.querySelectorAll(".sortable")
     placeholder = @getPlaceholder()
     return unless placeholder?
@@ -385,7 +389,7 @@
   onMouseDown: (event) ->
     return unless matches(event.target, ".tab")

-    tab = closest(event.target, '.tab')
+    tab = @tabForElement(event.target)
     if event.which is 3 or (event.which is 1 and event.ctrlKey is true)
       @rightClickedTab?.classList.remove('right-clicked')
       @rightClickedTab = tab
@@ -399,7 +403,7 @@
       event.preventDefault()

   onDoubleClick: (event) ->
-    if tab = closest(event.target, '.tab')
+    if tab = @tabForElement(event.target)
       tab.item.terminatePendingState?()

     else if event.target is this
@@ -409,7 +413,7 @@
   onClick: (event) ->
     return unless matches(event.target, ".tab .close-icon")

-    tab = closest(event.target, '.tab')
+    tab = @tabForElement(event.target)
     @pane.destroyItem(tab.item)
     false

@@ -456,12 +460,12 @@

   getDropTargetIndex: (event) ->
     target = event.target
-    tabBar = @getTabBar(target)
+    tabBar = target.closest('.tab-bar')

     return if @isPlaceholder(target)

-    sortables = tabBar.querySelectorAll(".sortable")
-    element = closest(target, '.sortable')
+    sortables = @getTabs()
+    element = @tabForElement(target)
     element ?= sortables[sortables.length - 1]

     return 0 unless element?
@@ -488,12 +492,6 @@

   isPlaceholder: (element) ->
     element.classList.contains('placeholder')
-
-  getTabBar: (target) ->
-    if target.classList.contains('tab-bar')
-      target
-    else
-      closest(target, '.tab-bar')

   onMouseEnter: ->
     for tab in @getTabs()
@@ -505,4 +503,12 @@
     tab.style.maxWidth = '' for tab in @getTabs()
     return

+  tabForElement: (element) ->
+    currentElement = element
+    while currentElement?
+      if tab = @tabsByElement.get(currentElement)
+        return tab
+      else
+        currentElement = currentElement.parentElement
+
 module.exports = document.registerElement("atom-tabs", prototype: TabBarView.prototype, extends: "ul")


Hide settings button if theme has no settings

--- lib/themes-panel.coffee
+++ lib/themes-panel.coffee
@@ -151,6 +151,17 @@
     @activeUiTheme = @getActiveUiTheme()
     @activeSyntaxTheme = @getActiveSyntaxTheme()
     @populateThemeMenus()
+
+    if not atom.config.get(@activeUiTheme)?
+      @currentUiThemeSettings.hide()
+    else
+      @currentUiThemeSettings.show()
+
+    if not atom.config.get(@activeSyntaxTheme)?
+      @currentSyntaxThemeSettings.hide()
+    else
+      @currentSyntaxThemeSettings.show()
+
     @handleCurrentThemeButtons()

   handleCurrentThemeButtons: ->


Hyphenate 'GitHub created'

Hyphenate 'GitHub created'

--- lib/welcome-view.coffee
+++ lib/welcome-view.coffee
@@ -33,7 +33,7 @@
           @ul =>
             @li => @raw 'The Atom docs for Guides and the API reference.'
             @li => @raw 'The Atom forum at discuss.atom.io.'
-            @li => @raw 'The Atom Org. This is where all GitHub created Atom packages can be found.'
+            @li => @raw 'The Atom Org. This is where all GitHub-created Atom packages can be found.'
           @p class: 'welcome-note welcome-metrics', =>
              @raw '''
                 Note: To help us improve Atom, we anonymously


re-rebasing point

re-rebasing point

Former-commit-id: 6fa8da899105a114ebd3c4d5ab4d41c33cd5acfb [formerly 038b17e08795db0b7c970ff8bd37349811233703] [formerly 4af5f9417ae565eb8fceffbf6e4a36fdc04de819 [formerly 61e8f0cf4fc25ccc32c1cf4c27ecc7886cac1c85]] [formerly c7fa1f0b4c34ef94e087d4ee0b04f19cfd7ca319 [formerly 60258cb9b750ee13a8ad8de575f2674267520e2d] [formerly ff643497657556016bb2e0ab206dd5093700db4e [formerly ff643497657556016bb2e0ab206dd5093700db4e [formerly a5bb0cf55b7fa215bbb60aa8ada068db75177de8]]]]
Former-commit-id: a9cb29074ad549fd02f6eb41fa257a4c2d4a2a8f [formerly e708251615a5a29e243c281b514e0ccc60db24ce] [formerly 2c4ad672aa8aecb0fb969e79a7200c72cc5f9655 [formerly 493b371e09c34e0607ca91625360757b90b1568c]]
Former-commit-id: 5a631b72ffce0d2a8949021fcb5bb8dd3a811c70 [formerly 65e6b705f9eabdc134533abd4f109e6a6da3cc2c]
Former-commit-id: 6f50412d8be5dd9347d83e3fcbf776c17c9ccf29
Former-commit-id: b361caa429e3db52994a35edffe601de17ff2b61

--- @client/modules/franklin/point/point_view.coffee
+++ @client/modules/franklin/point/point_view.coffee
@@ -1,5 +1,6 @@
 @ConsiderIt.module "Franklin.Point", (Point, App, Backbone, Marionette, $, _) ->

+  # High level point view and two subclasses. Each point is generated by a points controller.
   class Point.PointView extends App.Views.Layout
     actions : [] # the point actions available for this class of Point

@@ -75,12 +76,16 @@
       ev.stopPropagation()

+
+  # View that manages the content shown when a point is opened.
+  # Confusingly, point details are not managed here.
   class Point.OpenPointView extends App.Views.Layout
     template : '#tpl_open_point'
+    className : 'open_point_layout'
     regions :
       followRegion : '.point-follow-region'
       assessmentRegion : '.point-assessment-region'
-      discussionRegion : '.point-discussion'
+      discussionRegion : '.point-discussion-region'

     serializeData : ->
       @model.attributes
@@ -115,7 +120,7 @@

   class Point.PointAvatarArea extends App.Views.ItemView
     template : '#tpl_point_avatar_area'
-    className : 'point_avatar_area'
+    className : 'point_avatar_view'

     serializeData : ->
       assessment = @model.getAssessment()
@@ -176,6 +181,7 @@

   class Point.PointSummaryView extends App.Views.ItemView
     template : '#tpl_point_summary'
+    className : 'point_summary_view'

     serializeData : ->
       params = _.extend {}, @model.attributes,
@@ -245,6 +251,7 @@

   class Point.FollowPointView extends App.Views.ItemView
     template : '#tpl_follow_point'
+    className : 'follow_point_view'

     serializeData : ->
       current_user = App.request 'user:current'


Simplify before/after handling

Simplify before/after handling

--- spec/UserMiddleware.coffee
+++ spec/UserMiddleware.coffee
@@ -85,32 +85,26 @@
       receivePass passAction, action, payload, done
       send actionIn, action, payload
   describe 'receiving start action', ->
+    originalUser = null
+    beforeEach ->
+      originalUser = localStorage.getItem 'grid-user'
+      return unless originalUser
+      localStorage.removeItem 'grid-user'
+    afterEach ->
+      return unless originalUser
+      localStorage.setItem 'grid-user', originalUser
     describe 'without logged in user', ->
-      originalUser = null
-      before ->
-        originalUser = localStorage.getItem 'grid-user'
-        return unless originalUser
-        localStorage.removeItem 'grid-user'
-      after ->
-        return unless originalUser
-        localStorage.setItem 'grid-user', originalUser
       it 'should pass it out as-is', (done) ->
         action = 'start'
-        payload = true
+        payload = 'https://app.flowhub.io'
         receivePass passAction, action, payload, done
         send actionIn, action, payload
     describe 'with logged in user', ->
-      originalUser = null
       userData =
         id: 1
         name: 'Henri Bergius'
-      before ->
-        originalUser = localStorage.getItem 'grid-user'
+      beforeEach ->
         localStorage.setItem 'grid-user', JSON.stringify userData
-      after ->
-        localStorage.removeItem 'grid-user'
-        return unless originalUser
-        localStorage.setItem 'grid-user', originalUser
       it 'should pass it out as-is and send user:info', (done) ->
         received =
           pass: false


add comma handling functionality to smart-number directive for backspace and delete events, clean up keypress functionality, begin migrating keyup actions to keypress to avoid data malformation

--- app/assets/javascripts/angular/directives/smartNumber.js.coffee
+++ app/assets/javascripts/angular/directives/smartNumber.js.coffee
@@ -1,15 +1,15 @@
 NumberModule = angular.module('smart-number', [])

 NumberModule.directive 'smartNumber',
-['NumberConfig', (smartNumberConfig) ->
-
-    defaultOptions = NumberConfig.defaultOptions
+['smartNumberConfig', (smartNumberConfig) ->
+
+    defaultOptions = smartNumberConfig.defaultOptions
     controlKeys = [0,8,13] # 0 = tab, 8 = backspace , 13 = enter

     getOptions = (scope, attrs) ->
         options = angular.copy defaultOptions
-        if attrs.NumberOptions?
-            for own option, value of scope.$eval(attrs.NumberOptions)
+        if attrs.smartNumberOptions?
+            for own option, value of scope.$eval(attrs.smartNumberOptions)
                 options[option] = value
         options

@@ -70,6 +70,22 @@
     makeMaxDigits = (maxDigits) ->
         validRegex = new RegExp "^-?\\d{0,#{maxDigits}}(\\.\\d*)?$"
         (val) -> validRegex.test val
+
+    backspaceAtComma = (elem, event) ->
+      cursorPos = elem[0].selectionStart
+      elem.val().charAt(elem[0].selectionStart - 1) == "," and event.which == 8
+
+    deleteAtComma = (elem, event) ->
+      cursorPos = elem[0].selectionStart
+      elem.val().charAt(cursorPos) == "," and event.which == 46
+
+    moveCursorLeft = (elem) ->
+      newCursorPos = elem[0].selectionStart - 1
+      elem[0].setSelectionRange(newCursorPos, newCursorPos)
+
+    moveCursorRight = (elem) ->
+      newCursorPos = elem[0].selectionStart + 1
+      elem[0].setSelectionRange(newCursorPos, newCursorPos)

     makeIsValid = (options) ->
         validations = []
@@ -153,16 +169,12 @@
                 else
                   newCursorPosition = elem[0].selectionStart
               else
-                if elem.val().length >= options.maxDigits # maxDigits has been reached
+                if elem.val().length == 4 || elem.val().length == 8 # a new comma is added
+                  newCursorPosition = elem[0].selectionStart + 1
+                else if elem[0].selectionStart < elem.val().length # cursor is adding numbers, but is not at the end of the input field
                   newCursorPosition = elem[0].selectionStart
-                else
-                  if elem.val().length == 4 || elem.val().length == 8 # a new comma is added
-                    newCursorPosition = elem[0].selectionStart + 1
-                  else
-                    if elem[0].selectionStart < elem.val().length # cursor is adding numbers, but is not at the end of the input
-                      newCursorPosition = elem[0].selectionStart # otherwise
-                    else
-                      newCursorPosition = elem[0].selectionStart + 1 # otherwise
+                else # cursor is adding numbers at the end of the input field
+                  newCursorPosition = elem[0].selectionStart + 1

               elem.val resetCommas(elem.val()) # reformat the number in place
               elem[0].setSelectionRange(newCursorPosition, newCursorPosition) # set the new cursor position
@@ -170,6 +182,7 @@
               # not updating unless value is longer than 4 digits including commas
               # still some issues moving the comma after input/delete
               # need to add support for delete/backspace if comma is present
+              # issue where formatting is not occurring when entered too quickly
               if scope.rawScoreUpdating == false
                 beginUpdate(scope, elem)

@@ -190,6 +203,10 @@
                 # elem.val val.replace /,/g, '' # ATTN: LINE THAT ADDS ON-CLICK COMMA REMOVAL
                 elem[0].select()

+            elem.on 'keydown', (e) ->
+              moveCursorLeft(elem) if backspaceAtComma(elem, event)
+              moveCursorRight(elem) if deleteAtComma(elem, event)
+
             if options.preventInvalidInput == true
               elem.on 'keypress', (e) ->
                 if invalidInput(elem, event, options)


Include ruby grammar for fenced ruby blocks

--- src/packages/gfm/grammars/gfm.cson
+++ src/packages/gfm/grammars/gfm.cson
@@ -90,6 +90,16 @@
     'patterns': ['include': 'text.xml']
   }
   {
+    'begin': '^```(ruby|rb)$'
+    'beginCaptures':
+      '0': 'name': 'support.gfm'
+    'end': '^```$'
+    'endCaptures':
+      '0': 'name': 'support.gfm'
+    'name': 'markup.code.ruby.gfm'
+    'patterns': ['include': 'source.ruby']
+  }
+  {
     'begin': '^```.*$'
     'beginCaptures':
       '0': 'name': 'support.gfm'


Fix the spec bootstrap to load the package file

--- spec/spec-bootstrap.coffee
+++ spec/spec-bootstrap.coffee
@@ -1,4 +1,9 @@
-@pkgJson = require '../../package.json'
+@pkgJson = require 'package.json'

 # Start the crash reporter before anything else.
 require('crash-reporter').start(productName: @pkgJson.name, companyName: 'atom-shell-starter')
+
+h1 = document.createElement 'h1'
+h1.innerText = 'Spec Suite'
+
+document.body.appendChild h1


stop preload on embed as well.

stop preload on embed as well.

--- app/assets/javascripts/external_scripts/embed_script.js.coffee
+++ app/assets/javascripts/external_scripts/embed_script.js.coffee
@@ -3,7 +3,7 @@
   frame_mnfg_url = "#{window.root_url}/api/autocomplete?per_page=#{per_page}&categories=frame_mnfg&q="
   $(target).selectize
     plugins: ['restore_on_backspace']
-    preload: true
+    # preload: true
     create: false
     maxItems: 1
     valueField: 'slug'


Use graph ticks to make axis more readable

--- app/assets/javascripts/stat_graph_contributors_graph.js.coffee
+++ app/assets/javascripts/stat_graph_contributors_graph.js.coffee
@@ -71,7 +71,7 @@
     super @width, @height
   create_axes: ->
     @x_axis = d3.svg.axis().scale(@x).orient("bottom")
-    @y_axis = d3.svg.axis().scale(@y).orient("left")
+    @y_axis = d3.svg.axis().scale(@y).orient("left").ticks(5)
   create_svg: ->
     @svg = d3.select("#contributors-master").append("svg")
     .attr("width", @width + @MARGIN.left + @MARGIN.right)
@@ -130,8 +130,8 @@
   create_scale: ->
     super @width, @height
   create_axes: ->
-    @x_axis = d3.svg.axis().scale(@x).orient("bottom").tickFormat(d3.time.format("%m/%d"));
-    @y_axis = d3.svg.axis().scale(@y).orient("left")
+    @x_axis = d3.svg.axis().scale(@x).orient("bottom").ticks(8)
+    @y_axis = d3.svg.axis().scale(@y).orient("left").ticks(5)
   create_area: (x, y) ->
     @area = d3.svg.area().x((d) ->
       parseDate = d3.time.format("%Y-%m-%d").parse
@@ -148,7 +148,7 @@
     .append("g")
     .attr("transform", "translate(" + @MARGIN.left + "," + @MARGIN.top + ")")
   draw_path: (data) ->
-    @svg.append("path").datum(data).attr("class", "area-contributor").attr("d", @area);
+    @svg.append("path").datum(data).attr("class", "area-contributor").attr("d", @area)
   draw: ->
     @create_scale()
     @create_axes()


HitEnterView: minor code cleanup

HitEnterView: minor code cleanup

--- src/components/inputs/hitenterinputview.coffee
+++ src/components/inputs/hitenterinputview.coffee
@@ -4,17 +4,16 @@

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

-    options.type            or= "textarea"
+    options.type            or= 'textarea'
+    options.cssClass          = KD.utils.curry 'hitenterview', options.cssClass
     options.button          or= null
     options.showButton       ?= no
     options.label           or= null
     options.placeholder     or= ""
     options.callback        or= null
-    options.togglerPartials or= ["quick update disabled","quick update enabled"]
+    options.togglerPartials or= ['quick update disabled', 'quick update enabled']

     super options,data
-
-    @setClass "hitenterview"

     @button = @getOptions().button ? null
     @enableEnterKey()


:racehorse: Flatten segments directly

:racehorse: Flatten segments directly

--- src/scope-selector-matchers.coffee
+++ src/scope-selector-matchers.coffee
@@ -1,8 +1,6 @@
-_ = require 'underscore-plus'
-
 class SegmentMatcher
-  constructor: (segment) ->
-    @segment = _.flatten(segment).join('')
+  constructor: (segments) ->
+    @segment = segments[0].join('') + segments[1].join('')

   matches: (scope) -> scope is @segment


--- chrome/content/zotero-better-bibtex/zotero-better-bibtex.coffee
+++ chrome/content/zotero-better-bibtex/zotero-better-bibtex.coffee
@@ -453,6 +453,10 @@
       # If no capture, we're done
       return original.apply(this, arguments) unless @_displayOptions?['Keep updated']

+      if @_displayOptions.exportFileData
+        @flash('Ignoring "Export File Data"', 'Export of file data is disabled for "Keep updated"')
+        delete @_displayOptions.exportFileData
+
       # I don't want 'Keep updated' to be remembered as a default
       try
         settings = JSON.parse(Zotero.Prefs.get('export.translatorSettings'))