Updated toggle switch coffee to 2 spaces.

--- src/components/toggle-switch/toggle-switch.coffee
+++ src/components/toggle-switch/toggle-switch.coffee
@@ -11,252 +11,255 @@
 #         ~~~~                 \__\/        \__\/

 class ToggleSwitch
-    #        ___                   ___          ___
-    #       /  /\         ___     /  /\        /  /\
-    #      /  /:/        /  /\   /  /::\      /  /::\
-    #     /  /:/        /  /:/  /  /:/\:\    /  /:/\:\
-    #    /  /:/  ___   /  /:/  /  /:/  \:\  /  /:/~/:/
-    #   /__/:/  /  /\ /  /::\ /__/:/ \__\:\/__/:/ /:/___
-    #   \  \:\ /  /://__/:/\:\\  \:\ /  /:/\  \:\/:::::/
-    #    \  \:\  /:/ \__\/  \:\\  \:\  /:/  \  \::/~~~~
-    #     \  \:\/:/       \  \:\\  \:\/:/    \  \:\
-    #      \  \::/         \__\/ \  \::/      \  \:\
-    #       \__\/                 \__\/        \__\/
-
-    # Must be initialized with a toggle element
-    constructor: (details) ->
-        # Accept a pre-made jQuery object
-        if details instanceof jQuery or toString.call(details) is "[object String]"
-            details = $(details)
-            $input = details.children "input"
-            $label = details.children "label"
-
-            details.attr
-                "role": "checkbox"
-                "aria-checked": $input.prop("checked")
-
-            this[0] = details
-            @_input = $input
-            @_label = $label
-
-            # Bind the keypress event to manipulate the toggle
-            # and the change event to update the aria-role
-            toggle = this
-            $input.on "change", ->
-                toggle.attr "aria-checked", toggle.checked()
-
-            details.on "keypress", (event) ->
-                if event.charCode is 32
-                    event.preventDefault()
-                    toggle.toggle()
-
-        # Create a brand new instance
-        else
-            defaults =
-                # Whether the new toggle should be toggled on or not
-                # These five are all aliases for one another
-                active: false
-                on: false
-                checked: false
-                toggled: false
-                toggle: false
-
-                container: undefined
-                disabled: false         # Whether the toggle should be disabled
-                id: undefined           # Custom ID to use for the input/ label
-                label: ""               # Label to use for the toggle (hidden in default CSS)
-                name: "toggle"          # Name attribute to use for the input
-
-            options = $.extend defaults, details
-
-            # Create the toggle ID
-            toggleID = if options.id? then options.id else "toggle-switch-#{ToggleSwitchController._uniqueID()}"
-
-            # Replace HTML template items with relevant strings
-            toggleHTML = ToggleSwitch.template.replace /(TOGGLE_ID|LABEL|NAME)/g, (match) ->
-                switch match
-                    when "TOGGLE_ID" then toggleID
-                    when "LABEL" then options.label
-                    when "NAME" then options.name
-
-            newToggle = new ToggleSwitch $(toggleHTML)
-
-            # Respect the disable, toggled, and toggleColor options
-            newToggle.disable() if options.disabled
-            newToggle.toggle() if (options.active or options.on or options.checked or options.toggled or options.toggle)
-
-            # Find the appropriate container
-            $container = undefined
-            if options.container?
-                $container = if options.container instanceof jQuery then options.container else $(options.container)
-                # If specified container doesn't exist, go to body
-                $container = "body" if $container.length < 1
-            else
-                $container = "body"
-
-            newToggle[0].appendTo $container
-
-            return newToggle
-
-
-    # Remove the HTML element
-    remove: -> this[0].remove()
-
-
-
-
-
-    #        ___                   ___                   ___
-    #       /  /\         ___     /  /\         ___     /  /\
-    #      /  /:/_       /  /\   /  /::\       /  /\   /  /:/_
-    #     /  /:/ /\     /  /:/  /  /:/\:\     /  /:/  /  /:/ /\
-    #    /  /:/ /::\   /  /:/  /  /:/~/::\   /  /:/  /  /:/ /:/_
-    #   /__/:/ /:/\:\ /  /::\ /__/:/ /:/\:\ /  /::\ /__/:/ /:/ /\
-    #   \  \:\/:/~/://__/:/\:\\  \:\/:/__\//__/:/\:\\  \:\/:/ /:/
-    #    \  \::/ /:/ \__\/  \:\\  \::/     \__\/  \:\\  \::/ /:/
-    #     \__\/ /:/       \  \:\\  \:\          \  \:\\  \:\/:/
-    #       /__/:/         \__\/ \  \:\          \__\/ \  \::/
-    #       \__\/                 \__\/                 \__\/
-
-    # Reverse the current state
-    toggle: -> @setState !@state()
-    check: -> @toggle()
-
-    # Get the current state
-    state: -> @prop "checked"
-    checked: -> @state()
-
-    # Set the state to a given value
-    setState: (state) ->
-        currentState = @state()
-        return currentState if @disabled() or !state?
-
-        # Change state if it is different
-        unless currentState is state
-            @prop "checked", state
-            @trigger "change"
-        state
-    setChecked: (state) -> @setState state
-
-
-
-    #       _____                    ___          ___                                    ___
-    #      /  /::\      ___         /  /\        /  /\        _____                     /  /\
-    #     /  /:/\:\    /  /\       /  /:/_      /  /::\      /  /::\                   /  /:/_
-    #    /  /:/  \:\  /  /:/      /  /:/ /\    /  /:/\:\    /  /:/\:\   ___     ___   /  /:/ /\
-    #   /__/:/ \__\:|/__/::\     /  /:/ /::\  /  /:/~/::\  /  /:/~/::\ /__/\   /  /\ /  /:/ /:/_
-    #   \  \:\ /  /:/\__\/\:\__ /__/:/ /:/\:\/__/:/ /:/\:\/__/:/ /:/\:|\  \:\ /  /://__/:/ /:/ /\
-    #    \  \:\  /:/    \  \:\/\\  \:\/:/~/:/\  \:\/:/__\/\  \:\/:/~/:/ \  \:\  /:/ \  \:\/:/ /:/
-    #     \  \:\/:/      \__\::/ \  \::/ /:/  \  \::/      \  \::/ /:/   \  \:\/:/   \  \::/ /:/
-    #      \  \::/       /__/:/   \__\/ /:/    \  \:\       \  \:\/:/     \  \::/     \  \:\/:/
-    #       \__\/        \__\/      /__/:/      \  \:\       \  \::/       \__\/       \  \::/
-    #                               \__\/        \__\/        \__\/                     \__\/
-
-    # Check whether a toggle is disabled/ enabled
-    enabled: -> !@disabled()
-    disabled: -> @prop "disabled"
-
-    # Set the disabled status
-    enable: -> !(@setDisabled false)
-    disable: -> @setDisabled true
-
-    setDisabled: (disabled) ->
-        # Return current status unless a new status is given
-        currentDisabled = @disabled()
-        return currentDisabled unless disabled?
-
-        # Change it if it is different from the current status
-        unless currentDisabled is disabled
-            @prop "disabled", disabled
-        disabled
-
-
-
-    #      ___                      ___          ___          ___
-    #     /  /\        ___         /__/\        /  /\        /  /\         ___
-    #    /  /:/       /  /\        \  \:\      /  /:/_      /  /::\       /__/|
-    #   /__/::\      /  /::\        \  \:\    /  /:/ /\    /  /:/\:\     |  |:|
-    #   \__\/\:\    /  /:/\:\   ___  \  \:\  /  /:/ /:/_  /  /:/~/:/     |  |:|
-    #      \  \:\  /  /:/~/::\ /__/\  \__\:\/__/:/ /:/ /\/__/:/ /:/___ __|__|:|
-    #       \__\:\/__/:/ /:/\:\\  \:\ /  /:/\  \:\/:/ /:/\  \:\/::::://__/::::\
-    #       /  /:/\  \:\/:/__\/ \  \:\  /:/  \  \::/ /:/  \  \::/~~~~    ~\~~\:\
-    #      /__/:/  \  \::/       \  \:\/:/    \  \:\/:/    \  \:\          \  \:\
-    #      \__\/    \__\/         \  \::/      \  \::/      \  \:\          \__\/
-    #                              \__\/        \__\/        \__\/
-
-    # Class manipulations
-    addClass: (newClasses) -> this[0].addClass(newClasses); return this
-    removeClass: (newClasses) -> this[0].removeClass(newClasses); return this
-    toggleClass: (newClasses) -> this[0].toggleClass(newClasses); return this
-    hasClass: (className) -> this[0].hasClass className
-
-    # DOM traversals
-    find: (sel) -> this[0].find sel
-    closest: (sel) -> this[0].closest sel
-    children: (sel) -> this[0].children sel
-    parent: (sel) -> this[0].parent sel
-
-    # Events
-    trigger: (event) ->
-        if event.match and event.match /change/
-            @_input.trigger event
-        else
-            this[0].trigger event
-
-    on: (event, selector, data, handler) ->
-        if event.match and event.match /change/
-            @_input.on event, selector, data, handler
-        else
-            this[0].on event, selector, data, handler
-
-    off: (event, selector, handler) ->
-        if event.match and event.match /change/
-            @_input.off event, selector, handler
-        else
-            this[0].off event, selector, handler
-
-    # Properties and attributes
-    css: (prop, rule) ->
-        if rule?
-            if prop.match /display/ then this[0].css(prop, rule) else @_label.css prop, rule
-            this
-        else
-            if prop.match /display/ then this[0].css(prop) else @_label.css prop
-
-    is: (sel) -> if sel.match(/(\:checked|\:disabled)/) then @_input.is(sel) else this[0].is(sel)
-
-    html: -> this[0].html()
-    text: -> @_label.text()
-
-    attr: (attribute, value) ->
-        if value?
-            if attribute.match /aria/ then this[0].attr(attribute, value) else @_input.attr attribute, value
-            this
-        else
-            if attribute.match /aria/ then this[0].attr(attribute) else @_input.attr attribute
-
-    name: -> @attr "name"
-    data: (key, value) ->
-        if value? or typeof key is "object"
-            this[0].data key, value
-            this
-        else
-            this[0].data key
-
-    prop: (property, val) ->
-        if val?
-            @_input.prop property, val
-            this
-        else
-            @_input.prop property
+	#        ___                   ___          ___
+	#       /  /\         ___     /  /\        /  /\
+	#      /  /:/        /  /\   /  /::\      /  /::\
+	#     /  /:/        /  /:/  /  /:/\:\    /  /:/\:\
+	#    /  /:/  ___   /  /:/  /  /:/  \:\  /  /:/~/:/
+	#   /__/:/  /  /\ /  /::\ /__/:/ \__\:\/__/:/ /:/___
+	#   \  \:\ /  /://__/:/\:\\  \:\ /  /:/\  \:\/:::::/
+	#    \  \:\  /:/ \__\/  \:\\  \:\  /:/  \  \::/~~~~
+	#     \  \:\/:/       \  \:\\  \:\/:/    \  \:\
+	#      \  \::/         \__\/ \  \::/      \  \:\
+	#       \__\/                 \__\/        \__\/
+
+	# Must be initialized with a toggle element
+	constructor: (details) ->
+		# Accept a pre-made jQuery object
+		if details instanceof jQuery or toString.call(details) is "[object String]"
+			details = $(details)
+			$input = details.children "input"
+			$label = details.children "label"
+
+			details.attr
+				"role": "checkbox"
+				"aria-checked": $input.prop("checked")
+
+			this[0] = details
+			@_input = $input
+			@_label = $label
+
+			# Bind the keypress event to manipulate the toggle
+			# and the change event to update the aria-role
+			toggle = this
+			$input.on "change", ->
+				toggle.attr "aria-checked", toggle.checked()
+
+			details.on "keypress", (event) ->
+				if event.charCode is 32
+					event.preventDefault()
+					toggle.toggle()
+
+		# Create a brand new instance
+		else
+			defaults =
+				# Whether the new toggle should be toggled on or not
+				# These five are all aliases for one another
+				active: false
+				on: false
+				checked: false
+				toggled: false
+				toggle: false
+
+				container: undefined
+				disabled: false         # Whether the toggle should be disabled
+				id: undefined           # Custom ID to use for the input/ label
+				label: ""               # Label to use for the toggle (hidden in default CSS)
+				name: "toggle"          # Name attribute to use for the input
+
+			options = $.extend defaults, details
+
+			# Create the toggle ID
+			toggleID = if options.id? then options.id else "toggle-switch-#{ToggleSwitchController._uniqueID()}"
+
+			# Replace HTML template items with relevant strings
+			toggleHTML = ToggleSwitch.template.replace /(TOGGLE_ID|LABEL|NAME)/g, (match) ->
+				switch match
+					when "TOGGLE_ID" then toggleID
+					when "LABEL" then options.label
+					when "NAME" then options.name
+
+			newToggle = new ToggleSwitch $(toggleHTML)
+
+			# Respect the disable, toggled, and toggleColor options
+			newToggle.disable() if options.disabled
+			newToggle.toggle() if (options.active or options.on or options.checked or options.toggled or options.toggle)
+
+			# Find the appropriate container
+			$container = undefined
+			if options.container?
+				$container = if options.container instanceof jQuery then options.container else $(options.container)
+				# If specified container doesn't exist, go to body
+				$container = "body" if $container.length < 1
+			else
+				$container = "body"
+
+			newToggle[0].appendTo $container
+
+			return newToggle
+
+
+	# Remove the HTML element
+	remove: -> this[0].remove()
+
+
+
+
+
+	#        ___                   ___                   ___
+	#       /  /\         ___     /  /\         ___     /  /\
+	#      /  /:/_       /  /\   /  /::\       /  /\   /  /:/_
+	#     /  /:/ /\     /  /:/  /  /:/\:\     /  /:/  /  /:/ /\
+	#    /  /:/ /::\   /  /:/  /  /:/~/::\   /  /:/  /  /:/ /:/_
+	#   /__/:/ /:/\:\ /  /::\ /__/:/ /:/\:\ /  /::\ /__/:/ /:/ /\
+	#   \  \:\/:/~/://__/:/\:\\  \:\/:/__\//__/:/\:\\  \:\/:/ /:/
+	#    \  \::/ /:/ \__\/  \:\\  \::/     \__\/  \:\\  \::/ /:/
+	#     \__\/ /:/       \  \:\\  \:\          \  \:\\  \:\/:/
+	#       /__/:/         \__\/ \  \:\          \__\/ \  \::/
+	#       \__\/                 \__\/                 \__\/
+
+	# Reverse the current state
+	toggle: -> @setState !@state()
+	check: -> @toggle()
+
+	# Get the current state
+	state: -> @prop "checked"
+	checked: -> @state()
+
+	# Set the state to a given value
+	setState: (state) ->
+		currentState = @state()
+		return currentState if @disabled() or !state?
+
+		# Change state if it is different
+		unless currentState is state
+			@prop "checked", state
+			@trigger "change"
+
+		state
+
+	setChecked: (state) -> @setState state
+
+
+
+	#       _____                    ___          ___                                    ___
+	#      /  /::\      ___         /  /\        /  /\        _____                     /  /\
+	#     /  /:/\:\    /  /\       /  /:/_      /  /::\      /  /::\                   /  /:/_
+	#    /  /:/  \:\  /  /:/      /  /:/ /\    /  /:/\:\    /  /:/\:\   ___     ___   /  /:/ /\
+	#   /__/:/ \__\:|/__/::\     /  /:/ /::\  /  /:/~/::\  /  /:/~/::\ /__/\   /  /\ /  /:/ /:/_
+	#   \  \:\ /  /:/\__\/\:\__ /__/:/ /:/\:\/__/:/ /:/\:\/__/:/ /:/\:|\  \:\ /  /://__/:/ /:/ /\
+	#    \  \:\  /:/    \  \:\/\\  \:\/:/~/:/\  \:\/:/__\/\  \:\/:/~/:/ \  \:\  /:/ \  \:\/:/ /:/
+	#     \  \:\/:/      \__\::/ \  \::/ /:/  \  \::/      \  \::/ /:/   \  \:\/:/   \  \::/ /:/
+	#      \  \::/       /__/:/   \__\/ /:/    \  \:\       \  \:\/:/     \  \::/     \  \:\/:/
+	#       \__\/        \__\/      /__/:/      \  \:\       \  \::/       \__\/       \  \::/
+	#                               \__\/        \__\/        \__\/                     \__\/
+
+	# Check whether a toggle is disabled/ enabled
+	enabled: -> !@disabled()
+	disabled: -> @prop "disabled"
+
+	# Set the disabled status
+	enable: -> !(@setDisabled false)
+	disable: -> @setDisabled true
+
+	setDisabled: (disabled) ->
+		# Return current status unless a new status is given
+		currentDisabled = @disabled()
+		return currentDisabled unless disabled?
+
+		# Change it if it is different from the current status
+		unless currentDisabled is disabled
+			@prop "disabled", disabled
+
+		disabled
+
+
+
+	#      ___                      ___          ___          ___
+	#     /  /\        ___         /__/\        /  /\        /  /\         ___
+	#    /  /:/       /  /\        \  \:\      /  /:/_      /  /::\       /__/|
+	#   /__/::\      /  /::\        \  \:\    /  /:/ /\    /  /:/\:\     |  |:|
+	#   \__\/\:\    /  /:/\:\   ___  \  \:\  /  /:/ /:/_  /  /:/~/:/     |  |:|
+	#      \  \:\  /  /:/~/::\ /__/\  \__\:\/__/:/ /:/ /\/__/:/ /:/___ __|__|:|
+	#       \__\:\/__/:/ /:/\:\\  \:\ /  /:/\  \:\/:/ /:/\  \:\/::::://__/::::\
+	#       /  /:/\  \:\/:/__\/ \  \:\  /:/  \  \::/ /:/  \  \::/~~~~    ~\~~\:\
+	#      /__/:/  \  \::/       \  \:\/:/    \  \:\/:/    \  \:\          \  \:\
+	#      \__\/    \__\/         \  \::/      \  \::/      \  \:\          \__\/
+	#                              \__\/        \__\/        \__\/
+
+	# Class manipulations
+	addClass: (newClasses) -> this[0].addClass(newClasses); return this
+	removeClass: (newClasses) -> this[0].removeClass(newClasses); return this
+	toggleClass: (newClasses) -> this[0].toggleClass(newClasses); return this
+	hasClass: (className) -> this[0].hasClass className
+
+	# DOM traversals
+	find: (sel) -> this[0].find sel
+	closest: (sel) -> this[0].closest sel
+	children: (sel) -> this[0].children sel
+	parent: (sel) -> this[0].parent sel
+
+	# Events
+	trigger: (event) ->
+		if event.match and event.match /change/
+			@_input.trigger event
+		else
+			this[0].trigger event
+
+	on: (event, selector, data, handler) ->
+		if event.match and event.match /change/
+			@_input.on event, selector, data, handler
+		else
+			this[0].on event, selector, data, handler
+
+	off: (event, selector, handler) ->
+		if event.match and event.match /change/
+			@_input.off event, selector, handler
+		else
+			this[0].off event, selector, handler
+
+	# Properties and attributes
+	css: (prop, rule) ->
+		if rule?
+			if prop.match /display/ then this[0].css(prop, rule) else @_label.css prop, rule
+			this
+		else
+			if prop.match /display/ then this[0].css(prop) else @_label.css prop
+
+	is: (sel) -> if sel.match(/(\:checked|\:disabled)/) then @_input.is(sel) else this[0].is(sel)
+
+	html: -> this[0].html()
+	text: -> @_label.text()
+
+	attr: (attribute, value) ->
+		if value?
+			if attribute.match /aria/ then this[0].attr(attribute, value) else @_input.attr attribute, value
+			this
+		else
+			if attribute.match /aria/ then this[0].attr(attribute) else @_input.attr attribute
+
+	name: -> @attr "name"
+	data: (key, value) ->
+		if value? or typeof key is "object"
+			this[0].data key, value
+			this
+		else
+			this[0].data key
+
+	prop: (property, val) ->
+		if val?
+			@_input.prop property, val
+			this
+		else
+			@_input.prop property

 ToggleSwitch.template = "

