Start using Swedish language maps

Start using Swedish language maps

Fixes #188.

--- src/map.coffee
+++ src/map.coffee
@@ -301,9 +301,16 @@
                 url = "http://144.76.78.72/mapproxy/wmts/osm-toner/etrs_tm35fin/{z}/{x}/{y}.png"
             else
                 if @is_retina
-                    url = "http://144.76.78.72/mapproxy/wmts/osm-sm-hq/etrs_tm35fin_hq/{z}/{x}/{y}.png"
+                    if p13n.get_language() == 'sv'
+                        url = "http://144.76.78.72/mapproxy/wmts/osm-sm-sv-hq/etrs_tm35fin_hq/{z}/{x}/{y}.png"
+                    else
+                        url = "http://144.76.78.72/mapproxy/wmts/osm-sm-hq/etrs_tm35fin_hq/{z}/{x}/{y}.png"
                 else
-                    url = "http://144.76.78.72/mapproxy/wmts/osm-sm/etrs_tm35fin/{z}/{x}/{y}.png"
+                    if p13n.get_language() == 'sv'
+                        url = "http://144.76.78.72/mapproxy/wmts/osm-sm-sv/etrs_tm35fin/{z}/{x}/{y}.png"
+                    else
+                        url = "http://144.76.78.72/mapproxy/wmts/osm-sm/etrs_tm35fin/{z}/{x}/{y}.png"
+
             return @make_tm35_layer url

         create_map: ->


Allow layer image reset

Allow layer image reset

--- framer/Layer.coffee
+++ framer/Layer.coffee
@@ -391,6 +391,10 @@
 			# Set the property value
 			@_setPropertyValue "image", value

+			if value in [null, ""]
+				@style["background-image"] = null
+				return
+
 			imageUrl = value

 			# Optional base image value
@@ -596,8 +600,6 @@

 	addListener: (eventName, originalListener) =>

-		console.log "addListener", eventName
-
 		# # Modify the scope to be the calling object, just like jquery
 		# # also add the object as the last argument
 		listener = (args...) =>


Display an error message when no APIs can be used

ref #6

--- lib/translator-plus-dictionary.coffee
+++ lib/translator-plus-dictionary.coffee
@@ -19,10 +19,14 @@
     @emitter?.dispose()

   translate: (text, from, to, succeeded, failed) ->
+    numberOfUsedApis = 0
+
     # TODO Deal with only **one** translation at the same time.
     @emitter.emit("Started")
     for translator in @translators
       if not translator.canBeUsed(from, to) then continue
+
+      numberOfUsedApis += 1
       kind = {
         name: translator.name()
         type: "Translator"
@@ -43,6 +47,8 @@
       )
     for dictionary in @dictionaries
       if not dictionary.canBeUsed(from, to) then continue
+
+      numberOfUsedApis += 1
       kind = {
         name: dictionary.name()
         type: "Dictionary"
@@ -61,6 +67,18 @@
             failed(kind, error)
         )(kind)
       )
+
+    if numberOfUsedApis == 0
+      @emitter.emit("Failed", {
+        kind: {
+          name: "Translator Plus Dictionary"
+          type: "General"
+        },
+        error: {
+          message: "There are no APIs that translates from #{from.name} to #{to.name}."
+        }
+      })
+
     @emitter.emit("Finished")

   onStarted: (callback) -> @emitter.on("Started", callback)


Use new API to destroy markers in snippets package

--- src/packages/snippets/lib/snippet-expansion.coffee
+++ src/packages/snippets/lib/snippet-expansion.coffee
@@ -64,7 +64,7 @@

   destroy: ->
     @unsubscribe()
-    @editSession.destroyMarker(marker) for marker in @tabStopMarkers
+    marker.destroy() for marker in @tabStopMarkers
     @editSession.snippetExpansion = null

   restore: (@editSession) ->


document run execution

document run execution

--- src/run.coffee
+++ src/run.coffee
@@ -10,6 +10,17 @@
 context = require './context'
 {Tree} = require './tree'

+###
+The execution is done in 2 passes.
+
+On the first pass, a context object is build for each server. A context is the
+same object inject to a callback action as first argument. In a context, other
+server contexts are available through the `hosts` object where keys are the
+server name. A context object is enriched with the "actions" and "modules"
+properties which are respectively a list of "actions" and a list of modules.
+
+On the second pass, the action are executed.
+###
 Run = (config, params) ->
   EventEmitter.call @
   @setMaxListeners 100


client: copy changes for home, teamwork, help

--- client/landing/Intro/home.coffee
+++ client/landing/Intro/home.coffee
@@ -200,14 +200,14 @@

USE IT IN YOUR SCHOOL

-              Koding in the classroom, prepare your files online, share them with the whole class instantly. Collaborate live or just make your students watch what you're doing.
+              Prepare your files online and share them with the whole class instantly. Collaborate live with your students or let them follow along what you're doing.

CREATE PROJECT GROUPS

-              Want to work on a project with your buddies and use the same resources and running instances, share a VM between your fellow developers.
+              Want to work on a project with your buddies and use the same workspace? Share your VM with your fellow developers.


Show the correct watchers count

Show the correct watchers count

We request each repository from the GitHub API individually to get the `subscriber_count` field.

This is the actual watchers count (the `watchers_count` field is actually the number of users who have starred the repository).

--- source/repository-service/repository-service.coffee
+++ source/repository-service/repository-service.coffee
@@ -1,14 +1,27 @@
 require '../module/module'
 angular = require 'angular'

+Promise = require 'bluebird'
+
 module.exports = class RepositoryService
   constructor: (@$http) ->
+    @base = 'https://api.github.com/'

-  getAll: ->
-    url = 'https://api.github.com/search/repositories?q=user:karl&sort=stars&order=desc'
+  getAllForUser: (user) ->
+    url = "#{@base}search/repositories?q=user:#{user}&sort=stars&order=desc"
     @$http.get url
-      .then (results) ->
-        results.data.items
+      .then (response) =>
+        repositories = response.data.items
+
+        # Because the repositories returned from GitHub `search/repositories` and `/user/:name/repos`
+        # don't contain the `subcribers_count` field we need to make a call to
+        # get each repository individually to get that field.
+        # This is horribly inefficient, but I couldn't find any other documented
+        # way to get this data.
+        Promise.map repositories, (repository) =>
+          @$http.get "#{@base}repos/#{user}/#{repository.name}"
+            .then (response) ->
+              response.data


atom-packages: remove node_modules

atom-packages: remove node_modules

--- public/.atom/packages.cson
+++ public/.atom/packages.cson
@@ -16,7 +16,6 @@
   "linter-xo"
   "merge-conflicts"
   "minimap"
-  "node_modules"
   "package-sync"
   "pigments"
   "regex-railroad-diagram-fork"


added block filter to bucket filters

added block filter to bucket filters