-                            <input type='checkbox' name='NAME' id='TOGGLE_ID' tabindex='-1'>
-
-

-

-
-
"
+            							<input type='checkbox' name='NAME' id='TOGGLE_ID' tabindex='-1'>
+
+

+

+
+
"

@@ -274,283 +277,283 @@
 #       \__\/        \__\/        \__\/                 \__\/        \__\/

 class ToggleSwitchController
-    #        ___                   ___          ___
-    #       /  /\         ___     /  /\        /  /\
-    #      /  /:/        /  /\   /  /::\      /  /::\
-    #     /  /:/        /  /:/  /  /:/\:\    /  /:/\:\
-    #    /  /:/  ___   /  /:/  /  /:/  \:\  /  /:/~/:/
-    #   /__/:/  /  /\ /  /::\ /__/:/ \__\:\/__/:/ /:/___
-    #   \  \:\ /  /://__/:/\:\\  \:\ /  /:/\  \:\/:::::/
-    #    \  \:\  /:/ \__\/  \:\\  \:\  /:/  \  \::/~~~~
-    #     \  \:\/:/       \  \:\\  \:\/:/    \  \:\
-    #      \  \::/         \__\/ \  \::/      \  \:\
-    #       \__\/                 \__\/        \__\/
-
-    constructor: () ->
-        # Create a list of current toggles
-        existingToggles = []
-        $(".toggle-switch").each ->
-            existingToggles.push(new ToggleSwitch $(this))
-        @toggleSwitches = existingToggles
-        @_toggleSwitchCount = 1
-
-
-
-    #        ___         _____        _____
-    #       /  /\       /  /::\      /  /::\
-    #      /  /::\     /  /:/\:\    /  /:/\:\
-    #     /  /:/\:\   /  /:/  \:\  /  /:/  \:\
-    #    /  /:/~/::\ /__/:/ \__\:|/__/:/ \__\:|
-    #   /__/:/ /:/\:\\  \:\ /  /:/\  \:\ /  /:/
-    #   \  \:\/:/__\/ \  \:\  /:/  \  \:\  /:/
-    #    \  \::/       \  \:\/:/    \  \:\/:/
-    #     \  \:\        \  \::/      \  \::/
-    #      \  \:\        \__\/        \__\/
-    #       \__\/
-
-    # newToggleSwitch
-    # -----------------------------------------------------------------------------------------
-
-    # SUMMARY
-    # -----------------------------------------------------------------------------------------
-    # Adds a new toggle switch with the specified parameters.
-
-    # PARAMETERS
-    # -----------------------------------------------------------------------------------------
-    # options:      Hash of options to use for the newly created toggle (see details in
-    # ToggleSwitch constructor)
-
-    newToggleSwitch: (options = {}) ->
-        newToggle = new ToggleSwitch options
-
-        # Add the new toggle to the internal array
-        @toggleSwitches.push newToggle
-
-        # Return the new toggle
-        newToggle
-
-
-    # add => newToggleSwitch
-    # -----------------------------------------------------------------------------------------
-
-    add: (options) -> @newToggleSwitch options
-
-
-
-    #        ___          ___          ___          ___                      ___
-    #       /  /\        /  /\        /__/\        /  /\         ___        /  /\
-    #      /  /::\      /  /:/_      |  |::\      /  /::\       /__/\      /  /:/_
-    #     /  /:/\:\    /  /:/ /\     |  |:|:\    /  /:/\:\      \  \:\    /  /:/ /\
-    #    /  /:/~/:/   /  /:/ /:/_  __|__|:|\:\  /  /:/  \:\      \  \:\  /  /:/ /:/_
-    #   /__/:/ /:/___/__/:/ /:/ /\/__/::::| \:\/__/:/ \__\:\ ___  \__\:\/__/:/ /:/ /\
-    #   \  \:\/:::::/\  \:\/:/ /:/\  \:\~~\__\/\  \:\ /  /://__/\ |  |:|\  \:\/:/ /:/
-    #    \  \::/~~~~  \  \::/ /:/  \  \:\       \  \:\  /:/ \  \:\|  |:| \  \::/ /:/
-    #     \  \:\       \  \:\/:/    \  \:\       \  \:\/:/   \  \:\__|:|  \  \:\/:/
-    #      \  \:\       \  \::/      \  \:\       \  \::/     \__\::::/    \  \::/
-    #       \__\/        \__\/        \__\/        \__\/          ~~~~      \__\/
-
-    # removeToggleSwitches
-    # -----------------------------------------------------------------------------------------
-
-    # SUMMARY
-    # -----------------------------------------------------------------------------------------
-    # Removes toggle switches matching the selector
-
-    # PARAMETERS
-    # -----------------------------------------------------------------------------------------
-    # sel:          The selector that must be matched by the toggle switch to be deleted.
-
-    removeToggleSwitches: (sel) ->
-        # Store for use in loop
-        tsc = this
-
-        # Create a new array to store the non-deleted toggles
-        livingToggles = []
-
-        # Get all matching switches
-        @toggleSwitches.forEach (toggle, index) ->
-            if not sel? or toggle.is sel
-                # Remove the element
-                toggle.remove()
-            else
-                # Add to the non-deleted array
-                livingToggles.push toggle
-
-        # Store the new array of toggles
-        @toggleSwitches = livingToggles
-
-
-    # remove => removeToggleSwitches
-    # delete => removeToggleSwitches
-    # -----------------------------------------------------------------------------------------
-
-    remove: (sel) -> @removeToggleSwitches sel
-    delete: (sel) -> @removeToggleSwitches sel
-
-
-
-    #        ___                   ___                   ___
-    #       /  /\         ___     /  /\         ___     /  /\
-    #      /  /:/_       /  /\   /  /::\       /  /\   /  /:/_
-    #     /  /:/ /\     /  /:/  /  /:/\:\     /  /:/  /  /:/ /\
-    #    /  /:/ /::\   /  /:/  /  /:/~/::\   /  /:/  /  /:/ /:/_
-    #   /__/:/ /:/\:\ /  /::\ /__/:/ /:/\:\ /  /::\ /__/:/ /:/ /\
-    #   \  \:\/:/~/://__/:/\:\\  \:\/:/__\//__/:/\:\\  \:\/:/ /:/
-    #    \  \::/ /:/ \__\/  \:\\  \::/     \__\/  \:\\  \::/ /:/
-    #     \__\/ /:/       \  \:\\  \:\          \  \:\\  \:\/:/
-    #       /__/:/         \__\/ \  \:\          \__\/ \  \::/
-    #       \__\/                 \__\/                 \__\/
-
-    # toggle
-    # -----------------------------------------------------------------------------------------
-
-    # SUMMARY
-    # -----------------------------------------------------------------------------------------
-    # forwards the toggle message to toggles matching the passed selector.
-
-    # PARAMETERS
-    # -----------------------------------------------------------------------------------------
-    # sel:          The selector that must be matched by the toggle to be toggled.
-
-    toggle: (sel) ->
-        @_getSubsetOfToggleSwitches sel
-            .forEach (toggle) -> toggle.toggle()
-
-
-    # check => toggle
-    # -----------------------------------------------------------------------------------------
-
-    check: (sel) -> @toggle sel
-
-
-    # setState
-    # -----------------------------------------------------------------------------------------
-
-    # SUMMARY
-    # -----------------------------------------------------------------------------------------
-    # forwards the setState message to toggles matching the passed selector.
-
-    # PARAMETERS
-    # -----------------------------------------------------------------------------------------
-    # sel:          The selector that must be matched by the toggle to be toggled.
-
-    setState: (state, sel) ->
-        @_getSubsetOfToggleSwitches sel
-            .forEach (toggle) -> toggle.setState state
-
-
-    # setChecked => setState
-    # -----------------------------------------------------------------------------------------
-
-    setChecked: (state, sel) -> @setState state, sel
-
-
-
-    #        ___          ___                       ___          ___
-    #       /  /\        /  /\                     /  /\        /  /\
-    #      /  /:/       /  /::\                   /  /::\      /  /::\
-    #     /  /:/       /  /:/\:\   ___     ___   /  /:/\:\    /  /:/\:\
-    #    /  /:/  ___  /  /:/  \:\ /__/\   /  /\ /  /:/  \:\  /  /:/~/:/
-    #   /__/:/  /  /\/__/:/ \__\:\\  \:\ /  /://__/:/ \__\:\/__/:/ /:/___
-    #   \  \:\ /  /:/\  \:\ /  /:/ \  \:\  /:/ \  \:\ /  /:/\  \:\/:::::/
-    #    \  \:\  /:/  \  \:\  /:/   \  \:\/:/   \  \:\  /:/  \  \::/~~~~
-    #     \  \:\/:/    \  \:\/:/     \  \::/     \  \:\/:/    \  \:\
-    #      \  \::/      \  \::/       \__\/       \  \::/      \  \:\
-    #       \__\/        \__\/                     \__\/        \__\/
-
-    # setToggleColor
-    # -----------------------------------------------------------------------------------------
-
-    # SUMMARY
-    # -----------------------------------------------------------------------------------------
-    # forwards the setToggleColor message to toggles matching the passed selector.
-
-    # PARAMETERS
-    # -----------------------------------------------------------------------------------------
-    # sel:          The selector that must be matched by the toggle to be colored.
-
-    setToggleColor: (color, sel) ->
-        @_getSubsetOfToggleSwitches sel
-            .forEach (toggle) -> toggle.setToggleColor color
-
-
-
-    #       _____                    ___          ___                                    ___
-    #      /  /::\      ___         /  /\        /  /\        _____                     /  /\
-    #     /  /:/\:\    /  /\       /  /:/_      /  /::\      /  /::\                   /  /:/_
-    #    /  /:/  \:\  /  /:/      /  /:/ /\    /  /:/\:\    /  /:/\:\   ___     ___   /  /:/ /\
-    #   /__/:/ \__\:|/__/::\     /  /:/ /::\  /  /:/~/::\  /  /:/~/::\ /__/\   /  /\ /  /:/ /:/_
-    #   \  \:\ /  /:/\__\/\:\__ /__/:/ /:/\:\/__/:/ /:/\:\/__/:/ /:/\:|\  \:\ /  /://__/:/ /:/ /\
-    #    \  \:\  /:/    \  \:\/\\  \:\/:/~/:/\  \:\/:/__\/\  \:\/:/~/:/ \  \:\  /:/ \  \:\/:/ /:/
-    #     \  \:\/:/      \__\::/ \  \::/ /:/  \  \::/      \  \::/ /:/   \  \:\/:/   \  \::/ /:/
-    #      \  \::/       /__/:/   \__\/ /:/    \  \:\       \  \:\/:/     \  \::/     \  \:\/:/
-    #       \__\/        \__\/      /__/:/      \  \:\       \  \::/       \__\/       \  \::/
-    #                               \__\/        \__\/        \__\/                     \__\/
-
-    # enable/disable
-    # -----------------------------------------------------------------------------------------
-
-    # SUMMARY
-    # -----------------------------------------------------------------------------------------
-    # forwards the enable/disable messages to toggles matching the passed selector.
-
-    # PARAMETERS
-    # -----------------------------------------------------------------------------------------
-    # sel:          The selector that must be matched by the toggle to be enabled/disabled.
-
-    enable: (sel) ->
-        @_getSubsetOfToggleSwitches sel
-            .forEach (toggle) -> toggle.enable()
-
-    disable: (sel) ->
-        @_getSubsetOfToggleSwitches sel
-            .forEach (toggle) -> toggle.disable()
-
-
-
-    #        ___          ___                       ___       ___          ___
-    #       /__/\        /  /\                     /  /\     /  /\        /  /\
-    #       \  \:\      /  /:/_                   /  /::\   /  /:/_      /  /::\
-    #        \__\:\    /  /:/ /\   ___     ___   /  /:/\:\ /  /:/ /\    /  /:/\:\
-    #    ___ /  /::\  /  /:/ /:/_ /__/\   /  /\ /  /:/~/://  /:/ /:/_  /  /:/~/:/
-    #   /__/\  /:/\:\/__/:/ /:/ /\\  \:\ /  /://__/:/ /://__/:/ /:/ /\/__/:/ /:/___
-    #   \  \:\/:/__\/\  \:\/:/ /:/ \  \:\  /:/ \  \:\/:/ \  \:\/:/ /:/\  \:\/:::::/
-    #    \  \::/      \  \::/ /:/   \  \:\/:/   \  \::/   \  \::/ /:/  \  \::/~~~~
-    #     \  \:\       \  \:\/:/     \  \::/     \  \:\    \  \:\/:/    \  \:\
-    #      \  \:\       \  \::/       \__\/       \  \:\    \  \::/      \  \:\
-    #       \__\/        \__\/                     \__\/     \__\/        \__\/
-
-    # _getSubsetOfToggleSwitches
-    # -----------------------------------------------------------------------------------------
-
-    # SUMMARY
-    # -----------------------------------------------------------------------------------------
-    # Get a subset of all elements that match the passed CSS selector.
-
-    # PARAMETERS
-    # -----------------------------------------------------------------------------------------
-    # sel:          The selector to search for. Optional. If omitted, all toggles are returned.
-
-    _getSubsetOfToggleSwitches: (sel) ->
-        # if sel is undefined, return all switches
-        return @toggleSwitches unless sel?
-        return @toggleSwitches.filter (toggle) ->
-            return toggle.is sel
-
-
-    # _uniqueID
-    # -----------------------------------------------------------------------------------------
-
-    # SUMMARY
-    # -----------------------------------------------------------------------------------------
-    # Creates a unique ID to prevent duplicate input IDs on a page.
-
-    _uniqueID: ->
-        return @_toggleSwitchCount++
+	#        ___                   ___          ___
+	#       /  /\         ___     /  /\        /  /\
+	#      /  /:/        /  /\   /  /::\      /  /::\
+	#     /  /:/        /  /:/  /  /:/\:\    /  /:/\:\
+	#    /  /:/  ___   /  /:/  /  /:/  \:\  /  /:/~/:/
+	#   /__/:/  /  /\ /  /::\ /__/:/ \__\:\/__/:/ /:/___
+	#   \  \:\ /  /://__/:/\:\\  \:\ /  /:/\  \:\/:::::/
+	#    \  \:\  /:/ \__\/  \:\\  \:\  /:/  \  \::/~~~~
+	#     \  \:\/:/       \  \:\\  \:\/:/    \  \:\
+	#      \  \::/         \__\/ \  \::/      \  \:\
+	#       \__\/                 \__\/        \__\/
+
+	constructor: () ->
+		# Create a list of current toggles
+		existingToggles = []
+		$(".toggle-switch").each ->
+			existingToggles.push(new ToggleSwitch $(this))
+		@toggleSwitches = existingToggles
+		@_toggleSwitchCount = 1
+
+
+
+	#        ___         _____        _____
+	#       /  /\       /  /::\      /  /::\
+	#      /  /::\     /  /:/\:\    /  /:/\:\
+	#     /  /:/\:\   /  /:/  \:\  /  /:/  \:\
+	#    /  /:/~/::\ /__/:/ \__\:|/__/:/ \__\:|
+	#   /__/:/ /:/\:\\  \:\ /  /:/\  \:\ /  /:/
+	#   \  \:\/:/__\/ \  \:\  /:/  \  \:\  /:/
+	#    \  \::/       \  \:\/:/    \  \:\/:/
+	#     \  \:\        \  \::/      \  \::/
+	#      \  \:\        \__\/        \__\/
+	#       \__\/
+
+	# newToggleSwitch
+	# -----------------------------------------------------------------------------------------
+
+	# SUMMARY
+	# -----------------------------------------------------------------------------------------
+	# Adds a new toggle switch with the specified parameters.
+
+	# PARAMETERS
+	# -----------------------------------------------------------------------------------------
+	# options:      Hash of options to use for the newly created toggle (see details in
+	# ToggleSwitch constructor)
+
+	newToggleSwitch: (options = {}) ->
+		newToggle = new ToggleSwitch options
+
+		# Add the new toggle to the internal array
+		@toggleSwitches.push newToggle
+
+		# Return the new toggle
+		newToggle
+
+
+	# add => newToggleSwitch
+	# -----------------------------------------------------------------------------------------
+
+	add: (options) -> @newToggleSwitch options
+
+
+
+	#        ___          ___          ___          ___                      ___
+	#       /  /\        /  /\        /__/\        /  /\         ___        /  /\
+	#      /  /::\      /  /:/_      |  |::\      /  /::\       /__/\      /  /:/_
+	#     /  /:/\:\    /  /:/ /\     |  |:|:\    /  /:/\:\      \  \:\    /  /:/ /\
+	#    /  /:/~/:/   /  /:/ /:/_  __|__|:|\:\  /  /:/  \:\      \  \:\  /  /:/ /:/_
+	#   /__/:/ /:/___/__/:/ /:/ /\/__/::::| \:\/__/:/ \__\:\ ___  \__\:\/__/:/ /:/ /\
+	#   \  \:\/:::::/\  \:\/:/ /:/\  \:\~~\__\/\  \:\ /  /://__/\ |  |:|\  \:\/:/ /:/
+	#    \  \::/~~~~  \  \::/ /:/  \  \:\       \  \:\  /:/ \  \:\|  |:| \  \::/ /:/
+	#     \  \:\       \  \:\/:/    \  \:\       \  \:\/:/   \  \:\__|:|  \  \:\/:/
+	#      \  \:\       \  \::/      \  \:\       \  \::/     \__\::::/    \  \::/
+	#       \__\/        \__\/        \__\/        \__\/          ~~~~      \__\/
+
+	# removeToggleSwitches
+	# -----------------------------------------------------------------------------------------
+
+	# SUMMARY
+	# -----------------------------------------------------------------------------------------
+	# Removes toggle switches matching the selector
+
+	# PARAMETERS
+	# -----------------------------------------------------------------------------------------
+	# sel:          The selector that must be matched by the toggle switch to be deleted.
+
+	removeToggleSwitches: (sel) ->
+		# Store for use in loop
+		tsc = this
+
+		# Create a new array to store the non-deleted toggles
+		livingToggles = []
+
+		# Get all matching switches
+		@toggleSwitches.forEach (toggle, index) ->
+			if not sel? or toggle.is sel
+				# Remove the element
+				toggle.remove()
+			else
+				# Add to the non-deleted array
+				livingToggles.push toggle
+
+		# Store the new array of toggles
+		@toggleSwitches = livingToggles
+
+
+	# remove => removeToggleSwitches
+	# delete => removeToggleSwitches
+	# -----------------------------------------------------------------------------------------
+
+	remove: (sel) -> @removeToggleSwitches sel
+	delete: (sel) -> @removeToggleSwitches sel
+
+
+
+	#        ___                   ___                   ___
+	#       /  /\         ___     /  /\         ___     /  /\
+	#      /  /:/_       /  /\   /  /::\       /  /\   /  /:/_
+	#     /  /:/ /\     /  /:/  /  /:/\:\     /  /:/  /  /:/ /\
+	#    /  /:/ /::\   /  /:/  /  /:/~/::\   /  /:/  /  /:/ /:/_
+	#   /__/:/ /:/\:\ /  /::\ /__/:/ /:/\:\ /  /::\ /__/:/ /:/ /\
+	#   \  \:\/:/~/://__/:/\:\\  \:\/:/__\//__/:/\:\\  \:\/:/ /:/
+	#    \  \::/ /:/ \__\/  \:\\  \::/     \__\/  \:\\  \::/ /:/
+	#     \__\/ /:/       \  \:\\  \:\          \  \:\\  \:\/:/
+	#       /__/:/         \__\/ \  \:\          \__\/ \  \::/
+	#       \__\/                 \__\/                 \__\/
+
+	# toggle
+	# -----------------------------------------------------------------------------------------
+
+	# SUMMARY
+	# -----------------------------------------------------------------------------------------
+	# forwards the toggle message to toggles matching the passed selector.
+
+	# PARAMETERS
+	# -----------------------------------------------------------------------------------------
+	# sel:          The selector that must be matched by the toggle to be toggled.
+
+	toggle: (sel) ->
+		@_getSubsetOfToggleSwitches sel
+			.forEach (toggle) -> toggle.toggle()
+
+
+	# check => toggle
+	# -----------------------------------------------------------------------------------------
+
+	check: (sel) -> @toggle sel
+
+
+	# setState
+	# -----------------------------------------------------------------------------------------
+
+	# SUMMARY
+	# -----------------------------------------------------------------------------------------
+	# forwards the setState message to toggles matching the passed selector.
+
+	# PARAMETERS
+	# -----------------------------------------------------------------------------------------
+	# sel:          The selector that must be matched by the toggle to be toggled.
+
+	setState: (state, sel) ->
+		@_getSubsetOfToggleSwitches sel
+			.forEach (toggle) -> toggle.setState state
+
+
+	# setChecked => setState
+	# -----------------------------------------------------------------------------------------
+
+	setChecked: (state, sel) -> @setState state, sel
+
+
+
+	#        ___          ___                       ___          ___
+	#       /  /\        /  /\                     /  /\        /  /\
+	#      /  /:/       /  /::\                   /  /::\      /  /::\
+	#     /  /:/       /  /:/\:\   ___     ___   /  /:/\:\    /  /:/\:\
+	#    /  /:/  ___  /  /:/  \:\ /__/\   /  /\ /  /:/  \:\  /  /:/~/:/
+	#   /__/:/  /  /\/__/:/ \__\:\\  \:\ /  /://__/:/ \__\:\/__/:/ /:/___
+	#   \  \:\ /  /:/\  \:\ /  /:/ \  \:\  /:/ \  \:\ /  /:/\  \:\/:::::/
+	#    \  \:\  /:/  \  \:\  /:/   \  \:\/:/   \  \:\  /:/  \  \::/~~~~
+	#     \  \:\/:/    \  \:\/:/     \  \::/     \  \:\/:/    \  \:\
+	#      \  \::/      \  \::/       \__\/       \  \::/      \  \:\
+	#       \__\/        \__\/                     \__\/        \__\/
+
+	# setToggleColor
+	# -----------------------------------------------------------------------------------------
+
+	# SUMMARY
+	# -----------------------------------------------------------------------------------------
+	# forwards the setToggleColor message to toggles matching the passed selector.
+
+	# PARAMETERS
+	# -----------------------------------------------------------------------------------------
+	# sel:          The selector that must be matched by the toggle to be colored.
+
+	setToggleColor: (color, sel) ->
+		@_getSubsetOfToggleSwitches sel
+			.forEach (toggle) -> toggle.setToggleColor color
+
+
+
+	#       _____                    ___          ___                                    ___
+	#      /  /::\      ___         /  /\        /  /\        _____                     /  /\
+	#     /  /:/\:\    /  /\       /  /:/_      /  /::\      /  /::\                   /  /:/_
+	#    /  /:/  \:\  /  /:/      /  /:/ /\    /  /:/\:\    /  /:/\:\   ___     ___   /  /:/ /\
+	#   /__/:/ \__\:|/__/::\     /  /:/ /::\  /  /:/~/::\  /  /:/~/::\ /__/\   /  /\ /  /:/ /:/_
+	#   \  \:\ /  /:/\__\/\:\__ /__/:/ /:/\:\/__/:/ /:/\:\/__/:/ /:/\:|\  \:\ /  /://__/:/ /:/ /\
+	#    \  \:\  /:/    \  \:\/\\  \:\/:/~/:/\  \:\/:/__\/\  \:\/:/~/:/ \  \:\  /:/ \  \:\/:/ /:/
+	#     \  \:\/:/      \__\::/ \  \::/ /:/  \  \::/      \  \::/ /:/   \  \:\/:/   \  \::/ /:/
+	#      \  \::/       /__/:/   \__\/ /:/    \  \:\       \  \:\/:/     \  \::/     \  \:\/:/
+	#       \__\/        \__\/      /__/:/      \  \:\       \  \::/       \__\/       \  \::/
+	#                               \__\/        \__\/        \__\/                     \__\/
+
+	# enable/disable
+	# -----------------------------------------------------------------------------------------
+
+	# SUMMARY
+	# -----------------------------------------------------------------------------------------
+	# forwards the enable/disable messages to toggles matching the passed selector.
+
+	# PARAMETERS
+	# -----------------------------------------------------------------------------------------
+	# sel:          The selector that must be matched by the toggle to be enabled/disabled.
+
+	enable: (sel) ->
+		@_getSubsetOfToggleSwitches sel
+			.forEach (toggle) -> toggle.enable()
+
+	disable: (sel) ->
+		@_getSubsetOfToggleSwitches sel
+			.forEach (toggle) -> toggle.disable()
+
+
+
+	#        ___          ___                       ___       ___          ___
+	#       /__/\        /  /\                     /  /\     /  /\        /  /\
+	#       \  \:\      /  /:/_                   /  /::\   /  /:/_      /  /::\
+	#        \__\:\    /  /:/ /\   ___     ___   /  /:/\:\ /  /:/ /\    /  /:/\:\
+	#    ___ /  /::\  /  /:/ /:/_ /__/\   /  /\ /  /:/~/://  /:/ /:/_  /  /:/~/:/
+	#   /__/\  /:/\:\/__/:/ /:/ /\\  \:\ /  /://__/:/ /://__/:/ /:/ /\/__/:/ /:/___
+	#   \  \:\/:/__\/\  \:\/:/ /:/ \  \:\  /:/ \  \:\/:/ \  \:\/:/ /:/\  \:\/:::::/
+	#    \  \::/      \  \::/ /:/   \  \:\/:/   \  \::/   \  \::/ /:/  \  \::/~~~~
+	#     \  \:\       \  \:\/:/     \  \::/     \  \:\    \  \:\/:/    \  \:\
+	#      \  \:\       \  \::/       \__\/       \  \:\    \  \::/      \  \:\
+	#       \__\/        \__\/                     \__\/     \__\/        \__\/
+
+	# _getSubsetOfToggleSwitches
+	# -----------------------------------------------------------------------------------------
+
+	# SUMMARY
+	# -----------------------------------------------------------------------------------------
+	# Get a subset of all elements that match the passed CSS selector.
+
+	# PARAMETERS
+	# -----------------------------------------------------------------------------------------
+	# sel:          The selector to search for. Optional. If omitted, all toggles are returned.
+
+	_getSubsetOfToggleSwitches: (sel) ->
+		# if sel is undefined, return all switches
+		return @toggleSwitches unless sel?
+		return @toggleSwitches.filter (toggle) ->
+			return toggle.is sel
+
+
+	# _uniqueID
+	# -----------------------------------------------------------------------------------------
+
+	# SUMMARY
+	# -----------------------------------------------------------------------------------------
+	# Creates a unique ID to prevent duplicate input IDs on a page.
+
+	_uniqueID: ->
+		return @_toggleSwitchCount++

 ToggleSwitchController._toggleSwitchCount = 0
 ToggleSwitchController._uniqueID = () ->
-    ToggleSwitchController._toggleSwitchCount++
+	ToggleSwitchController._toggleSwitchCount++

@@ -568,4 +571,4 @@
 #       \__\/                     \__\/        \__\/        \__\/

 window.ToggleSwitchController = ToggleSwitchController
-window.ToggleSwitch = ToggleSwitch+window.ToggleSwitch = ToggleSwitch


Remove stray comment

Remove stray comment

--- services/web/app/coffee/router.coffee
+++ services/web/app/coffee/router.coffee
@@ -119,7 +119,6 @@
 		webRouter.get  '/user/personal_info', AuthenticationController.requireLogin(), UserInfoController.getLoggedInUsersPersonalInfo
 		privateApiRouter.get  '/user/:user_id/personal_info', AuthenticationController.httpAuth, UserInfoController.getPersonalInfo

-		# TODO: check this is the right router for these routes
 		webRouter.get  '/user/projects', AuthenticationController.requireLogin(), ProjectController.userProjectsJson
 		webRouter.get  '/project/:Project_id/entities', AuthenticationController.requireLogin(), ProjectController.projectEntitiesJson


minbet and maxbet are passed in the "open" message now.

--- patten.coffee
+++ patten.coffee
@@ -63,7 +63,7 @@
     event.preventDefault()
     if valid_bet()?
         bet.currbet *= 2