--- src/driver/driverUtil.coffee
+++ src/driver/driverUtil.coffee
@@ -43,6 +43,9 @@
   return segment.prop[prop] or getPropFromSegment(segment.parent, prop)

 bucketFilterFns = {
+  block: ->
+    return false
+
   is: ({prop, value}) ->
     return (segment) -> getPropFromSegment(segment, prop) is value

@@ -408,19 +411,18 @@
 # @param {SplitTree} root - the root of the split tree
 # @param {prepend,append,none} order - what to do with the root of the tree
 # @return {Array(SplitTree)} the tree nodes in the order specified
-exports.flatten = (root, order) ->
+exports.flattenTree = (root, order) ->
   throw new TypeError('must have a tree') unless root
   throw new TypeError('order must be on of prepend, append, or none') unless order in ['prepend', 'append', 'none']
-  result = []
-  flattenHelper(root, null, order, result)
+  flattenTreeHelper(root, order, result = [])
   return result

-flattenHelper = (root, order, result) ->
+flattenTreeHelper = (root, order, result) ->
   result.push(root) if order is 'prepend'

   if root.splits
     for split in root.splits
-      flattenHelper(split, preorder, result)
+      flattenTreeHelper(split, order, result)

   result.push(root) if order is 'append'
   return


better IS bucket filter

better IS bucket filter

--- src/driver/driverUtil.coffee
+++ src/driver/driverUtil.coffee
@@ -47,7 +47,16 @@
     return -> false

   is: ({prop, value}) ->
-    return (segment) -> getPropFromSegment(segment, prop) is value
+    if Array.isArray(value)
+      # value can also be a range for direct interval comparisons
+      [start, end] = value
+      start = Date.parse(start) if typeof start is 'string'
+      end = Date.parse(end) if typeof end is 'string'
+      return (segment) ->
+        [segStart, segEnd] = getPropFromSegment(segment, prop)
+        return segStart.valueOf() is start and segEnd.valueOf() is end
+    else
+      return (segment) -> getPropFromSegment(segment, prop) is value

   in: ({prop, values}) ->
     return (segment) -> getPropFromSegment(segment, prop) in values


Rollback to working code

Rollback to working code

--- src/scripts/helpers/backbone/views/editable.coffee
+++ src/scripts/helpers/backbone/views/editable.coffee
@@ -82,38 +82,15 @@
                 $editable.text('Starting up Aloha...')
                 # Wait for Aloha to start up
                 Aloha.ready () =>
-                  html = @model.get(value) or ''
-                  html += "<p> </p>" # Allow putting cursor after a Blockish. removed if empty.
-                  $editable.html(html)
+                  $editable.html(@model.get(value) or '')
                   $editable.addClass('aloha-root-editable') # the semanticblockplugin needs this for some reason
                   $editable.aloha()

-                  # Grab the editable so we can call `.getContents()`
-                  alohaId = $editable.attr('id')
-                  alohaEditable = Aloha.getEditableById(alohaId)
-
-                  if 'content' == value
-                    # See aloha.coffee for where this is used
-                    window.GLOBAL_UPOADER_HACK = () =>
-                      editableBody = alohaEditable.getContents()
-                      @model.set(value, editableBody)
-                      setChanged(@model, options.onEdit)
-
                   # Update the model if an event for this editable was triggered
                   Aloha.bind 'aloha-smart-content-changed.updatemodel', (evt, d) =>
-                    isItThisEditable = d.editable.obj.is($editable)
-                    isItThisEditable = isItThisEditable or $.contains($editable[0], d.editable.obj[0])
-
-                    # If you're having blur problems I feel bad for you son: d.triggerType != 'blur'
-                    if isItThisEditable
-
-                      # Update the model by retrieving the XHTML contents
-                      editableBody = alohaEditable.getContents()
-                      editableBody = editableBody.trim() # Trim for idempotence
-                      # Change the contents but do not update the Aloha editable area
-                      @model.set(value, editableBody)
+                    if d.editable.obj.is($editable) or $.contains($editable[0], d.editable.obj[0])
+                      @model.set(value, d.editable.getContents().trim()) # Trim for idempotence
                       setChanged(@model, options.onEdit)
-

             # Setup Select2
             when 'select2'


add support for creating a new page or book

--- src/scripts/modules/workspace/header/header.coffee
+++ src/scripts/modules/workspace/header/header.coffee
@@ -17,21 +17,22 @@
       @listenTo(@model, 'change:results change:loaded', @render) if @model

     addBook: () ->
-      alert('TODO: Not quite implemented yet.')
-      # title = prompt('What is the title for the new Book?')
-      # if title
-      #   newBook = new Content
-      #     title: title
-      #     contents: []
+      title = prompt('What is the title for the new Book?')
+      if title
+        newBook = new Content
+          mediaType: 'application/vnd.org.cnx.collection'
+          title: title
+          contents: []

-      #   newBook.save()
-      #   .fail(() -> alert('There was a problem saving. Please try again'))
-      #   .done () => @model.prependNew(newBook)
+        newBook.save()
+        .fail(() -> alert('There was a problem saving. Please try again'))
+        .done () => @model.prependNew(newBook)

     addPage: () ->
       title = prompt('What is the title for the new Page?')
       if title
         newPage = new Content
+          mediaType: 'application/vnd.org.cnx.module'
           title: title
           content: '
Please change this new Page
'


- some slight additional cleanup of project pre-processor

--- src/app/modules/core/projects/preprocessor.coffee
+++ src/app/modules/core/projects/preprocessor.coffee
@@ -3,50 +3,9 @@
   reqRes = require 'modules/core/reqRes'
   utils = require "modules/core/utils/utils"

-  #dependency resolving solved with the help of http://www.electricmonk.nl/docs/dependency_resolving_algorithm/dependency_resolving_algorithm.html
-  class Node
-    constructor:(name)->
-      @name = name
-      @edges = []
-    addEdge:(node)->
-      @edges.push(node)
-
-  class DependencyResolver
-
-  resolved = []
-  unresolved = []
-
-  dep_resolve=(node, resolved, unresolved)->
-    console.log "resolving node #{node.name}"
-    unresolved.push(node)
-    for edge in node.edges
-      if edge not in resolved
-        if edge in unresolved
-          throw new Error("Circular dependency detected between #{node.name} and #{edge.name }")
-        dep_resolve(edge, resolved, unresolved)
-    resolved.push(node)
-    unresolved.splice(unresolved.indexOf(node), 1)
-
-
-  a = new Node('a')
-  b = new Node('b')
-  c = new Node('c')
-  d = new Node('d')
-  e = new Node('e')
-
-  a.addEdge(b)    # a depends on b
-  a.addEdge(d)    # a depends on d
-  b.addEdge(c)    # b depends on c
-  b.addEdge(e)    # b depends on e
-  c.addEdge(d)    # c depends on d
-  c.addEdge(e)    # c depends on e
-  #d.addEdge(b)
-  #dep_resolve(a,resolved,unresolved)
-  #solution = (node.name for node in resolved)
-  #console.log "solution : #{solution.join(' ')}"

   class PreProcessor
-
+    #dependency resolving solved with the help of http://www.electricmonk.nl/docs/dependency_resolving_algorithm/dependency_resolving_algorithm.html
     constructor:()->
       @project = null
       @resolvedIncludes = []
@@ -77,23 +36,13 @@
       @project = project
       mainFileName = @project.get("name")
       mainFileCode = @project.pfiles.get(mainFileName).get("content")
-      mainFileNode = new Node(mainFileName)
-      result  = @processIncludes(mainFileNode,mainFileName, mainFileCode)
-
-      console.log "@resolvedIncludes"
-      console.log @resolvedIncludes
-      console.log "@unresolvedIncludes"
-      console.log @unresolvedIncludes
+      result  = @processIncludes(mainFileName, mainFileCode)

       if coffeeToJs
         result = CoffeeScript.compile(result, {bare: true})
       return result
-
-    process_old:(source)->
-      fullSource = libsSource + source
-      textblock = CoffeeScript.compile(fullSource, {bare: true})

-    processIncludes:(parentNode, filename, source)=>
+    processIncludes:(filename, source)=>
       #finds all matches of "include xxx", and fetches the corresponding text
       console.log "processing #{filename}"
       console.log "@unresolvedIncludes : #{@unresolvedIncludes.join(' ')}"
@@ -130,10 +79,7 @@
           throw new Error("Circular dependency detected from #{filename} to #{includeeFileName}")
         if not (includeeFileName in @resolvedIncludes)
           result = @fetch_data(store,projectName,projectSubPath)
-          newNode = new Node(includeeFileName)
-          if parentNode?
-            parentNode.addEdge(includeeFileName)
-          result = @processIncludes(newNode, includeeFileName, result)
+          result = @processIncludes(includeeFileName, result)

           @resolvedIncludes.push(includeeFileName)
         return result


Revert "Provide separate ports by connection status"

This reverts commit c229310dcd4058c91fb72dd3e22a911094da190d.

--- components/ConnectRuntime.coffee
+++ components/ConnectRuntime.coffee
@@ -18,15 +18,7 @@
       runtime:
         datatype: 'object'
         description: 'FBP Runtime instance'
-        required: false
-      connected:
-        datatype: 'object'
-        description: 'Connected FBP Runtime instance'
-        required: false
-      disconnected:
-        datatype: 'object'
-        description: 'Disconnected FBP Runtime instance'
-        required: false
+        required: true
       error:
         datatype: 'object'
         description: 'Runtime connection error'
@@ -58,10 +50,6 @@
       return

     onError = (e) =>
-      @outPorts.disconnected.beginGroup definition.id
-      @outPorts.disconnected.send rt
-      @outPorts.disconnected.endGroup()
-      @outPorts.disconnected.disconnect()
       @outPorts.error.send e
       @outPorts.error.disconnect()
       return
@@ -70,15 +58,11 @@
     rt.setParentElement @element if @element
     rt.once 'capabilities', =>
       rt.removeListener 'error', onError
-      @outPorts.connected.beginGroup definition.id
-      @outPorts.connected.send rt
-      @outPorts.connected.endGroup()
-      @outPorts.connected.disconnect()
+      @outPorts.runtime.beginGroup definition.id
+      @outPorts.runtime.send rt
+      @outPorts.runtime.endGroup()
+      @outPorts.runtime.disconnect()
     rt.once 'error', onError
     rt.connect()
-    @outPorts.runtime.beginGroup definition.id
-    @outPorts.runtime.send rt
-    @outPorts.runtime.endGroup()
-    @outPorts.runtime.disconnect()

 exports.getComponent = -> new ConnectRuntime


Start editing tip documentation for readability and brevity.

--- src/js/jquery.hlf.tip.coffee
+++ src/js/jquery.hlf.tip.coffee
@@ -5,27 +5,24 @@
 Written with jQuery 1.7.2
 ###

-# The base `tip` plugin features basic trigger element parsing, direction-based
-# attachment, cursor following, appearance state management and presentation by
-# fading, custom tip content, and use of the `hlf.hoverIntent` event extension.
-# The tip object is shared amongst the provided triggers.
-
-# The extended `snapTip` plugin extends the base tip and adds snapping-to-
-# trigger-element behavior. By default locks into place. If one of the snap-to-
-# axis options is turned off, the tip will slide along the remaining locked
-# axis.
-
-# Note the majority of presentation state logic is in the plugin stylesheet. We
-# update the presentation state by using `classNames`.
-
-# Lastly, like any other module in this library, we're using proper namespacing
-# whenever there is an added endpoint to the jQuery interface. This is done with
-# the custom `toString` methods. Also, plugin namespaces (under the root
-# `$.hlf`) each have a `debug` flag allowing more granular logging. Each
-# plugin's API is also entirely public, although some methods are intended as
-# protected given their name. Access the plugin singleton is as simple as via
-# `$('body').tip()` or `$('body').snapTip()`, although using the `toString` and
-# jQuery data methods is the same.
+# ❧
+
+# The base `tip` plugin does several things. It does basic parsing of trigger
+# element attributes for the tip content. It can anchor itself to a trigger by
+# selecting the best direction. It can follow the cursor. It toggles its
+# appearance by fading in and out and resizing, all via configurable animations.
+# It can display custom tip content. It uses of the `hlf.hoverIntent` event
+# extension to prevent appearance 'thrashing.' Last, the tip object attaches to
+# the context element. It acts as tip for the the current jQuery selection via
+# event delegation.
+
+# The extended `snapTip` plugin extends the base tip. It allows the tip to snap
+# to the trigger element. And by default the tip locks into place. But turn on
+# only one axis of snapping, and the tip will track the mouse only on the other
+# axis. For example, snapping to the x-axis will only allow the tip to shift
+# along the y-axis. The x will remain constant.
+
+# ❧

 # Export. Support AMD, CommonJS (Browserify), and browser globals.
 ((root, factory) ->
@@ -52,6 +49,10 @@
 )(@, ($, _, hlf) ->

   hlf.tip =
+    # It takes some boilerplate to write the plugins. To namespace when
+    # extending any jQuery API, we use custom `toString` helpers. Plugin
+    # namespaces (under the root`$.hlf`) each have a `debug` flag for granular
+    # logging.
     debug: off
     toString: _.memoize (context) ->
       switch context
@@ -60,13 +61,16 @@
         when 'class'  then 'js-tips'
         else 'hlf.tip'

+    # ❧
+
     # Tip Options
     # -----------
-    # Note the plugin instance gets extended with the options.
+    # NOTE: The plugin instance gets extended with the options.
     defaults: do (pre = 'js-tip-') ->
-      # - `$viewport` is the element in which the tip must fit into. It is not the
-      #   context, which stores the tip instance and by convention contains the
-      #   triggers.
+
+      # - `$viewport` is the element in which the tip must fit into. It is _not_
+      #   the context, which stores the tip instance and by convention contains
+      #   the triggers.
       $viewport: $ 'body'
       # - `triggerContent` can be the name of the trigger element's attribute or a
       #   function that provides custom content when given the trigger element.
@@ -74,7 +78,8 @@
       # - `cursorHeight` is the browser's cursor height. We need to know this to
       #   properly offset the tip to avoid cases of cursor-tip-stem overlap.
       cursorHeight: 12
-      # - Note that the direction data structure must be an array of
+      # - `defaultDirection` is used as a tie-breaker when selecting the best
+      #   direction. Note that the direction data structure must be an array of
       #   `components`, and conventionally with top/bottom first.
       defaultDirection: ['bottom', 'right']
       # - `safeToggle` prevents orphan tips, since timers are sometimes unreliable.
@@ -94,6 +99,8 @@
           </div>
         </div>
         """
+      # NOTE: The majority of presentation state logic is in the plugin
+      # stylesheet. We update the presentation state by using `classNames`.
       # - `classNames.stem` - Empty string to remove the stem.
       # - `classNames.follow` - Empty string to disable cursor following.
       classNames: do ->
@@ -134,7 +141,7 @@
         # - `snap.toXAxis` is the switch for snapping along x-axis. Off by default.
         # - `snap.toYAxis` is the switch for snapping along y-axis. Off by default.
         # - `snap.toTrigger` is the switch snapping to trigger that builds on top of
-        #   axis-snapping. On by default.
+        #   axis-snapping. On by default.
         snap:
           toTrigger: on
           toXAxis: off
@@ -151,48 +158,48 @@
           classNames.tip = 'js-tip js-snap-tip'
           classNames

-  # Tip API
-  # -------
-  # Note that most of the interface is intended as protected.
+  # ❧
+
+  # Tip Implementation
+  # ------------------
+  # Read on to learn about implementation details.
   class Tip

-    # The base constructor and `init` mostly do setup work that uses other
-    # subroutines when needed. Note that we're also keeping `$triggers` and
-    # `$context` as properties. `$context` is partly used to avoid directly
-    # binding event listeners to triggers, which can improve performance and
-    # allow dynamic binding.
+    # ❦ `constructor` keeps `$triggers` and `$context` as properties. `options`
+    # is further normalized.
     constructor: (@$triggers, options, @$context) ->
       for name, animation of options.animations when name isnt 'base'
         _.defaults animation, options.animations.base

+    # ❦ `init` offloads non-trivial setup to other subroutines
     init: ->
-      # Bind handler methods here after class setup completes.
       _.bindAll @, '_onTriggerMouseMove', '_setBounds'
-      # The element represented by this API is `$tip`. We build it. Alias it to
-      # `$el` for any mixins to consume.
-      @_setTip = ($tip) => @$tip = @$el = $tip
+      # Initialize tip element.
       @_setTip $ '<div>'
       # Infer `doStem` and `doFollow` flags from respective `classNames` entries.
       @doStem = @classNames.stem isnt ''
       @doFollow = @classNames.follow isnt ''
-      # Updated with `_setState`, `_state` toggles between: `awake`, `asleep`,
-      # `waking`, `sleeping`. The use case behind these states is the tip will
-      # remain visible and `awake` as long as there is a high enough frequency
-      # of relevant mouse activity. This is achieved with a simple base
-      # implementation around timers `_sleepCountdown` and `_wakeCountdown`.
+      # Initialize state, which is either: `awake`, `asleep`, `waking`,
+      # `sleeping`; respectively show, hide.
       @_setState 'asleep'
+      # The tip should remain visible and `awake` as long as there is a high
+      # enough frequency of relevant mouse activity. In addition to using
+      # `hoverIntent`, this is achieved with a simple base implementation around
+      # timers `_sleepCountdown` and `_wakeCountdown` and an extra reference to
+      # `_$currentTrigger`.
       @_wakeCountdown = null
       @_sleepCountdown = null
-      # `_$currentTrigger` helps manage trigger-related state.
       @_$currentTrigger = null
-      # Tip instances start off rendered and bound.
+      # Initialize tip. Note the initial render.
       @_render()
       @_bind()
-      # Also setup any context bindings.
+      # Initialize context.
       @_bindContext()
-      # Do this for initially provided triggers.
+      # Initialize triggers. Note the initial processing.
       @_processTriggers()
       @_bindTriggers()
+
+    _setTip: ($tip) => @$tip = @$el = $tip

     # Process `$triggers` and setup content, event, and positioning aspects.
     _processTriggers: ($triggers) ->


Added throttle to resizeTabHandles method also added min heigth and max height for tab handlers.

--- components/tabs/KDTabView.coffee
+++ components/tabs/KDTabView.coffee
@@ -3,6 +3,8 @@
   constructor:(options = {}, data)->

     options.resizeTabHandles  ?= no
+    options.maxHandleWidth    ?= 128
+    options.minHandleWidth    ?= 30
     @handles                   = []
     @panes                     = []
     @selectedIndex             = []
@@ -225,7 +227,7 @@
     handle = @getHandleByIndex index
     handle.getDomElement().addClass "hide-close-icon"

-  resizeTabHandles:->
+  resizeTabHandles: KD.utils.throttle ->
     return if not @getOptions().resizeTabHandles or @_tabHandleContainerHidden

     @tabHandleContainer.$().addClass "resize-in-action"
@@ -233,21 +235,25 @@

     visibleHandles   = []
     visibleTotalSize = 0
-    containerSize    = @tabHandleContainer.getWidth()
+    options          = @getOptions()
+    containerSize    = @tabHandleContainer.$().outerWidth no
+

     for handle in @handles
       unless handle.isHidden()
         visibleHandles.push handle
-        visibleTotalSize += handle.getOptimalWidth()
-
-    if containerSize < visibleTotalSize
+        visibleTotalSize += handle.$().outerWidth no
+
+    if containerSize < visibleTotalSize + 40
       for handle in visibleHandles
-        handle.$().css width: containerSize / visibleHandles.length - 10
+        possibleWidth = containerSize / visibleHandles.length - 10
+        handle.$().css width: if possibleWidth > options.maxHandleWidth then options.maxHandleWidth else possibleWidth
     else
       for handle in visibleHandles
-        handle.$().css width: handle.getOptimalWidth()
+        handle.$().css width: options.maxHandleWidth

     @resizeTimer = @utils.wait 300, =>
       @tabHandleContainer.$().removeClass "resize-in-action"
+  , 100

   _windowDidResize:(event)=> @resizeTabHandles event


do not get a collection for a non-logged in user

--- app/stores/favorites-store.coffee
+++ app/stores/favorites-store.coffee
@@ -15,15 +15,18 @@
     @favorited

   getFavorites: ->
-    query =
-      project_id: projectConfig.projectId
-      favorite: true
-      owner: userStore.userData?.user.login
+    if not userStore.userData?
+      @favorites = null
+    else
+      query =
+        project_id: projectConfig.projectId
+        favorite: true
+        owner: userStore.userData.user.login

-    api.type('collections').get(query)
-      .then ([favorites]) =>
-        @favorites = if favorites? then favorites else null
-        @getSubjectInCollection(@favorites)
+      api.type('collections').get(query)
+        .then ([favorites]) =>
+          @favorites = if favorites? then favorites else null
+          @getSubjectInCollection(@favorites)

   getSubjectInCollection: (favorites) ->
     if subjectStore.subject


Finished documenting Terminals.coffee. Accidentally fixed some problems.

--- coffeequate/src/terminals.coffee
+++ coffeequate/src/terminals.coffee
@@ -2,32 +2,37 @@

 	# Terminals for the equation tree.

+	# Base class for terminals.
 	class Terminal extends nodes.BasicNode
-		# Base class for terminals.
-		constructor: (@label) ->
-
-		# Question for Matt: why do the next two functions exist?
-		# I would have thought they should raise a NotImplementedError
+
+		# Evaluate this node.
+		#
+		# @throw [Error] Not implemented.
 		evaluate: ->
-
+			throw new Error("Not implemented.")
+
+		# Deep-copy this node.
+		#
+		# @throw [Error] Not implemented.
 		copy: ->
-			return new Terminal(@label)
-
+			throw new Error("Not implemented.")
+
+	# A constant in the equation tree, e.g. 0.5 or 1/2.
+	# Can be represented as a rational (1/2) or a float (0.5).
+	# If a constant is produced by negative exponentiation
+	# it becomes a rational; if it is entered as an integer then it
+	# is a rational; if it is entered as a float, then it remains
+	# a float.
+	# Rational `*` Rational -> Rational
+	# Rational `*` Float -> Float
+	# Float `*` Float -> Float
 	class Constant extends Terminal
-		# Constants in the equation tree, e.g. 0.5 or 1/2.
-		# Can be represented as a RATIONAL (1/2) or a FLOAT (0.5).
-		# If a constant is produced by a negative exponentiation (or division, but CQ doesn't use that)
-		# then it becomes a rational. If it is entered as an integer then it will also be a rational.
-		# If it is entered as a float, then it remains a float.
-		# Rational * Rational -> Rational
-		# Rational * Float -> Float
-		# Float * Float -> Float
-
-		# Make a new Constant
-		#
-		# @param numerator [String]
-		# @param denominator [String]
-		# @param mode [String] Optional. Can be rational or float.
+
+		# Make a new constant.
+		#
+		# @param numerator [String, Number] The numerator of the rational. If the number is a float, this is just the whole value.
+		# @param denominator [String, Number] The denominator of the rational.
+		# @param mode [String] Optional. Can be "rational" or "float" (default "rational").
 		constructor: (@numerator, @denominator=1, @mode="rational") ->
 			@cmp = -6

@@ -42,22 +47,22 @@
 					@numerator /= @denominator
 					@denominator = 1

-		# Evaluate the constant to be a float
-		#
-		# @return [Float] A float representation of this Constant
+		# Evaluate the constant.
+		#
+		# @return [Number] A float representation of this constant.
 		evaluate: ->
 			parseFloat(@numerator/@denominator)

-		#Deep copy this Constant
-		#
-		#@return [Constant] A copy of this Constant
+		# Deep-copy this constant.
+		#
+		# @return [Constant] A copy of this Constant
 		copy: ->
 			return new Constant(@numerator, @denominator, @mode)

-		#Compares this constant with another constant
-		#
-		#@param b [Constant]
-		#@return [Integer] returns an integer based on the comparison result (negative, neutral or positive)
+		# Compare this constant with another constant.
+		#
+		# @param b [Constant] The constant to compare with.
+		# @return [Number] An integer based on the comparison result. 1 if this is greater, -1 if vice versa, and 0 if equal.
 		compareSameType: (b) ->
 			if @evaluate() < b.evaluate()
 				return -1
@@ -66,10 +71,10 @@
 			else
 				return 1

-		# Multiplies by another constant and returns the resulting Constant
-		#
-		# @param b [Constant]
-		# return [Constant] The multiple of this and b
+		# Multiply by another constant.
+		#
+		# @param b [Constant] The constant to multiply by.
+		# return [Constant] The multiple of the two constants.
 		mul: (b) ->
 			if @mode == b.mode
 				newMode = @mode
@@ -78,9 +83,10 @@

 			return new Constant(@numerator * b.numerator, @denominator * b.denominator, newMode)

-		# Adds to another constant and returns the resulting Constant.
-		# @param b [Constant]
-		# @return [Constant] The addition of this and b
+		# Add another constant to this one.
+		#
+		# @param b [Constant] The constant to add.
+		# @return [Constant] The sum of the two constants.
 		add: (b) ->
 			if @mode == b.mode
 				newMode = @mode
@@ -88,9 +94,11 @@
 				newMode = "float"

 			return new Constant(b.denominator * @numerator + @denominator * b.numerator, @denominator * b.denominator, newMode)
-		# This constant to the power of another constant
-		# @param b [Constant]
-		# @return [Constant] Returns a constant of base this to power b
+
+		# Raise this constant to the power of another.
+		#
+		# @param b [Constant] The exponent.
+		# @return [Constant, Pow] A constant of this to the given exponent, or a power node if this is non-simplifiable.
 		pow: (b) ->
 			if @mode == "rational"
 				if b.mode == "rational"
@@ -132,32 +140,34 @@
 				# Also returning a float.
 				return new Constant(Math.pow(@evaluate(), b.evaluate()), 1, "float")

-		# Tests the equality between this Constant and another Constant.
-		# @param b [Constant]
-		# @return [Boolean] Whether or not the two Constants are equal
+		# Test the equality between this constant and another object.
+		# @param b [Object] The object to check.
+		# @return [Boolean] Whether or not the two objects are equal.
 		equals: (b) ->
 			unless b instanceof Constant
 				return false
 			return @evaluate() == b.evaluate()

-		# Does nothing - included for API parity
-		# @param replacements [???]
+		# Alias of copy. Included for API parity.
+		#
+		# @param replacements [Object] A map of replacements. Irrelevant.
 		replaceVariables: (replacements) ->
 			@copy() # Does nothing - this is a constant.

+		# Get all variables in this terminal. Included for API parity.
+		#
+		# @return [Array<Object>] Returns `[]`.
 		getAllVariables: ->
 			[]

-		# Substitute values into the constant - does nothing as this is a constant;
-		# Included for API parity
+		# Alias of copy. Included for API parity.
 		#
-		#@param substitutions [Object] A map of variable labels to their values. Values can be integers, Expressions, Terminals or BasicNodes
-		#@param uncertaintySubstitutions [???] I don't know how this works
+		# @param substitutions [Object] Map of substitutions. Irrelevant.
+		# @param uncertaintySubstitutions [Object] Map of uncertainty substitutions. Irrelevant.
 		sub: (substitutions, uncertaintySubstitutions) ->
 			@copy()

-		# Gets greatest common divisor and divides out to simplify Constant
-		#
+		# Simplify this fraction in-place using Euclid's method.
 		simplifyInPlace: ->
 			# Get the greatest common divisor.
 			a = @numerator
@@ -172,52 +182,52 @@
 			@denominator /= gcd
 			@denominator = Math.round(@denominator*10)/10

-		# Simplify this constant
-		#
-		# @return [Constant] A simplified copy of the current Constant
+		# Simplify this constant.
+		#
+		# @return [Constant] A simplified version of this constant.
 		simplify: ->
 			constant = @copy()
 			constant.simplifyInPlace()
 			return constant

-		# Expands the constant
-		# @return [Constant] A simplified constant
+		# Expand this constant. Included for API parity.
+		# @return [Constant] A copy of this constant.
 		expand: ->
 			@copy()

-		# Expands and simplifies
-		# @return [Constant] A simplified and expanded constant
+		# Expand and simplify. Included for API parity.
+		# @return [Constant] Simplified constant.
 		expandAndSimplify: ->
 			@simplify()

-		# Substitutes
+		# Substitute an expression into this. Included for API parity.
+		#
+		# @deprecated
 		substituteExpression: (sourceExpression, variable, equivalencies) ->
 			[@copy()]

-		# Gets uncertainty of the Constant
-		#
-		# @return [Constant] A constant of 0
+		# Get uncertainty of this constant.
+		#
+		# @return [Constant] 0, as there is no uncertainty in a constant.
 		getUncertainty: ->
 			new Constant(0)

-		# Gets the units of the Constant (does nothing since Constant)
-		#
-		# @return [null] null
+		# Get the units of variables. Included for API parity.
+		#
+		# @return [Object] null - Constants don't have units.
 		getVariableUnits: ->
 			null

-		#Sets units of the Constant (does nothing)
-		#
-		# @param variable [???]
-		# @param equivalencies [???]
-		# @param units [String]
-		# @return null
+		# Set the units of variables. Does nothing. Included for API parity.
+		#
+		# @param variable [String] Variable label. Irrelevant.
+		# @param equivalencies [Object] Equivalencies map. Irrelevant.
+		# @param units [BasicNode] Units for the variable. Irrelevant.
 		setVariableUnits: (variable, equivalencies, units) ->
-			null
-
-		# Creates a drawing node to export Constant for viewing.
-		#
-		# @return [FractionNode, NumberNode] A drawing node for viewing.
+
+		# Create a drawing node representing this constant
+		#
+		# @return [DrawingNode] A drawing node representing this constant.
 		toDrawingNode: ->
 			NumberNode = prettyRender.Number
 			FractionNode = prettyRender.Fraction
@@ -225,34 +235,36 @@
 				return new NumberNode(@numerator)
 			return new FractionNode(new NumberNode(@numerator), new NumberNode(@denominator))

+		# Differentiate this constant.
+		#
+		# return [Constant] 0, because constants are constant.
 		differentiate: (variable) ->
 			return new Constant(0)

-	# A class to represent symbolic constants in the equation tree; for e.g. Ï€
-	#
+	# Represents symbolic constants in the equation tree, such as π.
 	class SymbolicConstant extends Terminal

-		# Symbolic constants in the equation tree, e.g. Ï€
-		# Creates a new SymbolicConstant.
-		# @param label [String]
-		# @param value [Integer, Float] Optional. Default is null.
-		# @param units [String] Optional. Default is null.
+		# Make a new symbolic constant.
+		#
+		# @param label [String] The label of this constant (such as π).
+		# @param value [Number] Optional. Value of the symbolic constant (default is null).
+		# @param units [BasicNode, Terminal] Optional. Units of the constant (default is null).
 		constructor: (@label, @value=null, @units=null) ->
 			@cmp = -5

-		# Returns a deep copy of the SymbolicConstant
-		#
-		# @return [SymbolicConstant] Returns a new copy of the Symbolic Constant
+		# Deep-copy the symbolic constant.
+		#
+		# @return [SymbolicConstant] A new copy of the Symbolic Constant.
 		copy: ->
 			return new SymbolicConstant(@label, @value, @units)

-		# Compares this SymbolicConstant with another SymbolicConstant.
-		#
-		# @param b [SymbolicConstant]
-		# @return [Integer 0,1,2] Returns the difference 'discriminator' of the two SymbolicConstants
+		# Compare this symbolic constant with another symbolic constant.
+		# Note that this compares labels, not values - this is a lexiographic sort.
+		#
+		# @param b [SymbolicConstant] The constant to compare with.
+		# @return [Number] 1 if this constant is greater, -1 if vice-versa, and 0 if equal.
 		compareSameType: (b) ->
-			# Compare this object with another of the same type.
 			if @label < b.label
 				return -1
 			else if @label == b.label
@@ -260,123 +272,138 @@
 			else
 				return 1

-		# Evaluates the SymbolicConstant
-		# @return [Integer, Float] Returns the current value of the SymbolicConstant
+		# Evaluate the symbolic constant.
+		#
+		# @return [Number] The value of the symbolic constant, if it has one, or the value in the lookup table. Null otherwise.
 		evaluate: ->
-			@value
-
-		# Checks equality of this and another SymbolicConstant
+			if @value?
+				return @value
+			if @label of constants
+				return constants[@label]
+			return null
+
+		# Check equality of this and another object.
 		#
-		# @param b [SymbolicConstant]
-		# @return [Boolean] Whether or not the two SymbolicConstants are equal
+		# @param b [Object] The object to compare with.
+		# @return [Boolean] Whether the objects are equal.
 		equals: (b) ->
 			unless b instanceof SymbolicConstant
 				return false
 			return @label == b.label and @value == b.value

-		# Does nothing - included for API parity
-		#
-		# @params replacements [???]
-		# @return [SymbolicConstant]
+		# Replace variables - does nothing. Included for API parity.
+		#
+		# @params replacements [Object] Map of replacements. Irrelevant.
+		# @return [SymbolicConstant] A copy of this constant.
 		replaceVariables: (replacements) ->
 			@copy() # Does nothing - this is a constant.

-		#Does nothing??? Matt, please check
+		# Get all variables in this node. Included for API parity.
+		#
+		# @return [Array<Object>] []
 		getAllVariables: ->
 			[]

-		# Substitute values into the SymbolicConstant - does nothing as this is a SymbolicConstant;
-		# Included for API parity
+		# Substitute values - side effect of evaluation if evaluateSymbolicConstants is true.
 		#
-		#@param substitutions [Object] A map of variable labels to their values. Values can be integers, Expressions, Terminals or BasicNodes
-		#@param uncertaintySubstitutions [???] I don't know how this works
+		# @param substitutions [Object] Substitutions map. Irrelevant, included for API parity.
+		# @param uncertaintySubstitutions [Object] Uncertainty substitutions map. Irrelevant.
+		# @param equivalencies [Object] Optional. Equivalencies object. Irrelevant.
+		# @param assumeZeroUncertainty [Boolean] Optional. Whether to assume unknown uncertainties are zero. Irrelevant.
+		# @param evaluateSymbolicConstants [Boolean] Optional. Whether to evaluate this constant (default is false).
+		# @return [SymbolicConstant, Constant] A copy of this constant if not evaluating symbolic constants, or an evaluated constant otherwise.
+		# @todo Change the way equivalencies are handled. [#62](https://github.com/MatthewJA/Coffeequate/issues/62)
 		sub: (substitutions, uncertaintySubstitutions, equivalencies=null, assumeZeroUncertainty=false, evaluateSymbolicConstants=false) ->
 			unless evaluateSymbolicConstants
 				return @copy()
+			if @value?
+				return new Constant(@value)
 			if @label of constants
 				return new Constant(constants[@label])
-
-		# Simplify the SymbolicConstant
-		#
-		# @return [SymbolicConstant] Returns a deep copy of the SymbolicConstant
+			return @copy()
+
+		# Simplify this constant.
+		#
+		# @return [SymbolicConstant] A copy of the constant.
 		simplify: ->
 			@copy()

-		# Expand the SymbolicConstant
-		#
-		# @return [SymbolicConstant] Returns a deep copy of the SymbolicConstant
+		# Expand this constant.
+		#
+		# @return [SymbolicConstant] A copy of the constant.
 		expand: ->
 			@copy()

-		# Expand and simplify the SymbolicConstant
-		#
-		# @return [SymbolicConstant] Returns a deep copy of the SymbolicConstant
+		# Expand and simplify this constant.
+		#
+		# @return [SymbolicConstant] A copy of the constant.
 		expandAndSimplify: ->
 			@copy()

-		# Substitutes an expression into the SymbolicConstant
-		#
-		# @param sourceExpression [Expression]
-		# @param variable [???]
-		# @param equivalencies []
+		# Substitutes an expression into this constant.
+		#
+		# @deprecated
 		substituteExpression: (sourceExpression, variable, equivalencies) ->
 			[@copy()]

-		# Gets the uncertainty of the SymbolicConstant
-		#
-		# @return [Constant] Returns a Constant of 0
+		# Get uncertainty of this constant.
+		#
+		# @return [Constant] 0, as we assume no uncertainty in a symbolic constant.
 		getUncertainty: ->
 			new Constant(0)

-		# Gets the units of the SymbolicConstant i.e. null
-		# @return null
-		getVariableUnits: ->
+		# Get units of variable children of this constant. Included for API parity.
+		#
+		# @param variable [String] The variable to check for. Irrelevant.
+		# @return [Object] null - no children.
+		getVariableUnits: (variable) ->
 			null

-		# Sets the units of the SymbolicConstant
-		# @param variable
-		# @param equivalencies
-		# @param units
+		# Set units of variable children. Included for API parity.
+		#
+		# @param variable [String] The variable to set for. Irrelevant.
+		# @param equivalencies [Object] Equivalencies object. Irrelevant.
+		# @param units [BasicNode, Terminal] The units to set. Irrelevant.
+		# @todo Change the way equivalencies are handled. [#62](https://github.com/MatthewJA/Coffeequate/issues/62)
 		setVariableUnits: (variable, equivalencies, units) ->
 			null

-		# Creates a DrawingNode of the SymbolicConstant to be viewed
-		#
-		# @return [VariableNode] Returns a prettyRendered DrawingNode of the SymbolicConstant
+		# Make a drawing node representing this constant.
+		#
+		# @return [DrawingNode] Renderable drawing node representing this constant.
 		toDrawingNode: ->
 			VariableNode = prettyRender.Variable
 			return new VariableNode(@label, "constant symbolic-constant")

-		# Differentiates the SymbolicConstant
-		# @param variable [???]
-		# @return [Constant] Returns a Constant of 0
+		# Differentiate this constant.
+		#
+		# @param variable [String] Variable to differentiate with respect to.
+		# @return [Constant] 0, as constants are constant.
 		differentiate: (variable) ->
 			return new Constant(0)

-	# A class to represent Variables in the Equation tree; e.g. 'm'
+	# Represents variables in the equation tree.
 	class Variable extends Terminal
-		# Variables in the equation tree, e.g. m
-
-		# Make a new Variable
+
+		# Make a new Variable.
 		#
-		# @param label [String]
-		# @param units [???] Optional. Defaults to null.
+		# @param label [String] The label of this variable.
+		# @param units [BasicNode, Terminal] Optional. Units of this variable (default is null).
 		constructor: (@label, @units=null) ->
 			@cmp = -4

-		# Creates a deep copy of the current Variable
-		#
-		# @return [Variable] Returns a deep copy of the current Variable
+		# Deep-copy this Variable.
+		#
+		# @return [Variable] A copy of this Variable.
 		copy: ->
 			return new Variable(@label, @units)

-		# Compares this Variable with another Variable
-		#
-		# @param b [Variable] The other Variable
-		# @return [Integer -1, 0, 1] Returns an integer to indicate less than, equal to or greater than the other Variable
+		# Compare this Variable with another Variable.
+		#
+		# @param b [Variable] The variable to compare with.
+		# @return [Number] 1 if this is greater, 0 if equal, and -1 if this is lesser.
 		compareSameType: (b) ->
-			# Compare this object with another of the same type.
 			if @label < b.label
 				return -1
 			else if @label == b.label
@@ -384,10 +411,12 @@
 			else
 				return 1

-		# Checks equality of this Variable and another Variable
-		#
-		# @param b [Variable] The other variable
-		# @param equivalencies [???] Optional.
+		# Check equality of this Variable and another object.
+		#
+		# @param b [Object] The other object to compare with.
+		# @param equivalencies [Object] Equivalencies object. Optional (default is null).
+		# @return [Boolean] Whether the objects are equal.
+		# @todo Change the way equivalencies are handled. [#62](https://github.com/MatthewJA/Coffeequate/issues/62)
 		equals: (b, equivalencies=null) ->
 			# Check equality between this and some other object.
 			unless b instanceof Variable
@@ -398,22 +427,27 @@
 			else
 				return b.label == @label

-		# Replaces the variables with new variables (MATT I DON'T GET THIS ONE)
+		# Replace variable labels.
+		#
+		# @param replacements [Object] A map of variable labels to replacement labels.
+		# @return [Variable] This variable, possibly with its name replaced.
 		replaceVariables: (replacements) ->
 			copy = @copy()
 			if @label of replacements
 				copy.label = replacements[@label]
 			return copy

-		# Gets all variables
-		# @return [List of Strings] Returns the variable label
+		# Get a list of children variable labels.
+		#
+		# @return [Array<String>] An array containing just this label.
 		getAllVariables: ->
 			[@label]

-		# Substitutes values into the Variable
-		#
-		# @param [???] substitutions
-		# @param [???] uncertaintySubstitutions
+		# Substitute values into the Variable.
+		#
+		# @param substitutions [Object] A map of variable labels to their values.
+		# @param uncertaintySubstitutions [Object] A map of uncertainty labels to their values.
+		# @return [Variable, Constant] This variable, possibly substituted.
 		sub: (substitutions, uncertaintySubstitutions) ->
 			if @label of substitutions
 				substitute = substitutions[@label]
@@ -424,13 +458,9 @@
 			else
 				return @copy()

-		# Substitutes an Expression into the Variable
-		#
-		# @param sourceExpression [sourceExpression] The source expression to be used.
-		# @param variable [???]
-		# @param equivalencies [???] Optional.
-		# @param eliminate [???] Optional.
-		# @return [Variable] Returns the resulting Variable from the substitution
+		# Substitute an expression into the Variable.
+		#
+		# @deprecated
 		substituteExpression: (sourceExpression, variable, equivalencies=null, eliminate=false) ->
 			# Replace all instances of a variable with an expression.

@@ -450,17 +480,18 @@
 			else
 				return [@copy()]

-		# Gets the uncertainty of the Variable
-		#
-		# @return [???] IDK how this one works either TBH
+		# Get uncertainty of this Variable.
+		#
+		# @return [Uncertainty] Symbolic uncertainty of this Variable.
 		getUncertainty: ->
 			new Uncertainty(@label)

-		# Gets the units of the Variable
-		#
-		# @param variable [???]
-		# @param equivalencies [???]
-		# @return [units] The current units of the Variable
+		# Get the units of a given Variable.
+		#
+		# @param variable [String] Label of the variable to get units for.
+		# @param equivalencies [Object] Equivalencies object.
+		# @return [BasicNode, Terminal] Units if this is the Variable being looked for. null otherwise.
+		# @todo Change the way equivalencies are handled. [#62](https://github.com/MatthewJA/Coffeequate/issues/62)
 		getVariableUnits: (variable, equivalencies) ->
 			if equivalencies?
 				if @label in equivalencies.get(variable)
@@ -469,11 +500,12 @@
 				return @units
 			return null

-		# Sets the units for the Variable
-		#
-		# @param variable [???]
-		# @param equivalencies [???]
-		# @param units [???]
+		# Set units for a given Variable.
+		#
+		# @param variable [String] The variable to set units for.
+		# @param equivalencies [Object] Equivalencies object.
+		# @param units [BasicNode, Terminal] The units to set.
+		# @todo Change the way equivalencies are handled. [#62](https://github.com/MatthewJA/Coffeequate/issues/62)
 		setVariableUnits: (variable, equivalencies, units) ->
 			if equivalencies?
 				if @label in equivalencies.get(variable)
@@ -481,58 +513,59 @@
 			else if @label == variable
 				@units = units

-		# Simplifies the Variable
-		#
-		# @return [Variable] A deep copy of the Variable
- 		simplify: ->
-			@copy()
-
-		# Expand the Variable
-		#
-		# @return [Variable] A deep copy of the Variable
+		# Simplify the Variable.
+		#
+		# @return [Variable] Copy of the Variable.
+		simplify: ->
+			@copy()
+
+		# Expand the Variable.
+		#
+		# @return [Variable] Copy of the Variable.
 		expand: ->
 			@copy()

-		# Expands and simplifies the Variable
-		#
-		#@return [Variable] A deep copy of the Variable
+		# Expand and simplify the Variable.
+		#
+		# @return [Variable] Copy of the Variable.
 		expandAndSimplify: ->
 			@copy()

-		# Returns a DrawingNode of the Variable to be viewed
-		#
-		# @return [VariableNode] A DrawingNode version of the variable
+		# Make a drawing node representing this Variable.
+		#
+		# @return [DrawingNode] Drawing node representing this variable.
 		toDrawingNode: ->
 			VariableNode = prettyRender.Variable
 			return new VariableNode(@label)

-		# Differentiates the variable
-		#
-		# @param variable [Variable]
-		# @return [Constant] Returns a constant of value either 1 or 0 (Mitchell: not sure how this actually works)
+		# Differentiate the variable.
+		#
+		# @param variable [String] The label of the variable to differentiate with respect to.
+		# @return [Constant] The differentiated variable.
 		differentiate: (variable) ->
 			if variable == @label
 				return new Constant(1)
 			return new Constant(0)

-	# Defines an Uncertainty object in the equation tree; for e.g. sigma_m
-	# ??? I know nothing about this object really, it's going to be very poorly documented and needs to be edited
+	# Represents an uncertainty.
 	class Uncertainty extends Terminal

-		#Creates an Uncertainty (that sounds really beautiful doesn't it?)
-		#
-		# @param label [String] Label of the Uncertainty object
+		# Make an Uncertainty.
+		#
+		# @param label [String] Label of the variable this Uncertainty is for.
 		constructor: (@label) ->
-			# Matt: what do I do here?
 			@cmp = -4.5

+		# Deep-copy the Uncertainty.
+		#
+		# @return [Uncertainty] A copy of the Uncertainty.
 		copy: ->
 			return new Uncertainty(@label)

-		#Compares the value of this Uncertainty and another Uncertainty
-		#
-		# @param b [Uncertainty]
-		# @return [Integer -1, 0, 1]
+		# Compares this Uncertainty with another Uncertainty.
+		#
+		# @param b [Uncertainty] Uncertainty to compare with.
+		# @return [Number] 1 if this is greater, 0 if equal, -1 if this is lesser.
 		compareSameType: (b) ->
 			if @label < b.label
 				return -1
@@ -541,8 +574,12 @@
 			else
 				return 1

-		# Before commit: think about this more before asking Matt
-		# Matt: should we do this?
+		# Check equality of this and another object.
+		#
+		# @param b [Object] Object to compare with.
+		# @param equivalencies [Object] Equivalencies object. Optional (default is null).
+		# @return [Boolean] Whether the objects are equal.
+		# @todo Change the way equivalencies are handled. [#62](https://github.com/MatthewJA/Coffeequate/issues/62)
 		equals: (b, equivalencies=null) ->
 			# Check equality between this and some other object.
 			unless b instanceof Uncertainty
@@ -553,15 +590,28 @@
 			else
 				return b.label == @label

+		# Replace variable labels.
+		#
+		# @param replacements [Object] Map of variable labels to new labels.
+		# @return [Uncertainty] This node with its label possibly replaced.
 		replaceVariables: (replacements) ->
 			copy = @copy()
 			if @label of replacements
 				copy.label = replacements[@label]
 			return copy

+		# Get variable labels.
+		#
+		# @return [Array<String>] An array containing just this label.
 		getAllVariables: ->
 			[@label]

+		# Substitute values.
+		#
+		# @param substitutions [Object] Substitutions map. Irrelevant; included for API parity.
+		# @param uncertaintySubstitutions [Object] Map of uncertainty labels to uncertainty values.
+		# @param equivalencies [Object] Equivalencies object. Optional (default is null).
+		# @param assumeZero [Boolean] Whether to assume this uncertainty is zero if its value is not defined.
 		sub: (substitutions, uncertaintySubstitutions, equivalencies=null, assumeZero=false) ->
 			if @label of uncertaintySubstitutions and uncertaintySubstitutions[@label]?
 				substitute = uncertaintySubstitutions[@label]
@@ -572,31 +622,59 @@
 			else
 				return if not assumeZero then @copy() else new Constant("0")

+		# Substitute an expression.
+		#
+		# @deprecated
 		substituteExpression: (sourceExpression, variable, equivalencies=null, eliminate=false) ->
 			throw new Error("Can't sub uncertainties")

+		# Get uncertainty.
+		#
+		# @throw [Error] Not implemented for uncertainties.
 		getUncertainty: ->
 			throw new Error("Can't take uncertainty of an uncertainty")

+		# Get variable units.
+		#
+		# @throw [Error] Not implemented for uncertainties.
 		getVariableUnits: (variable, equivalencies) ->
 			throw new Error("Can't do that with uncertainties")

+		# Set variable units.
+		#
+		# @throw [Error] Not implemented for uncertainties.
 		setVariableUnits: (variable, equivalencies, units) ->
 			throw new Error("Can't do that with uncertainties")

+		# Simplify this node.
+		#
+		# @return [Uncertainty] A copy of this uncertainty.
 		simplify: ->
 			@copy()

+		# Expand this node.
+		#
+		# @return [Uncertainty] A copy of this uncertainty.
 		expand: ->
 			@copy()

+		# Expand and then simplify this node.
+		#
+		# @return [Uncertainty] A copy of this uncertainty.
 		expandAndSimplify: ->
 			@copy()

+		# Make a new drawing node representing this uncertainty.
+		#
+		# @return [DrawingNode] A drawing node representing this uncertainty.
 		toDrawingNode: ->
 			UncertaintyNode = prettyRender.Uncertainty
 			return new UncertaintyNode(@label)
-		# Don't differentiate uncertainties. It won't work. (Throws error 'Can't differentiate uncertainties!')
+
+		# Differentiate.
+		# Don't differentiate uncertainties. It won't work.
+		#
+		# @throw [Error] Not implemented for uncertainties.
 		differentiate: (variable) ->
 			throw new Error("Can't differentiate uncertainties!")


Add Rename to Doc Server provider

Add Rename to Doc Server provider

--- src/code/providers/document-store-provider.coffee
+++ src/code/providers/document-store-provider.coffee
@@ -1,12 +1,13 @@
 {div, button, span} = React.DOM

 documentStore = "http://document-store.herokuapp.com"
-authorizeUrl     = "#{documentStore}/user/authenticate"
-checkLoginUrl    = "#{documentStore}/user/info"
-listUrl          = "#{documentStore}/document/all"
-loadDocumentUrl      = "#{documentStore}/document/open"
-saveDocumentUrl      = "#{documentStore}/document/save"
-removeDocumentUrl    = "#{documentStore}/document/delete"
+authorizeUrl      = "#{documentStore}/user/authenticate"
+checkLoginUrl     = "#{documentStore}/user/info"
+listUrl           = "#{documentStore}/document/all"
+loadDocumentUrl   = "#{documentStore}/document/open"
+saveDocumentUrl   = "#{documentStore}/document/save"
+removeDocumentUrl = "#{documentStore}/document/delete"
+renameDocumentUrl = "#{documentStore}/document/rename"

 tr = require '../utils/translate'
 isString = require '../utils/is-string'
@@ -208,6 +209,20 @@
       error: ->
         callback "Unable to load "+metadata.name

+  rename: (metadata, newName, callback) ->
+    $.ajax
+      url: renameDocumentUrl
+      data:
+        recordid: metadata.providerData.id
+        newRecordname: newName
+      context: @
+      xhrFields:
+        withCredentials: true
+      success: (data) ->
+        callback null, metadata
+      error: ->
+        callback "Unable to rename "+metadata.name
+
   _addParams: (url, params) ->
     return url unless params
     kvp = []


adding pandas plot source

adding pandas plot source

--- subtree/bokehjs/static/coffee/pandas/pandas.coffee
+++ subtree/bokehjs/static/coffee/pandas/pandas.coffee
@@ -1,4 +1,5 @@
 base = require("../base")
+datasource = require("../common/datasource")
 ContinuumView = require("../common/continuum_view").ContinuumView
 HasParent = base.HasParent
 HasProperties = base.HasProperties
@@ -9,6 +10,15 @@
 coll = Collection.extend({model : IPythonRemoteData})
 exports.ipythonremotedatas = new coll()
 ENTER = 13
+
+class PandasPlotSource extends datasource.ColumnDataSource
+  type : 'PandasPlotSource'
+
+coll = Collection.extend({model : PandasPlotSource})
+exports.pandasplotsources = new coll()
+
+class PandasPlotSources extends Backbone.Collection
+  model : PandasPlotSource

 class PandasPivotView extends ContinuumView
   template : require("./pandaspivot")


Fix issue when radio button value is null vs false


[skip] Extracted `endEdit` from `cancelEdit` so that the two actions can be differentiated (4m)

--- vendor/assets/javascripts/neat/model_editor.coffee
+++ vendor/assets/javascripts/neat/model_editor.coffee
@@ -47,6 +47,11 @@
   cancelEdit: (e)->
     e?.preventDefault()
     e?.stopImmediatePropagation()
+    @endEdit()
+
+  endEdit: (e)->
+    e?.preventDefault()
+    e?.stopImmediatePropagation()
     if @inEdit()
       @$el.find(':focus').blur()
       @$el.removeClass('editor').addClass('neat-editable')
@@ -84,7 +89,7 @@
           @onSaveSuccess()
         error: _.bind(@onSaveError, @)

-    @cancelEdit()
+    @endEdit()

   okToSave: (attributes)->
     true
@@ -120,7 +125,7 @@
         wait: true
         success: => @onDestroySuccess
         error: _.bind(@onSaveError, @)
-      @cancelEdit()
+      @endEdit()

   confirmDestroy: (resource, callback)->
     if confirm("Delete this #{resource}?")


mixpanel: move KONFIG to inside instance method

--- workers/social/lib/social/models/user/index.coffee
+++ workers/social/lib/social/models/user/index.coffee
@@ -671,9 +671,9 @@
       return callback message: "Guests group not found!"  unless guestsGroup?
       guestsGroup.removeMember account, callback

-  mixpanel  = Mixpanel.init KONFIG.mixpanel
-
   @convert = secure (client, userFormData, callback) ->
+    mixpanel  = Mixpanel.init KONFIG.mixpanel
+
     { connection, sessionToken : clientId } = client
     { delegate : account } = connection
     { nickname : oldUsername } = account.profile


Add sexy fades

Add sexy fades

--- app/assets/javascripts/backbone/views/tree_view.js.coffee
+++ app/assets/javascripts/backbone/views/tree_view.js.coffee
@@ -7,7 +7,9 @@
   render_tree: () =>
     console.log("View says: Did fetch! This: ", this)
     $("#indicator").hide()
+    @$el.hide()
     @$el.html @model.get("data")
+    @$el.fadeIn("slow")

   render_loading: () =>
     loading_indicator = $("<div />").attr("id", "indicator")


Dialog::'s addTab() and switchTab() are public

--- app/assets/javascripts/uploadcare/widget/dialog.js.coffee
+++ app/assets/javascripts/uploadcare/widget/dialog.js.coffee
@@ -99,7 +99,7 @@
         else
           @__hideTab 'preview'

-      __addTab: (name) ->
+      addTab: (name) ->
         {tabs} = uploadcare.widget

         tabCls = switch name
@@ -130,7 +130,7 @@

         return tab

-      __switchTab: (@currentTab) ->
+      switchTab: (@currentTab) ->
         @content.find('.uploadcare-dialog-body')
           .find('.uploadcare-dialog-selected-tab')
             .removeClass('uploadcare-dialog-selected-tab')


Add checkIfLikedBefore to instance methods

--- server/app/bongo/models/messages/post.coffee
+++ server/app/bongo/models/messages/post.coffee
@@ -33,8 +33,8 @@
       static          : ['create','on','one']
       instance        : [
         'on','reply','restComments','commentsByRange'
-        'like','fetchLikedByes','mark','unmark','fetchTags'
-        'delete','modify','fetchRelativeComments'
+        'like','fetchLikedByes', 'mark','unmark','fetchTags'
+        'delete','modify','fetchRelativeComments','checkIfLikedBefore'
       ]
     schema            : schema
     relationships     :


row class changed to dynamic-row to avoid collision with bootstrap

--- vendor/assets/javascripts/button_add/hook.js.coffee
+++ vendor/assets/javascripts/button_add/hook.js.coffee
@@ -1,6 +1,6 @@
 jQuery ->
     $("form.dynamic").on 'click', '.remove-button', (event) ->
-        $row = $(this).closest('.row')
+        $row = $(this).closest('.dynamic-row')
         $row.find("input[type=hidden]").val(1);
         $row.hide()


f95 file extension was added

f95 file extension was added

--- src/languages/fortran.coffee
+++ src/languages/fortran.coffee
@@ -16,6 +16,8 @@
   extensions: [
     "f90"
     "F90"
+    "f95"
+    "F95"
   ]

   ###


Reduce indent before checkBlankLine

Reduce indent before checkBlankLine

--- tasks/sass-format.coffee
+++ tasks/sass-format.coffee
@@ -97,6 +97,7 @@
               okMsg.push('空白行有り')
           else
             regex = new RegExp('^(['+indentChar+']{'+(indentStep * indent)+'}){1,}({|[^{]+[,{])$')
+
             if regex.test(text)
               if options.lang is 'en'
                 errMsg.push('No blank line!')
@@ -238,10 +239,10 @@
               #閉じカッコ
               if /^([ \t]+)?.*}([ \t]+)?$/.test(text[i])

+                indent--
+
                 if options.blankLine.close
                   checkBlankLine(indent,text[i+1])
-
-                indent--

               if options.debug