-        if bet.currbet > bet.maxbet
+        if Number(bet.currbet) > Number(bet.maxbet)
             bet.currbet = bet.maxbet
         else if !amount_re.test(bet.currbet)
             bet.currbet = bet.currbet.toFixed(8)
@@ -74,8 +74,10 @@
     event.preventDefault()
     if valid_bet()?
         bet.currbet /= 2
-        if bet.currbet < bet.minbet or !amount_re.test(bet.currbet)
+        if Number(bet.currbet) < Number(bet.minbet)
             bet.currbet = bet.minbet
+        else if !amount_re.test(bet.currbet)
+            bet.currbet = bet.currbet.toFixed(8)
         $('#bet').val(bet.currbet)

 max_bet = (event) ->
@@ -369,7 +371,6 @@
         for item in ['#myprofit', '#nbet', '#nwin', '#npattern', '#wagered']
             $(item).text('Error')
         return
-    console.log(data)
     show_ranking(data.ranking)
     $('#myprofit').text(numcomma(data.profit))
     $('#wagered').text(numcomma(data.wagered))
@@ -397,7 +398,6 @@

 ranking_update = ->
     if stream.pending_ranking_update
-        console.log('update ranking')
         sock_send({type: 'ranking'})

 setup_plot = ->
@@ -508,6 +508,8 @@
     $('.edge').text("#{data.edge}%")
     $('.edge-ex').text(data.edge_example)
     $('#jpincr').text(data.jp_incr)
+    bet.minbet = data.min_bet
+    bet.maxbet = data.max_bet

 $('#new-useed').click( ->
     this.focus()
@@ -614,9 +616,6 @@
         $('#nonce').val(data.nonce)
         $('#useed').val(data.useed)
         $('#sshash').val(data.sshash)
-
-        bet.minbet = data.min_bet
-        bet.maxbet = data.max_bet

         # Recent history
         table = $('#history tbody')
@@ -787,9 +786,14 @@
             when 'ranking' then handle_ranking(data)
             when 'bet-update'
                 $('#jackpot').text(data.jackpot)
-                if data.maxbet?
-                    bet.maxbet = data.maxbet
-                    stream.pending_ranking_update = true
+                if data.max_bet?
+                    if $('#bet').val() == bet.maxbet
+                        # The earlier bet was a maxbet, so it is nice
+                        # to update it to reflect the update.
+                        $('#bet').val(data.max_bet)
+                    bet.maxbet = data.max_bet
+                    if login_data.name?
+                        stream.pending_ranking_update = true
             when 'balance' then $('#balance').text(data.balance)
             when 'address'
                 login_data.address = data.address


Don't use 'm' encoding  any more. That's simpler.

--- src/transport.coffee
+++ src/transport.coffee
@@ -156,10 +156,7 @@
             @session.unregister(status, reason)

     doSendBulk: (messages) ->
-        if messages.length is 1
-            @doSendFrame('m' + JSON.stringify(messages[0]))
-        else
-            @doSendFrame('a' + JSON.stringify(messages))
+        @doSendFrame('a' + JSON.stringify(messages))

 # Write stuff directly to connection.


Added semicolon in getKeyData requests

Added semicolon in getKeyData requests

--- muleview/app/Mule.coffee
+++ muleview/app/Mule.coffee
@@ -71,7 +71,7 @@
   # For a given key, returns data per each retention
   # in the form of "retention => data array"
   getKeyData: (key, callback) ->
-    @askMule "graph/#{key}?level=0&alerts=false&filter=now", (response) =>
+    @askMule "graph/#{key};?level=0&alerts=false&filter=now", (response) =>
       retentions = {}
       for own name, data of response
         [keyName, retention] = name.split(";")


better error object structure

better error object structure

--- src/validator.coffee
+++ src/validator.coffee
@@ -10,7 +10,19 @@

     @schema = schema

+  formatError: (error) ->
+    if not error then return
+
+    errors = {}
+
+    for i in [0..error.length - 1]
+      property = error[i]['property']
+      #delete error[i]['property']  //dup data
+      errors[property] = error[i]
+
+    return errors
+
   validate: ->
-    return amanda.validate  @data, @schema, (error) ->
-      return error
+    return amanda.validate  @data, @schema, (error) =>
+      return @formatError error


Destroy subviews before bindings in die.

This allows things like ViewBinding to have its view killed if necessary, as opposed to just removed.

--- src/view/view.coffee
+++ src/view/view.coffee
@@ -246,8 +246,8 @@
     if @_batman.events
       event.clearHandlers() for _, event of @_batman.events

+    @destroySubviews()
     @destroyBindings()
-    @destroySubviews()

     @node = null
     @parentNode = null


Debugging web test errors

Debugging web test errors

--- src/webserver.coffee
+++ src/webserver.coffee
@@ -53,6 +53,8 @@
       unless client.url then return res.json 400,
         error: "Adding or updating a client requires a jolokia url."

+      console.log client
+
       cl = @jsrv.add_client(
         client.name, client.url, client.template, client.cluster)
       res.json 200,


changed translations to work with different settings format

--- translations.coffee
+++ translations.coffee
@@ -5,7 +5,6 @@
 module.exports =

 	setup: (options) ->
-
 		subdomainLang = options?.subdomainLang || {}

 		i18n.init
@@ -13,16 +12,16 @@
 			saveMissing: true
 			resSetPath: __dirname + "/locales/missing-__lng__.json"
 			sendMissingTo: "fallback"
-			fallbackLng: options?.defaultLng || "en-US"
+			fallbackLng: options?.defaultLng || "en"
 			detectLngFromHeaders: false
 			useCookie: false
-			preload: _.values(subdomainLang)
+			preload: _.pluck(_.values(subdomainLang), "lngCode")

 		setLangBasedOnDomainMiddlewear = (req, res, next) ->

 			host = req.headers.host
 			subdomain = host.slice(0, host.indexOf("."))
-			lang = options?.subdomainLang?[subdomain]
+			lang = options?.subdomainLang?[subdomain]?.lngCode
 			if req.originalUrl.indexOf("setLng") == -1 and lang?
 				req.i18n.setLng lang
 			next()


common: destroy account menu and avatar area if they exist

--- client/Main/maincontroller/mainviews/mainview.coffee
+++ client/Main/maincontroller/mainviews/mainview.coffee
@@ -153,6 +153,7 @@
     @createLoggedInAccountArea()

   createLoggedInAccountArea:->
+    @accountArea.destroySubViews()

     @accountArea.addSubView @accountMenu = new AvatarAreaIconMenu
     @accountMenu.accountChanged KD.whoami()
@@ -351,4 +352,3 @@
           duration = 400
           KDScrollView::scrollTo.call mainView, {top, duration}
           break
-


Client: Activity: Feed: Deleted unused method

--- client/activity/lib/components/comments/index.coffee
+++ client/activity/lib/components/comments/index.coffee
@@ -68,10 +68,6 @@
     @setState { hasValue: hasValue, commentValue: value }

-  getPostButtonClassNames: -> classnames
-    'FeedItem-postComment' : yes
-    'green'                : @state.hasValue
-    'hidden'               : not @state.focusOnInput and not @state.hasValue

   render: ->


helper: realtime add fetchCollaborationFile

--- client/ide/lib/collaboration/helpers/realtime.coffee
+++ client/ide/lib/collaboration/helpers/realtime.coffee
@@ -1,5 +1,20 @@
 getNick = require 'app/util/nick'
 _ = require 'lodash'
+
+###*
+ * Fetches collaboration file with given fileName and calls the callback with it.
+ *
+ * @param {RealtimeManager} manager
+ * @param {string} fileName
+ * @param {function(err: object, result: object)}
+###
+fetchCollaborationFile = (manager, fileName, callback) ->
+
+  isSessionActive manager, fileName, (isActive, file) =>
+    if isActive
+    then callback null, file
+    else callback 'trying to fetch file from inactive session'
+

 ###*
  * Load file with given id into RealtimeManager instance.
@@ -289,6 +304,7 @@

 module.exports = {
+  fetchCollaborationFile
   loadCollaborationFile
   createCollaborationFile
   deleteCollaborationFile


Drawing Pane: Require responsive-sketchpad module

--- client/ide/lib/workspace/panes/idedrawingpane.coffee
+++ client/ide/lib/workspace/panes/idedrawingpane.coffee
@@ -4,6 +4,10 @@
 KDNotificationView = kd.NotificationView
 nick = require 'app/util/nick'
 IDEPane = require './idepane'
+
+$ = require 'jquery'
+require('kd-shim-jquery-sketchpad') $
+
 module.exports = class IDEDrawingPane extends IDEPane


bugfix "theta --volume (number)" validation  #9

--- bin/theta.coffee
+++ bin/theta.coffee
@@ -24,7 +24,7 @@

 parser.filter 'NUMBER', (v) ->
   return v unless v # allow empty argument
-  if /^[1-9][0-9]*(\.\d+)?$/.test v
+  if /^[1-9]?[0-9]*(\.\d+)?$/.test v
     return v - 0
   throw "invalid number - \"#{v}\""

@@ -124,24 +124,25 @@
 parser.on 'volume', (opt, volume) ->
   theta.connect()
   theta.once 'connect', ->
-    unless volume
-      theta.getProperty 0x502C, (err, res) ->
+    if typeof volume is 'number'
+      theta.setProperty 0x502C, volume, (err, res) ->
         if err
           console.error err
           return process.exit 1
-        console.log "AudioVolume: #{res.dataPacket.array[0]}"
-        theta.disconnect()
+        theta.getProperty 0x502C, (err, res) ->
+          if err
+            console.error err
+            return process.exit 1
+          console.log "AudioVolume: #{res.dataPacket.array[0]}"
+          theta.disconnect()
       return
-    theta.setProperty 0x502C, volume, (err, res) ->
+    theta.getProperty 0x502C, (err, res) ->
       if err
         console.error err
         return process.exit 1
-      theta.getProperty 0x502C, (err, res) ->
-        if err
-          console.error err
-          return process.exit 1
-        console.log "AudioVolume: #{res.dataPacket.array[0]}"
-        theta.disconnect()
+      console.log "AudioVolume: #{res.dataPacket.array[0]}"
+      theta.disconnect()
+    return

 if process.argv.length < 3
   parser.on_switches.help.call()


applicatoin manager background app show callback fix by gokmen

--- client/landing/app/MainApp/ApplicationManager.coffee
+++ client/landing/app/MainApp/ApplicationManager.coffee
@@ -189,11 +189,12 @@

   show:(appOptions, callback)->

-    return if appOptions.background
-
     appInstance = @get appOptions.name
+
+    if appOptions.background
+      return @utils.defer -> callback? appInstance
+
     appView     = appInstance.getView?()
-
     return unless appView

     @emit 'AppManagerWantsToShowAnApp', appInstance, appView, appOptions


BitObject is now an ArrayProxy. Don't know what I'll do with this in the future

--- src/coffee/ValpoUtils/BitObject.coffee
+++ src/coffee/ValpoUtils/BitObject.coffee
@@ -1,8 +1,15 @@

 define ['ember', './Core'], (Em, VU) ->

-  BitObject = Em.ObjectProxy.extend
+  BitObject = Em.ArrayProxy.extend
     mask: 0
+
+    content: Em.computed( ->
+      ret = Em.A()
+      @bitwiseFn (term, mask) ->
+        ret.push term
+      ret
+    ).property 'mask'

     add: (id) ->
       id = +id
@@ -34,7 +41,7 @@
       this

     has: (id) ->
-      (@get('mask') & 1<<id) isnt 0
+      (@get('mask') & 1<<+id) isnt 0

     bitwiseFn: (callback) ->
       mask = @get 'mask'
@@ -46,12 +53,6 @@
         mask >>= 1
         term++
       this
-
-    toArray: ->
-      ret = []
-      @bitwiseFn (term, mask) ->
-        ret.push term
-      ret

     toString: ->
       mask = @get 'mask'


Fix reference to launchDropBoxChooser().

--- src/coffeeconsole/coffeeconsole.coffee
+++ src/coffeeconsole/coffeeconsole.coffee
@@ -299,7 +299,7 @@
           |
           | Quick Links:
           | #WELCOME - Open sample with quick welcome/tutorial.
-          | #CHOOSE  - Open a file from your Dropbox.
+          | #CHOOSE  - Open a file from your Dropbox.
           | #NEW     - Open a new, blank document.
           |
           | help() for features and tips.


Defer UI changes to after history is fully loaded

--- scripts/home.coffee
+++ scripts/home.coffee
@@ -26,13 +26,13 @@
     historyList = historyContainer.querySelector('ul')
     blurb = document.getElementById('blurb')
     if history.length != 0
-        blurb.classList.add('hidden')
-        historyContainer.classList.remove('hidden')
-    loadDetailedHistory(items, (result) ->
-        for item in items
-            if result[item]
-                historyList.appendChild(createHistoryItem({ item: result[item], hash: item }))
-    )
+        loadDetailedHistory(items, (result) ->
+            blurb.classList.add('hidden')
+            historyContainer.classList.remove('hidden')
+            for item in items
+                if result[item]
+                    historyList.appendChild(createHistoryItem({ item: result[item], hash: item }))
+        )
 , false)

 createHistoryItem = (h) ->


reverted 367ca09475385c5c96ec3b6362972b09bd74e39c as tp fix issue where search results weren't clickable

--- _assets/js/_search.coffee
+++ _assets/js/_search.coffee
@@ -26,10 +26,8 @@

   if $('#search-posts').val().length > 0
     isSelected = true
-    $('#search-results').css('display', '')
   else
     isSelected = false
-    $('#search-results').css('display', 'none')

   $('#search-results').hover (->
     isSelected = true
@@ -58,7 +56,10 @@
     return

   $('#search-posts').focusout ->
-    $('#search-results').css('display', 'none')
+    if !isSelected and $('#search-posts').val().length > 0
+      $('#search-results').css('display', 'none')
+    else
+      $('#search-results').css('display', '')
     return

   $('#search-posts').focusin ->


Fixed Webcam view

Fixed Webcam view

--- src/components/image/webcamview.coffee
+++ src/components/image/webcamview.coffee
@@ -173,5 +173,5 @@

   viewAppended: ->
     super()
-    [@button, @save, @retake, @video, @picture].forEach @bound 'addSubView'
+    @addSubView view for view in [@button, @save, @retake, @video, @picture]


caching signal items as well.

caching signal items as well.

--- edf.coffee
+++ edf.coffee
@@ -34,6 +34,7 @@
 		@_handle	= fs.openSync @edf_path, "r"

 		@_header_item	= { }
+		@_signal_item	= { }

 		# Run through and populate _signals using the specs.
 		for i in [0..parseInt(@get_header_item( "num_signals_in_data_record"))]
@@ -109,7 +110,7 @@

 	get_header_item: ( name ) ->

-		# Check local instance cache first.
+		# If we already have a cached copy of it, return it.
 		if @_header_item[name]?
 			return @_header_item[name]

@@ -123,9 +124,20 @@
 		@_header_item[name]

 	get_signal_item: ( signal_index, name ) ->
-		# Wraps getting the signal spec and slicing the buffer and returning a string.
-		spec = @_get_signal_spec signal_index, name
-		@_get_buffer_slice( spec.length, spec.position ).toString( ).trim( )
+
+		# Simple mashing of the signal and name.
+		_i = name + "_" + signal_index
+
+		# If we have the cached item, simply return it.
+		if @_signal_item[_i]?
+			return @_signal_item[_i]
+
+		# Gets the spec object.
+		spec		= @_get_signal_spec signal_index, name
+
+		# Gets the actual item. caches it, returns it.
+		@_signal_item[_i]	= @_get_buffer_slice( spec.length, spec.position ).toString( ).trim( )
+		@_signal_item[_i]

 	get_signal_data: ( signal_index, start, end ) ->


Fix relative path in twss

Fix relative path in twss

--- scripts/twss.coffee
+++ scripts/twss.coffee
@@ -23,7 +23,7 @@
   robot.hear /.*/i, (msg) ->
     natural = require 'natural'
     # path from the root of hubot
-    natural.BayesClassifier.load './src/scripts/twss/classifier-twss.json', null, (err, classifier) ->
+    natural.BayesClassifier.load './twss/classifier-twss.json', null, (err, classifier) ->
       check = (grams) ->
         c = classifier.getClassifications(grams)
         cmp = {}


Add fragment using history API

Add fragment using history API

This avoids page jumping, refs #600

--- app/assets/javascripts/ui.js.coffee
+++ app/assets/javascripts/ui.js.coffee
@@ -2,9 +2,9 @@
   # Tabs
   $(".tabs").parent().tabs()

-  $(".tabs").parent().on "tabsactivate", (event, ui) ->
-    window.location.hash = ui.newPanel.attr('id')
-    $("html, body").animate({ scrollTop: ($("##{ui.newPanel.attr('id')}").offset().top - 80) }, 0)
+  if history.pushState
+    $(".tabs").parent().on "tabsactivate", (event, ui) ->
+      history.pushState(null, null, "##{ui.newPanel.attr('id')}")

   # Crude way to make large blocks .clickable by definiting a.primary-link in them
   $(".clickable").click ->


refactor specs to nicer repetition pattern

--- test/spec/controllers/choropleth_form_controller_spec.coffee
+++ test/spec/controllers/choropleth_form_controller_spec.coffee
@@ -37,10 +37,9 @@
         expect(@scope.mappingPropertyOnMap).to.be.undefined

-      describe '', ->  # NOTE: due to the scoping of params a repeater always has to be alone in a descibe block (scope)
-        for key in ['projection', 'mapName', 'mappingPropertyOnData', 'valueProperty']
-          it "should initialize #{key}", ->
-            expect(@scope[key]).to.eql(@snippetModel.storedData[key])
+      ['projection', 'mapName', 'mappingPropertyOnData', 'valueProperty'].forEach (key) ->
+        it "should initialize #{key}", ->
+          expect(@scope[key]).to.eql(@snippetModel.storedData[key])

     describe "skips some when data is not set", ->
@@ -52,14 +51,17 @@
           $scope: @scope, $http: {}, ngProgress: @ngProgress, dataService: {})

-      describe '', ->
-        for key in ['mappingPropertyOnData', 'valueProperty']
-          it "should not initialize #{key}", ->
-            expect(@scope[key]).to.be.undefined
+      ['mappingPropertyOnData', 'valueProperty'].forEach (key) ->
+        it "should not initialize #{key}", ->
+          expect(@scope[key]).to.be.undefined

-      describe '', ->
-        for key in ['projection', 'mapName', 'mappingPropertyOnMap']
+      ['mappingPropertyOnData', 'valueProperty'].forEach (key) ->
+        it "should not initialize #{key}", ->
+          expect(@scope[key]).to.be.undefined
+
+
+      ['projection', 'mapName', 'mappingPropertyOnMap'].forEach (key) ->
           it "should initialize #{key}", ->
             expect(@scope[key]).to.eql(@snippetModel.storedData[key])

@@ -71,10 +73,32 @@
           $scope: @scope, $http: {}, ngProgress: @ngProgress, dataService: {})

-      describe '', ->
-        for key in ['projection', 'mapName', 'mappingPropertyOnMap', 'mappingPropertyOnData', 'valueProperty']
+      ['projection', 'mapName', 'mappingPropertyOnMap', 'mappingPropertyOnData', 'valueProperty'].forEach (key) ->
           it "should initialize #{key}", ->
             expect(@scope[key]).to.eql(@snippetModel.storedData[key])
+
+
+    describe 'initialize property selection lists', ->
+
+      describe 'for map selections', ->
+
+        beforeEach ->
+          @choroplethController = instantiateController('ChoroplethFormController',
+            $scope: @scope, $http: {}, ngProgress: @ngProgress, dataService: {})
+
+        it 'should initialize available projections'
+
+
+        it 'should initialize available mapping properties on map'
+
+
+      describe 'for data selections', ->
+
+        it 'should initialize available mapping properties on data'
+
+
+        it 'should initialize available value properties on data'
+

   # TODO: there seems to be some timing issue when changing user input...


Send game over message after final d_score

--- models/game.coffee
+++ models/game.coffee
@@ -140,7 +140,11 @@
         @DbHelper.addEvent @gameId, word_index, player.uuid, {type: @DbHelper.eventType.snap}

       if @isGameOver()
-        @gameOver()
+        # send this with a delay to make sure players receive their final point
+        # before the game over message
+        setTimeout () =>
+          @gameOver()
+        , 500
       cb(null, playerSnap)

   reachedMaxScore: () ->


removed .button calls for destroy

removed .button calls for destroy

--- app/assets/javascripts/answerbox/destroy.coffee
+++ app/assets/javascripts/answerbox/destroy.coffee
@@ -2,7 +2,6 @@
   ev.preventDefault()
   if confirm 'Are you sure?'
     btn = $(this)
-    btn.button "loading"
     aid = btn[0].dataset.aId
     $.ajax
       url: '/ajax/destroy_answer' # TODO: find a way to use rake routes instead of hardcoding them here
@@ -16,5 +15,4 @@
       error: (jqxhr, status, error) ->
         console.log jqxhr, status, error
         showNotification "An error occurred, a developer should check the console for details", false
-      complete: (jqxhr, status) ->
-        btn.button "reset"+      complete: (jqxhr, status) ->


Updating

Updating

--- projects.cson
+++ projects.cson
@@ -1,9 +1,21 @@
+"arch-scripts":
+  title: "arch-scripts"
+  paths: [
+    "/home/fusion809/Shell"
+    "/home/fusion809/.bashrc"
+    "/home/fusion809/.zshrc"
+  ]
 "fusion809.github.io":
   title: "fusion809.github.io"
   paths: [
     "/home/fusion809/GitHub/mine/fusion809.github.io"
   ]
-PKGBUILDs:
+"hexo-site":
+  title: "hexo-site"
+  paths: [
+    "/home/fusion809/GitHub/mine/hexo-site"
+  ]
+"PKGBUILDs":
   title: "PKGBUILDs"
   paths: [
     "/home/fusion809/GitHub/mine/PKGBUILDs"


Revert "Small fix, change example to demonstrate Geometry::toJSON()"

This reverts commit f975e01f4a79127fe55a0860ac4750edf2020d6f.

--- examples/quadtree.coffee
+++ examples/quadtree.coffee
@@ -19,23 +19,14 @@

 console.log tree.queryAll().length

-bbox = reader.read "POLYGON((1.12345678 1, 1.12345678 2, 2 2, 2 1, 1.12345678 1))"
-
-# Give Geometry::toJSON a new default: max 7 digits, includes bbox
-g = require("../geos").Geometry
-toJSON = g::toJSON
-g::toJSON = -> toJSON.call(@, 7, on)
-console.log(JSON.stringify(bbox))
+bbox = reader.read "POLYGON((1 1, 1 2, 2 2, 2 1, 1 1))"

 r = tree.query bbox

 console.log r

 for i in r
-  if !geometries[i]?
-  	console.log(i, 'is undefined')
-  else
-    console.log geometries[i].toString()
+  console.log geometries[i].toString()

 console.log process.memoryUsage()
 console.log "Memory in MBytes: " + (process.memoryUsage().rss - rss)/1024/1024


change version property

change version property

--- src/scaleApp.core.coffee
+++ src/scaleApp.core.coffee
@@ -1,4 +1,4 @@
-VERSION = "0.3"
+VERSION = "0.3.1"

 modules = {}
 instances = {}
@@ -43,7 +43,7 @@

   for i,p of plugins when p.sandbox?
     plugin = new p.sandbox sb
-    sb[k] = v for k,v of plugin when plugin.hasOwnProperty k
+    sb[k] = v for own k,v of plugin

   instance = new module.creator sb
   instance.options = instanceOpts


Add button to remove imported command

Add button to remove imported command

--- extension/options.coffee
+++ extension/options.coffee
@@ -9,19 +9,20 @@
     @displayHotkey()
     @setupListeners()

-    $.when(@getCustomCommands(), @getCustomCommandIds())
+    $.when(@getCommands(), @getCustomCommandIds())
       .then @handleCommands

   setupListeners: ->
-    @$hotkeyInput.on "keypress", @onHotkeyKeypress
-    @$importForm.on "submit", @onImportFormSubmit
+    $(document)
+      .on("keypress", "#hotkey", @onHotkeyKeypress)
+      .on("submit", "#import-form", @onImportFormSubmit)
+      .on("click", "#import-list .remove", @onClickCommandRemove)

-  getCustomCommands: ->
+  getCommands: ->
     deferred = $.Deferred()

     chrome.storage.local.get "commands", (storage) ->
-      customCommands = _.filter storage.commands, (command) -> command.custom
-      deferred.resolve customCommands
+      deferred.resolve storage.commands

     deferred

@@ -33,24 +34,25 @@

     deferred

-  setCustomCommands: (value) => @customCommands = value
-
-  handleCommands: (customCommands, customCommandIds) =>
-    @customCommands = customCommands or []
+  handleCommands: (commands, customCommandIds) =>
+    @commands = commands or []
     @customCommandIds = customCommandIds or []

-    commandIndex = {}
-    commandIndex[command.gistID] = command for command in customCommands
-    unfetchedCommands = _.filter customCommandIds, (id) -> not commandIndex[id]
+    console.log @getCustomCommands(), @customCommandIds

-    for id in unfetchedCommands
-      GitHub.fetchCommand(id).then @addCommand
-
+    @fetchUnfetchedCommands()
     @renderCustomCommands()

+  getCustomCommands: =>
+    _.filter @commands, (command) -> command.custom
+
   addCommand: (command) =>
-    return if _.find(@customCommands, ({gistID}) -> gistID is command.gistID)
-    @customCommands.push command
+    return if _.any(@commands, ({gistID}) -> gistID is command.gistID)
+    command.custom = true
+
+    @commands.push command
+    chrome.storage.local.set commands: @commands
+
     @renderCustomCommands()

   syncCommand: (command) =>
@@ -58,13 +60,42 @@
     @customCommandIds.push command.gistID
     chrome.storage.sync.set customCommandIds: @customCommandIds

+  removeCommand: (removeID) =>
+    @commands = _.filter @commands, ({gistID}) ->
+      gistID isnt removeID
+
+    @customCommandIds =_.filter @customCommandIds, (id) ->
+      id isnt removeID
+
+    chrome.storage.sync.set customCommandIds: @customCommandIds
+    chrome.storage.local.set commands: @commands
+    @renderCustomCommands()
+
+  fetchUnfetchedCommands: ->
+    commandIndex = {}
+    commandIndex[command.gistID] = command for command in @getCustomCommands()
+    unfetchedCommands = _.filter @customCommandIds, (id) -> not commandIndex[id]
+
+    for id in unfetchedCommands
+      GitHub.fetchCommand(id).then @addCommand
+
   renderCustomCommands: =>
     @$importList.empty()
     commands = []
-    for command in @customCommands
-      commands.push $("<li>").text command.name
+    for command in @getCustomCommands()
+      commands.push $("""
+        <li>#{command.name}
+         <button class="remove" data-id="#{command.gistID}">Remove</button>
+        </li>
+      """)

     @$importList.append commands
+
+  onClickCommandRemove: (e) =>
+    id = $(e.target).data("id")
+    command = _.findWhere @getCustomCommands(), gistID: id
+    if confirm "Are you sure you want to remove \"#{command.name}\""
+      @removeCommand id

   onImportFormSubmit: (e) =>
     e.preventDefault()


Check data.overlay.

Check data.overlay.

--- app/javascripts/sliceDisplay.coffee
+++ app/javascripts/sliceDisplay.coffee
@@ -19,6 +19,12 @@
       overlayElt = document.getElementById('qi-slice-overlay')
       cornerstone.enable(overlayElt)

+      imageData = (data, volumeIndex, sliceIndex) ->
+        data[volumeIndex][sliceIndex]
+
+      overlayData = (data, sliceIndex) ->
+        data[sliceIndex]
+
       # @param data the binary image data
       displayImage = (data) ->
         cornerstone.displayImage(imageElt, data)
@@ -29,15 +35,28 @@
         opts = modalityLUT: INVERSION_LUT
         cornerstone.displayImage(overlayElt, data, opts)

-      # Displays the slice image and overlay.
+      # Displays the slice image and overlay. The input *data* argument
+      # is a {image, overlay} object, where:
+      # * *image* is the required 4D time series image
+      #   [volume, slice, x, y] intensity array
+      # * *overlay* is the optional 3D [slice, x, y] overlay array
       #
+      # Note: the array dimension order differs from the conventional
+      # NIfTI ndarray order in the last three dimensions, which is
+      # [x, y, slice] rather than [slice, x, y]. The caller is
+      # responsible for transposing the array, e.g. using
+      # ndarray.transpose(0, 3, 1, 2).
+      #
+      # The overlay can be a binary mask, e.g. ROI, or a scalar modeling
+      # result, e.g. Ktrans.
+      #
+      # @param data the {image, overlay} associative object
       # @param volume the one-based volume number
       # @param slice the one-based slice number
-      # @param overlayIndex the zero-based overlay index
-      display: (volume, slice, overlayIndex) ->
-        imgData = imageData(volume - 1, slice - 1)
+      display: (data, volume, slice) ->
+        imgData = imageData(data.image, volume - 1, slice - 1)
         cornerstone.displayImage(imgData)
-        if overlayIndex?
-          ovlData = overlayData(overlayIndex)
+        if data.overlay?
+          ovlData = overlayData(data.overlay, slice - 1)
           cornerstone.displayOverlay(ovlData)
 )


Bring back close button, remember state in localStorage

--- framer/Components/ShareComponent.coffee
+++ framer/Components/ShareComponent.coffee
@@ -79,14 +79,19 @@
 			minAvailableSpace: 300
 			minAvailableSpaceFullScreen: 500
 			maxDescriptionLength: 145
+			id: window.location.pathname.replace(/\//g, "")
+
+		# See if a state is set
+		@state = localStorage.getItem("framerShareSheetState-#{@options.id}")
+		@options.fixed = if !@state then false else true

 		@_checkData()
 		@render() if !Utils.isMobile()

 	render: ->
 		@_renderSheet()
+		@_renderCTA()
 		@_renderToggleButtons()
-		@_renderCTA()
 		@_renderInfo()
 		@_renderDescription() if @shareInfo.description
 		@_renderDate() if @shareInfo.openInFramerURL and @shareInfo.date
@@ -99,7 +104,13 @@
 		# Wait until the device screen x position is available
 		Utils.delay .1, =>
 			@_calculateAvailableSpace()
-			@_openIfEnoughSpace()
+
+			if @state is "open"
+				@_openSheet()
+			else if @state is "closed"
+				@_closeSheet()
+			else
+				@_openIfEnoughSpace()

 		@_startListening()

@@ -122,9 +133,10 @@

 	# Render main sheet
 	_renderSheet: ->
-		@sheet = new Layer
+		@sheet = new ShareLayer
 			width: @options.width
 			clip: true
+			ignoreEvents: false
 			point: 10
 			borderRadius: 4
 			backgroundColor: "#FFF"
@@ -165,6 +177,17 @@
 				fontWeight: "500"
 				fontSize: "13px"

+		@close = new Layer
+			parent: @cta
+			ignoreEvents: false
+			size: 12
+			point: 12
+			backgroundColor: null
+			style:
+				backgroundImage: "url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAABGdBTUEAALGPC/xhBQAAAZdJREFUSA2tlt9OgzAUh6UkRrLMCfgnwWwPoXcmBk32Crvfo+1+76A3Jt4SX8Bk8VYBkagJAc+P7CyMUWiHvYCepv2+0p42GNPpdFQUxdV4PH5eLBY/B/9QZrPZYRiGN6ZpvgjAiXm+Wq3u5/P5UV8+4FEU3RH3Isuya4GZU/BpGMZxXwnD8zy3ifflOM6TGQRB5vv+WxzHHiR4I0a7ztfU4bZtPyyXy28TkL4SGRzsUtBH0gbfEuwj6YLvCHQkKvBGgYpEFQ6WgYes4FwgdZFdSOXJZPKYpmmOPOdU5GyRMVoFGFSVEDQRQuTUPEKed8ExfpNFCJoKpzDN+pLgQ+qD057SISrzvGlMtU1UA1kdy7KeedkF9cFgUMj6V9s7v4A3lPbghAamBP+lpRqqnvhWAcN5Q7Esruu+6lwrUkEdzhvKe6IqaRTI4Ly2OpIdQRdcV7IlUIXrSDYCXbiqpBTsC1eRGH3hLMG7eq3w3WV6nndLwanq3VIF1uv17EqS5Ezg14I6fnCe1wfpxvj1wa1LE363LCv4A+knGKYRZVX+AAAAAElFTkSuQmCC')"
+
+		@_enableUserSelect(@close)
+		@_showPointer(@close)
 		@_showPointer(@open)

 	# Render CTA section
@@ -451,8 +474,7 @@

 	_openIfEnoughSpace: =>
 		# Open or close sheet based on available space
-		if @availableSpace < @threshold
-			'close'
+		if @availableSpace < @threshold and !@options.fixed
 			@_closeSheet()
 		else
 			@_openSheet()
@@ -503,8 +525,14 @@
 			@style =
 				cursor: "default"

+		@close.onClick =>
+			@_closeSheet()
+			@options.fixed = true
+			localStorage.setItem("framerShareSheetState-#{@options.id}", 'closed')
 		@open.onClick =>
 			@_openSheet()
+			@options.fixed = true
+			localStorage.setItem("framerShareSheetState-#{@options.id}", 'open')

 		# When the window resizes evaluate if the sheet needs to be hidden
 		Canvas.onResize =>


Dual barchart values are now animated.

Dual barchart values are now animated.

--- app/scripts/directives/compare-bar-chart.coffee
+++ app/scripts/directives/compare-bar-chart.coffee
@@ -39,11 +39,15 @@
             .enter().append("rect")
             .attr('class', (d, i) ->
               return 'bar' + (i+1)
-            ).attr("x", (d, i) ->
-              return x(Math.min(0, d))
-            ).attr("y", 0)
-            .attr("width", x)
+            ).attr("x", x(0))
+            .attr("y", 0)
+            .attr("width", 0)
             .attr("height", 30)
+            .transition()
+              .duration(1000)
+              .attr("width", x)
+              .attr("x", (d, i) -> return x(Math.min(0, d)))
+

       scope.drawBarChart()


Ozaria properties that can cause validation errors

--- app/schemas/models/user.coco.coffee
+++ app/schemas/models/user.coco.coffee
@@ -369,6 +369,9 @@
   administratedTeachers: c.array {}, c.objectId()
   administratingTeachers: c.array {}, c.objectId()

+  seenNewDashboardModal: { type: 'boolean', description: 'OZARIA PROPERTY' }
+  closedNewTDGetStartedTooltip: { type: 'boolean', description: 'OZARIA PROPERTY' }
+
   features:
     type: 'object'
     title: 'Feature Flags'


improve(draw-route): improve generating new Threat for Model

See #47.

--- app/scripts/controllers/draw.coffee
+++ app/scripts/controllers/draw.coffee
@@ -26,10 +26,10 @@
         values

     $scope.semverRegex = new RegExp("\\bv?(?:0|[1-9][0-9]*)\\.(?:0|[1-9][0-9]*)\\.(?:0|[1-9][0-9]*)(?:-[\\da-z\\-]+(?:\\.[\\da-z\\-]+)*)?(?:\\+[\\da-z\\-]+(?:\\.[\\da-z\\-]+)*)?\\b")
-
+
     $scope.newThreat = {
-        name: ''
-        severity: null
+        name: 'Untitled Threat'
+        severity: 'Medium'
         description: ''
     }

@@ -105,14 +105,10 @@
     # )()

     $scope.generateThreat = ->
-        model.addThreat($scope.newThreat)
+        newThreat = $.extend(true, {}, $scope.newThreat);
+        model.addThreat(newThreat)
         $scope.menu.newThreatOpen = false
         $scope.menu.threatsOpen = true
-        $scope.newThreat = {
-            name: ''
-            severity: null
-            description: ''
-        }

     $scope.shareModel = ->
         model = $scope.model


Evitamos que la 1ª petición se cargue también por AJAX.

--- app/scripts/jquery.paginator.coffee
+++ app/scripts/jquery.paginator.coffee
@@ -30,9 +30,7 @@
       $element.removeCargando()

     if defaults.history
-      if browser_supports_history()
-        $(window).bind("popstate", -> load_page($element, location.href, defaults))
-      else
+      if !browser_supports_history()
         $.history.init (hash) -> if hash != '' then load_page($element, hash, defaults)

     jQuery(defaults.paginator + ' a,' + defaults.table + ' th a', $element).live('click', ->
@@ -40,6 +38,7 @@
         if browser_supports_history()
           history.pushState(null, document.title, @href)
           load_page($element, @href, defaults)
+          $(window).bind("popstate", -> load_page($element, location.href, defaults))
         else
           $.history.load(@href)
       else


Fixed bug in query projection

Fixed bug in query projection

--- mongo-query.coffee
+++ mongo-query.coffee
@@ -84,12 +84,15 @@
 optimizeProjection = (obj) ->
   keys = Object.keys(obj).sort()
   return if keys.length <= 1
-  for i in [1 ... keys.length]
+  i = 1
+  while i < keys.length
     a = keys[i-1]
     b = keys[i]
     if common.startsWith(b, a)
       if b.charAt(a.length) == '.' or b.charAt(a.length - 1) == '.'
         delete obj[b]
+        keys.splice(i--, 1)
+    ++ i

 exports.test = test


Spread promisified request call

Spread promisified request call

Holy shit this was a frustrating issue. When you promisify request it returns an array since the callback args are not standard form.
https://github.com/petkaantonov/bluebird/issues/309

--- src/streak-podium.coffee
+++ src/streak-podium.coffee
@@ -16,33 +16,40 @@
 #   Nigel Rahkola <me@nigelrahkola.com>
 #   Mitch Leblanc <>

+Promise = require("bluebird")
+request = Promise.promisify(require("request"))

 module.exports = (robot) ->
-  robot.hear /org test1/i, (res) ->
+  robot.hear /ladder/i, (res) ->
     orgLogin = "pulseenergy"  # TODO: also get this from an env var
     access_token = process.env.HUBOT_ORG_ACCESS_TOKEN
     unless access_token?
       console.log("Missing ORG_ACCESS_TOKEN in environment: please set and try again")
       return
     console.log("Found the access token in the environment! #{access_token}")
-    ladder = buildLadder(orgLogin, access_token, robot, res)

+    options = {
+      uri: "https://api.github.com/orgs/#{orgLogin}/members",
+      json: "true",
+      headers: {
+        "accept": "application/json",
+        "Authorization": "token #{access_token}",
+        'User-Agent': 'request'
+      }
+    }
+    request(options).spread((response, body) ->
+      console.log(response)
+      console.log('\n\n@@@\n')
+      console.log(body)
+      return body
+    ).then((body) ->
+      return getContributions(body[0].login)
+    ).then((user) ->
+      console.log('\n\nUSERLOGIN')
+      console.log(user)
+    )

-buildLadder = (orgLogin, access_token, robot, res) ->
-  robot.http("https://api.github.com/orgs/#{orgLogin}/members")
-    .header("accept", "application/json", "Authorization", "token #{access_token}")
-    .get() (err, response, body) ->
-      if err
-        console.log("NUTS! #{err} statusCode: #{response.statusCode}")
-      else
-        result = JSON.parse(body)
-        users = (((json) -> return json) json for json in result)
-        getContributions(robot, res, users[0].login)
-
-getContributions = (robot, res, userLogin) ->
-   robot.http("https://github.com/users/#{userLogin}/contributions")
-    .get() (err, response, body) ->
-      if err
-        console.log("#{response.statusCode} getting  contributions for user #{userLogin}")
-      else
-        res.send body
+getContributions = (userLogin) ->
+  request({uri: "https://github.com/users/#{userLogin}/contributions"}).spread((response, body) ->
+    return body
+  )


Cleaned up new dialog view

Cleaned up new dialog view

--- public/scripts/backbone-schedule/views/modals/new.coffee
+++ public/scripts/backbone-schedule/views/modals/new.coffee
@@ -8,7 +8,7 @@

     initialize: ->
       _.bindAll @
-      @newTemplate = _.template(newTemplate)
+      @newTemplate = _.template newTemplate
       @render()

     events:
@@ -16,15 +16,20 @@

     new: ->
       Shark.schedule = new Schedule
-      Shark.term = Shark.terms.where( {_id: $('#term-list option:selected').val()} )[0]
-      $('#new').modal('hide')
+      $options = @$el.find '#term-list'
+      # Select the term chosen, defaulting to the current Term if none checked
+      Shark.term = Shark.terms.where( _id: $options.val() )[0] or Shark.school.get 'currentTerm'
+      # Close the modal
+      @$el.modal 'hide'

     render: ->
       @$el.html @newTemplate()
+      $list = @$el.find '#term-list'
       Shark.terms.each (term) =>
-        term_text = term.get('name')
-        term_text = term_text.charAt(0).toUpperCase() + term_text.slice(1)
-        @$el.find('#term-list').append $('<option />').val(term.get('_id')).text(term_text)
+        termText = term.get 'name'
+        termText = termText.charAt(0).toUpperCase() + termText.slice 1
+        termId = term.get '_id'
+        $list.append $('<option/>').val(termId).text(termText)

   NewView
 )


Add ESM test for 3 lang mods

Add ESM test for 3 lang mods

--- src/test/test-esm.coffee
+++ src/test/test-esm.coffee
@@ -7,6 +7,9 @@
 ###* @type {Data} See data structure in all-data.coffee ###
 import allData from './data/all-data.mjs'
 import numbo from '../esm/numbo.mjs'
+import enUS from '../esm/en-us.mjs'
+import zhTW from '../esm/zh-tw.mjs'
+import zhCN from '../esm/zh-cn.mjs'

 import langs from './shared/langs.coffee'
 import types from './shared/types.coffee'
@@ -23,4 +26,17 @@
 		)
 		testResults.push eachTestResult

+langMods = [
+	{ lang: 'enUS', mod: enUS }
+	{ lang: 'zhTW', mod: zhTW }
+	{ lang: 'zhCN', mod: zhCN }
+]
+for langMod in langMods
+	for type in types
+		dataList = allData[langMod.lang][type]
+		eachTestResult = createResult(
+			langMod.lang, langMod.mod, dataList, langMod.lang, type
+		)
+		testResults.push eachTestResult
+
 console.log testResults


SplitPanel: Fix for affectedPanel logic on resizeMethod.

--- src/components/split/splitview.coffee
+++ src/components/split/splitview.coffee
@@ -283,7 +283,7 @@
     value         = @_sanitizeSize value
     value         = @_getSize() if value > @_getSize()
     askedPanel    = @panels[index]
-    affectedPanel = @panels[index+1%2]
+    affectedPanel = @panels[(index + 1) % 2]

     if askedPanel._getSize() is value
       @_resizeDidStop()


making open date work for now

making open date work for now

--- src/components/task-plan/builder.cjsx
+++ src/components/task-plan/builder.cjsx
@@ -15,6 +15,8 @@
 {TutorInput, TutorDateInput, TutorDateFormat, TutorTextArea} = require '../tutor-input'
 {CourseStore}   = require '../../flux/course'
 {UnsavedStateMixin} = require '../unsaved-state'
+
+ISO_DATE_FORMAT = 'YYYY-MM-DD'

 module.exports = React.createClass
   displayName: 'TaskPlanBuilder'
@@ -57,21 +59,21 @@
       tasking

   getOpensAtDefault: ->
-    moment(TimeStore.getNow()).add(1, 'day').toDate()
+    moment(TimeStore.getNow()).add(1, 'day').format(ISO_DATE_FORMAT)

   getQueriedOpensAt: ->
     {opens_at} = @context?.router?.getCurrentQuery() # attempt to read the open date from query params
     isNewPlan = TaskPlanStore.isNew(@props.id)
-    opensAt = if opens_at and isNewPlan then moment(opens_at).toDate()
+    opensAt = if opens_at and isNewPlan then TimeHelper.getMomentPreserveDate(opens_at).toDate()
     if not opensAt
       # default open date is tomorrow
       opensAt = @getOpensAtDefault()

     # if there is a queried due date, make sure it's not the same as the open date
     dueAt = @getQueriedDueAt()
-    if dueAt? and moment(dueAt).isSame(opensAt, 'day')
+    if dueAt? and not TimeHelper.getMomentPreserveDate(dueAt).isAfter(opensAt, 'day')
       # make open date today if default due date is tomorrow
-      opensAt = moment(TimeStore.getNow()).toDate()
+      opensAt = moment(TimeStore.getNow()).format(ISO_DATE_FORMAT)

     opensAt


Segmenting config in favor of organization and conditional options.

--- src/toaster/toast.coffee
+++ src/toaster/toast.coffee
@@ -117,46 +117,52 @@

     # project nature
     if config.browser?
-      config.nature_is_browser = true
-      @_toast_browser config, config.browser
+      @_toast_browser config
     else
-      config.nature_is_node = true
-      @_toast_node config.node or {}
-
-  _toast_browser:( base_config, config )->
-
-    # simple mixin
-    config[k] = v for k, v of base_config
-
-    # ...: main - mandatory
-    unless config.main?
-      msg = 'You need to inform the main entry point (module id) for your app.'
-      msg += '\nCheck your `toaster.coffee` config file.'
-      return error msg
-
-    # ...: minify - optional
-    config.minify ?= true # boolean
-
-    # ...: webroot - optional
-    config.webroot ?= '' # string
-    if @toaster.cli.argv.s? and config.webroot is ''
-      msg = 'Inform your webroot before using static server.'
-      msg += '\nCheck your `toaster.coffee` config file.'
-      return error msg
-
-    # ...: port - optional
-    config.port ?= 3000
-
-    # ...: base_url - optional
-    if config.base_url?
-      if config.base_url.slice -1 isnt '/'
-        config.base_url += '/'
-    else
-       config.base_url = ''
+      # TODO
+      # @_toast_node config.node or {}
+
+  _toast_browser:( config )->
+
+    browser = config.browser
+
+    # ...: amd - optional
+    if browser.amd?
+
+      # ...: main - mandatory
+      unless browser.amd.main?
+        msg = 'You need to inform the main entry point (module id) for your '
+        msg += 'app. \nCheck your `toaster.coffee` config file.'
+        return error msg
+
+      # ...: boot - mandatory
+      unless browser.amd.boot?
+        msg = 'You need to inform the amd/boot file name for your app.'
+        msg += '\nCheck your `toaster.coffee` config file.'
+        return error msg
+
+      # ...: base_url - optional
+      if browser.amd.base_url?
+        if browser.amd.base_url.slice -1 isnt '/'
+          browser.amd.base_url += '/'
+      else
+          browser.amd.base_url = ''
+
+    # ...: server - optional
+    if server?
+
+      # ...: root  (mandatory when server is informed)
+      unless server.root?
+        msg = 'You need to inform the `root` property in your server config.'
+        msg += '\nCheck your `toaster.coffee` config file.'
+        return error msg
+
+      # ...: port - optional
+      server.port ?= 3000

     # ...: vendors - optional
-    if config.vendors?
-      for vname, vurl of config.vendors
+    if browser.vendors?
+      for vname, vurl of browser.vendors

         continue if /^http/m.test vurl

@@ -167,7 +173,7 @@
           if (fs.lstatSync vpath).isSymbolicLink()
             vpath = fs.readlinkSync vendor

-          config.vendors[vname] = vpath
+          browser.vendors[vname] = vpath

         else
           # error "Local vendor not found. #{dir}\nCheck your config."
@@ -176,16 +182,20 @@
           return error msg

     # ...:optimize - optional
-    config.optimize ?= null
+    browser.optimize ?= null

     # ...:optimization method (at least one should be specified)
-    if config.optimize?
-      if (config.optimize.merge? or config.optimize.layers?) is false
+    if browser.optimize?
+
+      # ...: minify - optional
+      browser.minify ?= true # boolean
+
+      if (browser.optimize.merge? or browser.optimize.layers?) is false
         msg = 'Check your `toaster.coffee` at least one method is need in order'
         msg += ' to optimize your project.'
         return error msg

-      else if (config.optimize.merge? and config.optimize.layers?)
+      else if (browser.optimize.merge? and browser.optimize.layers?)
         msg = 'Check your `toaster.coffee`, only one optimization method is '
         msg += 'allowed, please use `layers` or `merge`.'
         return error msg


If connect timeout, do not create a new data set.

In existing code, we start up by looking for Sage Simulation data set. If we time out or don't find it we create a new one.
This changes the logic to omitting the timeout condition.

--- src/code/models/codap-connect.coffee
+++ src/code/models/codap-connect.coffee
@@ -71,7 +71,9 @@
       action: 'get',
       resource: 'dataContext[Sage Simulation]'
     , (ret) =>
-      if ret?.success
+      # ret==null is indication of timeout, not an indication that the data set
+      # doesn't exist.
+      if !ret or ret.success
         @initGameHandler ret
       else
         @_createDataContext()


remove possibly misleading log message.

remove possibly misleading log message.

--- src/code/models/codap-connect.coffee
+++ src/code/models/codap-connect.coffee
@@ -48,7 +48,7 @@

   initGameHandler: =>
     @initAccomplished = true
-    log.info 'CodapConnect: connection established.'
+
   #
   # Requests a CODAP action, if the Building Models tool is configured to reside
   # in CODAP. For actions that may be requested, see


Fix colombian regex

Fix colombian regex

--- src/coffee/countries/colombia.coffee
+++ src/coffee/countries/colombia.coffee
@@ -8,7 +8,7 @@
 		@countryName = "Colombia"
 		@countryNameAbbr = "COL"
 		@countryCode = '57'
-		@regex = /^((\+|)57|)(0|)(((1|2|3|4|5|6|7|8)\d{7})|(3\d{10}))$/
+		@regex = /^((\+|)57|)(0|)(((1|2|3|4|5|6|7|8)\d{7})|(3\d{9}))$/
 		@optionalTrunkPrefix = '0'
 		@nationalNumberSeparator = ' '
 		@nationalDestinationCode =


add controls and fullscreen.

add controls and fullscreen.

--- js/3panorama.coffee
+++ js/3panorama.coffee
@@ -127,6 +127,9 @@
         # bind mouse event to control the camera
         bindMouseTouchControl(renderer.domElement)

+        # control bar
+        initControls(container)
+
         # resize the camera and renderer when window size changed.
         window.addEventListener("resize", onWindowResize, false)

@@ -193,6 +196,61 @@
         target.addEventListener "touchmove", touchMoveHandle, false
         target.addEventListener "touchend", touchEndHandle, false

+    toggleTargetFullscreen = (target) ->
+        if document.fullscreenElement or document.mozRequestFullScreen or document.webkitFullscreenElement or document.msFullscreenElement
+            # fullscreen state. to exit fullscreen
+            if document.exitFullscreen
+                document.exitFullscreen()
+            else if document.msExitFullscreen
+                document.msExitFullscreen();
+            else if document.mozCancelFullScreen
+                document.mozCancelFullScreen()
+            else if document.webkitExitFullscreen
+                document.webkitExitFullscreen()
+            else
+                console.log("The bowser doesn't support fullscreen mode") # Don't support fullscreen
+        else
+            # to enter fullscreen
+            if document.documentElement.requestFullscreen
+                target.requestFullscreen()
+            else if document.documentElement.msRequestFullscreen
+                target.msRequestFullscreen()
+            else if document.documentElement.mozRequestFullScreen
+                target.mozRequestFullScreen()
+            else if document.documentElement.webkitRequestFullscreen
+                target.webkitRequestFullscreen()
+            else
+                console.log("The bowser doesn't support fullscreen mode")
+
+
+    initControls = (container) ->
+        controls = document.createElement("div")
+        controls.className = "3panorama-controls"
+        # postion: above the container
+        controls.style.position = "absolute"
+        controls.style.bottom = 0
+
+        controls.style.width = "100%"
+        controls.style.height = "3.5em"
+        controls.style["min-height"] = "32px"
+
+        fullscreen = document.createElement("img")
+        fullscreen.src = "data:image/svg+xml;utf8;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iaXNvLTg4NTktMSI/Pgo8IS0tIEdlbmVyYXRvcjogQWRvYmUgSWxsdXN0cmF0b3IgMTkuMC4wLCBTVkcgRXhwb3J0IFBsdWctSW4gLiBTVkcgVmVyc2lvbjogNi4wMCBCdWlsZCAwKSAgLS0+CjxzdmcgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgdmVyc2lvbj0iMS4xIiBpZD0iTGF5ZXJfMSIgeD0iMHB4IiB5PSIwcHgiIHZpZXdCb3g9IjAgMCAzMjAgMzIwIiBzdHlsZT0iZW5hYmxlLWJhY2tncm91bmQ6bmV3IDAgMCAzMjAgMzIwOyIgeG1sOnNwYWNlPSJwcmVzZXJ2ZSIgd2lkdGg9IjI0cHgiIGhlaWdodD0iMjRweCI+CjxnIGlkPSJYTUxJRF8xMDVfIj4KCTxnPgoJCTxnPgoJCQk8cG9seWdvbiBwb2ludHM9IjEyNS4wMDcsMTgwLjg0OSAyMCwyODUuODU3IDIwLDIwMy40MDEgMCwyMDMuNDAxIDAsMzIwIDExNi41OTksMzIwIDExNi41OTksMzAwIDM0LjE0MiwzMDAgMTM5LjE1LDE5NC45OTIgICAgICAgICAiIGZpbGw9IiNGRkZGRkYiLz4KCQkJPHBvbHlnb24gcG9pbnRzPSIyMDMuNDAxLDAgMjAzLjQwMSwyMCAyODUuODU1LDIwIDE4MC44NSwxMjUuMDA1IDE5NC45OTMsMTM5LjE0OCAzMDAsMzQuMTQgMzAwLDExNi41OTkgMzIwLDExNi41OTkgMzIwLDAgICAgICAgICAiIGZpbGw9IiNGRkZGRkYiLz4KCQkJPHBvbHlnb24gcG9pbnRzPSIyMCwzNC4xNDIgMTI1LjAwNiwxMzkuMTQ4IDEzOS4xNDksMTI1LjAwNiAzNC4xNDMsMjAgMTE2LjU5OSwyMCAxMTYuNTk5LDAgMCwwIDAsMTE2LjU5OSAyMCwxMTYuNTk5ICAgICIgZmlsbD0iI0ZGRkZGRiIvPgoJCQk8cG9seWdvbiBwb2ludHM9IjMwMCwyODUuODU1IDE5NC45OTQsMTgwLjg0OSAxODAuODUxLDE5NC45OTEgMjg1Ljg2LDMwMCAyMDMuNDAxLDMwMCAyMDMuNDAxLDMyMCAzMjAsMzIwIDMyMCwyMDMuNDAxICAgICAgMzAwLDIwMy40MDEgICAgIiBmaWxsPSIjRkZGRkZGIi8+CgkJPC9nPgoJPC9nPgo8L2c+CjxnPgo8L2c+CjxnPgo8L2c+CjxnPgo8L2c+CjxnPgo8L2c+CjxnPgo8L2c+CjxnPgo8L2c+CjxnPgo8L2c+CjxnPgo8L2c+CjxnPgo8L2c+CjxnPgo8L2c+CjxnPgo8L2c+CjxnPgo8L2c+CjxnPgo8L2c+CjxnPgo8L2c+CjxnPgo8L2c+Cjwvc3ZnPgo="
+        fullscreen.style.margin = "0.3em"
+        fullscreen.style.height = "75%"
+        fullscreen.style["min-height"] = "24px"
+
+        fullscreen.addEventListener("click",
+            ->
+                toggleTargetFullscreen(container)
+            , false)
+
+
+
+        controls.appendChild(fullscreen)
+
+        container.appendChild(controls)
+

     onWindowResize = (event) ->
         getViewerSize()


Cursor now moves to a more natural spot after insertLine replaces blank line

--- web/scripts/playerCodeEditor.coffee
+++ web/scripts/playerCodeEditor.coffee
@@ -585,13 +585,15 @@
         if currentLine.trim() == ""
             text.removeLines currentRow, currentRow
             text.insertLines currentRow, [line]
+            cursorOffset = 1
         else
             text.insertLines currentRow + 1, [line]
+            cursorOffset = 2

         if text.getLength() == 2 and text.getLine(currentRow) == ""
             text.removeNewLine currentRow

-        @editor.gotoLine currentRow + 2, 0, false
+        @editor.gotoLine currentRow + cursorOffset, 0, false
         return

     editLine: ({text, editRow, newLine}) ->


make startup message consistent

make startup message consistent

--- app.coffee
+++ app.coffee
@@ -33,4 +33,4 @@
 host = Settings.internal?.tags?.host || "localhost"
 port = Settings.internal?.tags?.port || 3012
 app.listen port, host, ->
-	console.log "tags-sharelatex listening at #{host}:#{port}"
+	logger.info "tags starting up, listening on #{host}:#{port}"


fix beginShutdown to use server.close()

fix beginShutdown to use server.close()

--- app.coffee
+++ app.coffee
@@ -117,7 +117,7 @@
 			process.exit 1
 		, 120*1000
 		killTimer.unref?() # prevent timer from keeping process alive
-		app.close () ->
+		server.close () ->
 			logger.log "closed all connections"
 			Metrics.close()
 			process.disconnect?()
@@ -128,7 +128,7 @@
 host = "0.0.0.0"

 if !module.parent # Called directly
-	app.listen port, host, (error) ->
+	server = app.listen port, host, (error) ->
 		logger.info "Filestore starting up, listening on #{host}:#{port}"


throw on request error will improve in the future

--- app.coffee
+++ app.coffee
@@ -26,6 +26,8 @@
                 response.on "data", (chunk) -> json += chunk

                 response.on "end", -> callback JSON.parse(json), type
+            else
+                throw response.statusCode
         ).end()

     # URLs to API.


"what fucking fagotry is that?"

"what fucking fagotry is that?"

--- app.coffee
+++ app.coffee
@@ -69,7 +69,7 @@

     fs.unlinkSync config.faye.socket

-    oldmask = process.umask(0000)
+    oldmask = process.umask(0o0000)
     faye.listen config.faye.socket
     process.umask(oldmask)


changed session store which should work with sentinel now

--- app.coffee
+++ app.coffee
@@ -17,11 +17,15 @@
 # care of parsing these to req.body._csrf
 bodyParser = require("body-parser")

+
+redis = require("redis-sharelatex")
+rclient = redis.createClient(settings.redis.web)
+
 session    = require('express-session')
 RedisStore = require('connect-redis')(session)

-redis = require("redis-sharelatex")
-rclient = redis.createClient(Settings.redis.web)
+sessionStore = new RedisStore(client:rclient)
+

 IndexController = require "./app/js/IndexController"
 AuthenticationController = require "./app/js/AuthenticationController"
@@ -39,11 +43,7 @@
 # Cookies and sessions.
 fiveDaysInMilliseconds = 5 * 24 * 60 * 60 * 1000
 app.use(session(
-	store: new RedisStore({
-		host: settings.redis.web.host,
-		port: settings.redis.web.port,
-		pass: settings.redis.web.password
-	})
+	store:sessionStore
 	secret: settings.security.sessionSecret,
 	name: settings.cookieName,
 	cookie:


Add: set port from env

Add: set port from env

--- app.coffee
+++ app.coffee
@@ -6,4 +6,4 @@
 app.get "/", (req, res) ->
   request req.query.url, (err, resp, body) ->
     res.send body
-app.listen 3000
+app.listen process.env.PORT or 3005


Use current user's options

Use current user's options

--- resources/assets/coffee/react/profile-page/detail.coffee
+++ resources/assets/coffee/react/profile-page/detail.coffee
@@ -33,7 +33,7 @@
     super props

     @state =
-      expanded: props.user.ranking_expanded
+      expanded: if currentUser.id? then currentUser.ranking_expanded else true

   render: =>
@@ -81,12 +81,13 @@

   toggleExtend: =>
-    $.ajax laroute.route('account.options'),
-      method: 'put',
-      dataType: 'json',
-      data:
-        user_profile_customization:
-          ranking_expanded:
-            !@state.expanded
+    if currentUser.id?
+      $.ajax laroute.route('account.options'),
+        method: 'put',
+        dataType: 'json',
+        data:
+          user_profile_customization:
+            ranking_expanded:
+              !@state.expanded

     @setState expanded: !@state.expanded