Merge remote-tracking branch 'origin/master'

This commit is contained in:
Scott Erickson 2014-02-17 12:00:39 -08:00
commit 1c49e475b9
23 changed files with 258 additions and 70 deletions

View file

@ -210,8 +210,11 @@ class Angel
@purgatoryTimer = null
if @worker
worker = @worker
_.defer -> worker.terminate()
@worker.removeEventListener 'message', @onWorkerMessage
onWorkerMessage = @onWorkerMessage
_.delay ->
worker.terminate()
worker.removeEventListener 'message', onWorkerMessage
, 1000
@worker = null
@

View file

@ -98,10 +98,10 @@ module.exports = class LevelLoader extends CocoClass
onSupermodelError: ->
msg = $.i18n.t('play_level.level_load_error',
defaultValue: "Level could not be loaded.")
@$el.html('<div class="alert">' + msg + '</div>')
$('body').append('<div class="alert">' + msg + '</div>')
onSupermodelLoadedOne: (e) ->
@notifyProgress()
@update()
# Things to do when either the Session or Supermodel load
@ -109,7 +109,7 @@ module.exports = class LevelLoader extends CocoClass
@notifyProgress()
return if @updateCompleted
return unless @supermodel.finished() and @sessionsLoaded()
return unless @supermodel?.finished() and @sessionsLoaded()
@denormalizeSession()
@loadLevelSounds()
app.tracker.updatePlayState(@level, @session)

View file

@ -129,7 +129,7 @@ module.exports = class CocoRouter extends Backbone.Router
view.render()
closeCurrentView: ->
window.currentModal?.hide()
window.currentModal?.hide?()
return unless window.currentView?
if window.currentView.cache
window.currentView.scrollY = window.scrollY

View file

@ -140,8 +140,8 @@ module.exports = CocoSprite = class CocoSprite extends CocoClass
@show()
return @updateActionDirection() unless action.animation or action.container
m = if action.container then "gotoAndStop" else "gotoAndPlay"
@imageObject[m] action.name
@imageObject.framerate = action.framerate or 20
@imageObject[m] action.name
reg = @getOffset 'registration'
@imageObject.regX = -reg.x
@imageObject.regY = -reg.y

View file

@ -254,8 +254,10 @@ module.exports = class SpriteBoss extends CocoClass
updateSelection: ->
if @selectedSprite?.thang and (not @selectedSprite.thang.exists or not @world.getThangByID @selectedSprite.thang.id)
@selectSprite null, null, null
@selectionMark?.toggle false
@updateTarget()
return unless @selectionMark
@selectedSprite = null unless @selectedSprite?.thang
@selectionMark.toggle @selectedSprite?
@selectionMark.setSprite @selectedSprite
@selectionMark.update()

View file

@ -36,6 +36,7 @@ module.exports = Surface = class Surface extends CocoClass
worldLoaded: false
scrubbing: false
debug: false
frameRate: 60
defaults:
wizards: true
@ -190,7 +191,7 @@ module.exports = Surface = class Surface extends CocoClass
createjs.Tween.removeTweens(@)
@currentFrame = @scrubbingTo
@scrubbingTo = parseInt(progress * @world.totalFrames)
@scrubbingTo = Math.floor(progress * @world.totalFrames)
@scrubbingPlaybackSpeed = Math.sqrt(Math.abs(@scrubbingTo - @currentFrame) * @world.dt / (scrubDuration or 0.5))
if scrubDuration
t = createjs.Tween
@ -227,7 +228,7 @@ module.exports = Surface = class Surface extends CocoClass
@onFrameChanged()
getCurrentFrame: ->
return Math.max(0, Math.min(parseInt(@currentFrame), @world.totalFrames - 1))
return Math.max(0, Math.min(Math.floor(@currentFrame), @world.totalFrames - 1))
getProgress: -> @currentFrame / @world.totalFrames
@ -344,8 +345,7 @@ module.exports = Surface = class Surface extends CocoClass
@stage.addEventListener 'stagemousedown', @onMouseDown
@canvas.on 'mousewheel', @onMouseWheel
@hookUpChooseControls() if @options.choosing
console.log "Setting fps", @world.frameRate unless @world.frameRate is 30
createjs.Ticker.setFPS @world.frameRate
createjs.Ticker.setFPS @frameRate
showLevel: ->
return if @dead
@ -467,16 +467,16 @@ module.exports = Surface = class Surface extends CocoClass
@trailmaster.tick() if @trailmaster
# Skip some frame updates unless we're playing and not at end (or we haven't drawn much yet)
frameAdvanced = (@playing and @currentFrame < @world.totalFrames) or @totalFramesDrawn < 2
++@currentFrame if frameAdvanced
@currentFrame += @world.frameRate / @frameRate if frameAdvanced
@updateSpriteSounds() if frameAdvanced
break unless Dropper.drop()
# these are skipped for dropped frames
@updateState @currentFrame isnt oldFrame
@drawCurrentFrame()
@drawCurrentFrame e
@onFrameChanged()
@updatePaths() if (@totalFramesDrawn % 2) is 0 or createjs.Ticker.getMeasuredFPS() > createjs.Ticker.getFPS() - 5
Backbone.Mediator.publish('surface:ticked', {dt: @world.dt})
@updatePaths() if (@totalFramesDrawn % 4) is 0 or createjs.Ticker.getMeasuredFPS() > createjs.Ticker.getFPS() - 5
Backbone.Mediator.publish('surface:ticked', {dt: 1 / @frameRate})
mib = @stage.mouseInBounds
if @mouseInBounds isnt mib
Backbone.Mediator.publish('surface:mouse-' + (if mib then "over" else "out"), {})
@ -484,6 +484,11 @@ module.exports = Surface = class Surface extends CocoClass
updateSpriteSounds: ->
@world.getFrame(@getCurrentFrame()).restoreState()
current = Math.max(0, Math.min(@currentFrame, @world.totalFrames - 1))
if current - Math.floor(current) > 0.01
next = Math.ceil current
ratio = current % 1
@world.frames[next].restorePartialState ratio if next > 1
@spriteBoss.updateSounds()
updateState: (frameChanged) ->
@ -492,9 +497,9 @@ module.exports = Surface = class Surface extends CocoClass
@spriteBoss.update frameChanged
@dimmer?.setSprites @spriteBoss.sprites
drawCurrentFrame: ->
drawCurrentFrame: (e) ->
++@totalFramesDrawn
@stage.update()
@stage.update e
# paths - TODO: move to SpriteBoss? but only update on frame drawing instead of on every frame update?

View file

@ -67,7 +67,7 @@ module.exports = class ThangState
restore: ->
# Restore trackedProperties' values to @thang, retrieving them from @trackedPropertyValues if needed. Optimize it.
return @ if @thang._state is @
return @ if @thang._state is @ and not @thang.partialState
unless @hasRestored # Restoring in a deserialized World for first time
props = []
for prop, propIndex in @trackedPropertyKeys
@ -81,6 +81,26 @@ module.exports = class ThangState
else # Restoring later times
for prop, propIndex in @trackedPropertyKeys
@thang[prop] = @props[propIndex]
@thang.partialState = false
@
restorePartial: (ratio) ->
inverse = 1 - ratio
for prop, propIndex in @trackedPropertyKeys when prop is "pos" or prop is "rotation"
if @hasRestored
value = @props[propIndex]
else
type = @trackedPropertyTypes[propIndex]
storage = @trackedPropertyValues[propIndex]
value = @getStoredProp propIndex, type, storage
if prop is "pos"
@thang.pos = @thang.pos.copy()
@thang.pos.x = inverse * @thang.pos.x + ratio * value.x
@thang.pos.y = inverse * @thang.pos.y + ratio * value.y
@thang.pos.z = inverse * @thang.pos.z + ratio * value.z
else if prop is "rotation"
@thang.rotation = inverse * @thang.rotation + ratio * value
@thang.partialState = true
@
serialize: (frameIndex, trackedPropertyIndices, trackedPropertyTypes, trackedPropertyValues, specialValuesToKeys, specialKeysToValues) ->

View file

@ -2,7 +2,7 @@
class Vector
@className: "Vector"
# Class methods for nondestructively operating
for name in ['add', 'subtract', 'multiply', 'divide']
for name in ['add', 'subtract', 'multiply', 'divide', 'limit', 'normalize']
do (name) ->
Vector[name] = (a, b, useZ) ->
a.copy()[name](b, useZ)

View file

@ -25,6 +25,9 @@ module.exports = class WorldFrame
#console.log "Frame", @time, "restoring state for", thang.id, "and saying it don't exist"
thang.exists = false
restorePartialState: (ratio) ->
thangState.restorePartial ratio for thangID, thangState of @thangStateMap
restoreStateForThang: (thang) ->
thangState = @thangStateMap[thang.id]
if not thangState

View file

@ -89,6 +89,7 @@
margin: 8px 8px 0 0
overflow-y: scroll
float: left
@include user-select(text)
.prop
img

View file

@ -6,12 +6,10 @@
left: 10px
right: 10px
height: 140px
padding-top: 50px
// Height and padding-top relate to .tab-content height
padding-left: 35px
padding-right: 60px
// Docs' popovers flicker when too far right, so we have big padding-right
// twilight: color: #E2E2E2
// Height relates to .tab-content height
padding-top: 35px
padding-left: 12px
padding-right: 4px
color: #333
// Get crazy with the backgrounds so that we can lower the opacity on the editor background above it, making a gradient of the disabled background color on the top around where it's usually covered
background-color: transparent
@ -36,3 +34,23 @@
line-height: 16px
margin: 0 4px
font-weight: normal
.nav > li > a
padding: 2px 20px 0px 20px
margin-bottom: 3px
ul.nav.nav-pills
li.active a
background-color: transparent
&.multiple-tabs li.active a
background-color: lighten(rgb(230, 212, 146), 10%)
&.multiple-tabs li:not(.active) a
cursor: pointer
//.nav-pills > li.active > a, .nav-pills > li.active > a:hover, .nav-pills > li.active > a:focus
// background-color: lighten(rgb(230, 212, 146), 10%)
.property-entry-column
display: inline-block
margin-right: 3px
vertical-align: top

View file

@ -1,28 +1,32 @@
@import "../../../bootstrap/mixins"
@import "app/styles/bootstrap/mixins"
@import "app/styles/mixins"
.spell-palette-entry-view
display: inline-block
margin: 0px 4px
display: block
padding: 0px 4px
font-family: Menlo, Monaco, Consolas, "Courier New", monospace
font-size: 12px
border: 1px solid transparent
cursor: pointer
@include user-select(all)
&:hover
border: 1px solid #BFF
&.pinned
background-color: darken(#BFF, 20%)
// Pulling these colors from the most relevant textmate-theme classes
&.function
// twilight: color: #7587A6
color: #0000A2
&.object
// twilight: color: #AC885B
color: rgb(6, 150, 14)
&.string
// twilight: color: #CDA869
color: rgb(3, 106, 7)
&.number
// twilight: color: #F9EE98
color: rgb(0, 0, 205)
&.boolean
// twilight: color: #C9CEA8
color: rgb(88, 92, 246)
&.undefined
// twilight: color: #CF6A4C
color: rgb(197, 6, 11)

View file

@ -1,11 +1,23 @@
@import "../../../bootstrap/mixins"
@import "app/styles/bootstrap/mixins"
@import "app/styles/mixins"
#tome-view
height: 100%
> .popover
// Only those popovers which are our direct children (spell documentation)
left: auto !important
top: auto !important
right: 100%
bottom: 151px
@include user-select(text)
&.pinned
@include box-shadow(0 0 500px white)
.popover
padding: 10px
max-width: 400px
min-width: 400px
background: transparent url(/images/level/popover_background.png)
background-size: 100% 100%
border: 0

View file

@ -1,3 +1,10 @@
img(src="/images/level/code_palette_background.png").code-palette-background
h4(data-i18n="play_level.tome_available_spells") Available Spells
.properties
ul(class="nav nav-pills" + (tabbed ? ' multiple-tabs' : ''))
each slug, group in entryGroupSlugs
li(class=group == "this" || slug == "available-spells" ? "active" : "")
a(data-toggle="pill", data-target='#palette-tab-' + slug)
h4= group
.tab-content
each slug, group in entryGroupSlugs
div(id="palette-tab-" + slug, class="tab-pane" + (group == "this" || slug == "available-spells" ? " active" : ""))
div(class="properties properties-" + slug)

View file

@ -16,7 +16,7 @@ module.exports = class LevelSaveView extends SaveVersionModal
constructor: (options) ->
super options
@level = options.level
getRenderData: (context={}) ->
context = super(context)
context.level = @level
@ -63,8 +63,8 @@ module.exports = class LevelSaveView extends SaveVersionModal
console.log "Got errors:", JSON.parse(res.responseText)
forms.applyErrorsToForm($(form), JSON.parse(res.responseText))
res.success =>
@hide()
modelsToSave = _.without modelsToSave, newModel
unless modelsToSave.length
url = "/editor/level/#{@level.get('slug') or @level.id}"
document.location.href = url
@hide() # This will destroy everything, so do it last

View file

@ -24,12 +24,15 @@ module.exports = class HUDView extends View
'god:new-world-created': 'onNewWorld'
events:
'click': -> Backbone.Mediator.publish 'focus-editor'
'click': 'onClick'
afterRender: ->
super()
@$el.addClass 'no-selection'
onClick: (e) ->
Backbone.Mediator.publish 'focus-editor' unless $(e.target).parents('.thang-props').length
onFrameChanged: (e) ->
@timeProgress = e.progress
@update()

View file

@ -64,7 +64,7 @@ module.exports = class SpellListTabEntryView extends SpellListEntryView
@$el.find('code').popover(
animation: true
html: true
placement: 'bottom'
placement: 'left'
trigger: 'hover'
content: @formatPopover doc
container: @$el.parent()
@ -126,4 +126,5 @@ module.exports = class SpellListTabEntryView extends SpellListEntryView
destroy: ->
@avatar?.destroy()
@$el.find('code').popover 'destroy'
super()

View file

@ -4,6 +4,7 @@ popoverTemplate = require 'templates/play/level/tome/spell_palette_entry_popover
{me} = require 'lib/auth'
filters = require 'lib/image_filter'
{downTheChain} = require 'lib/world/world_utils'
window.Vector = require 'lib/world/vector' # So we can document it
# If we use marked somewhere else, we'll have to make sure to preserve options
marked.setOptions {gfm: true, sanitize: false, smartLists: true, breaks: true}
@ -41,16 +42,32 @@ safeJSONStringify = (input, maxDepth) ->
output = input
JSON.stringify output, null, 1
# http://stackoverflow.com/a/987376/540620
$.fn.selectText = ->
el = @[0]
if document.body.createTextRange
range = document.body.createTextRange()
range.moveToElementText(el)
range.select()
else if window.getSelection
selection = window.getSelection()
range = document.createRange()
range.selectNodeContents(el)
selection.removeAllRanges()
selection.addRange(range)
module.exports = class SpellPaletteEntryView extends View
tagName: 'div' # Could also try <code> instead of <div>, but would need to adjust colors
className: 'spell-palette-entry-view'
template: template
popoverPinned: false
subscriptions:
'surface:frame-changed': "onFrameChanged"
events:
'mouseover': 'onMouseOver'
'mouseenter': 'onMouseEnter'
'mouseleave': 'onMouseLeave'
'click': 'onClick'
constructor: (options) ->
@ -59,14 +76,14 @@ module.exports = class SpellPaletteEntryView extends View
@doc = options.doc
if _.isString @doc
@doc = name: @doc, type: typeof @thang[@doc]
@doc.owner ?= 'this'
if options.isSnippet
@doc.type = 'snippet'
@doc.type = @doc.owner = 'snippet'
@doc.shortName = @doc.shorterName = @doc.title = @doc.name
else
@doc.owner ?= 'this'
suffix = if @doc.type is 'function' then '()' else ''
@doc.shortName = "#{@doc.owner}.#{@doc.name}#{suffix};"
if @doc.owner is 'this'
if @doc.owner is 'this' or options.tabbify
@doc.shorterName = "#{@doc.name}#{suffix}"
else
@doc.shorterName = @doc.shortName.replace ';', ''
@ -81,12 +98,12 @@ module.exports = class SpellPaletteEntryView extends View
super()
@$el.addClass(@doc.type)
@$el.popover(
animation: true
animation: false
html: true
placement: 'top'
trigger: 'hover'
placement: 'left'
trigger: 'manual' # Hover, until they click, which will then pin it until unclick.
content: @formatPopover()
container: @$el.parent().parent().parent()
container: '#tome-view'
)
@$el.on 'show.bs.popover', =>
Backbone.Mediator.publish 'tome:palette-hovered', thang: @thang, prop: @doc.name
@ -98,13 +115,14 @@ module.exports = class SpellPaletteEntryView extends View
content.replace /\#\{(.*?)\}/g, (s, properties) => @formatValue downTheChain(owner, properties.split('.'))
formatValue: (v) ->
return null if @doc.type is 'snippet'
return @thang.now() if @doc.name is 'now'
return '[Function]' if not v and @doc.type is 'function'
unless v?
if @doc.owner is 'this'
v = @thang[@doc.name]
else
v = window[@doc.owner][@doc.name]
v = window[@doc.owner][@doc.name] # grab Math or Vector
if @doc.type is 'number' and not isNaN v
if v == Math.round v
return v
@ -121,12 +139,29 @@ module.exports = class SpellPaletteEntryView extends View
return safeJSONStringify v, 2
v
onMouseOver: (e) ->
onMouseEnter: (e) ->
# Make sure the doc has the updated Thang so it can regenerate its prop value
@$el.data('bs.popover').options.content = @formatPopover()
@$el.popover('setContent')
@$el.popover 'show' unless @popoverPinned
onMouseLeave: (e) ->
@$el.popover 'hide' unless @popoverPinned
togglePinned: ->
if @popoverPinned
@popoverPinned = false
@$el.add('#tome-view .popover').removeClass 'pinned'
@$el.popover 'hide'
else
@popoverPinned = true
@$el.add('#tome-view .popover').addClass 'pinned'
onClick: (e) ->
unless @popoverPinned
$(e.target).selectText()
e.stopPropagation() # don't re-focus editor since we might want to select text
@togglePinned()
Backbone.Mediator.publish 'tome:palette-clicked', thang: @thang, prop: @doc.name
onFrameChanged: (e) ->
@ -134,5 +169,8 @@ module.exports = class SpellPaletteEntryView extends View
@options.thang = @thang = e.selectedThang # Update our thang to the current version
destroy: ->
$('.popover.pinned').remove() if @popoverPinned # @$el.popover('destroy') doesn't work
@togglePinned() if @popoverPinned
@$el.popover 'destroy'
@$el.off()
super()

View file

@ -5,6 +5,8 @@ filters = require 'lib/image_filter'
SpellPaletteEntryView = require './spell_palette_entry_view'
LevelComponent = require 'models/LevelComponent'
N_ROWS = 4
module.exports = class SpellPaletteView extends View
id: 'spell-palette-view'
template: template
@ -18,28 +20,56 @@ module.exports = class SpellPaletteView extends View
constructor: (options) ->
super options
@thang = options.thang
@createPalette()
getRenderData: ->
c = super()
c.entryGroups = @entryGroups
c.entryGroupSlugs = @entryGroupSlugs
c.tabbed = _.size(@entryGroups) > 1
c
afterRender: ->
super()
@createPalette()
for group, entries of @entryGroups
groupSlug = @entryGroupSlugs[group]
for columnNumber, entryColumn of entries
col = $('<div class="property-entry-column"></div>').appendTo @$el.find(".properties-#{groupSlug}")
for entry in entryColumn
col.append entry.el
entry.render() # Render after appending so that we can access parent container for popover
createPalette: ->
lcs = @supermodel.getModels LevelComponent
allDocs = {}
allDocs[doc.name] = doc for doc in (lc.get('propertyDocumentation') ? []) for lc in lcs
props = @thang.programmableProperties ? []
snippets = @thang.programmableSnippets ? []
props = _.sortBy @thang.programmableProperties ? []
snippets = _.sortBy @thang.programmableSnippets ? []
shortenize = props.length + snippets.length > 6
tabbify = props.length + snippets.length >= 10
@entries = []
@entries.push @addEntry(allDocs[prop] ? prop, shortenize) for prop in props
@entries.push @addEntry(allDocs[prop] ? prop, shortenize, true) for prop in snippets
@entries.push @addEntry(allDocs[prop] ? prop, shortenize, tabbify) for prop in props
@entries.push @addEntry(allDocs[prop] ? prop, shortenize, tabbify, true) for prop in snippets
@entries = _.sortBy @entries, (entry) ->
order = ['this', 'Math', 'Vector', 'snippets']
index = order.indexOf entry.doc.owner
index = String.fromCharCode if index is -1 then order.length else index
index += entry.doc.name
if tabbify and _.find @entries, ((entry) -> entry.doc.owner isnt 'this')
@entryGroups = _.groupBy @entries, (entry) -> entry.doc.owner
else
defaultGroup = $.i18n.t("play_level.tome_available_spells", defaultValue: "Available Spells")
@entryGroups = {}
@entryGroups[defaultGroup] = @entries
@entryGroupSlugs = {}
for group, entries of @entryGroups
@entryGroupSlugs[group] = _.string.slugify group
@entryGroups[group] = _.groupBy entries, (entry, i) -> Math.floor i / N_ROWS
null
addEntry: (doc, shortenize, isSnippet=false) ->
entry = new SpellPaletteEntryView doc: doc, thang: @thang, shortenize: shortenize, isSnippet: isSnippet
@$el.find('.properties').append entry.el
entry.render() # Render after appending so that we can access parent container for popover
entry
addEntry: (doc, shortenize, tabbify, isSnippet=false) ->
new SpellPaletteEntryView doc: doc, thang: @thang, shortenize: shortenize, tabbify: tabbify, isSnippet: isSnippet
onDisableControls: (e) -> @toggleControls e, false
onEnableControls: (e) -> @toggleControls e, true

View file

@ -51,7 +51,7 @@ module.exports = class TomeView extends View
events:
'click #spell-view': 'onSpellViewClick'
'click': -> Backbone.Mediator.publish 'focus-editor'
'click': 'onClick'
afterRender: ->
super()
@ -140,6 +140,9 @@ module.exports = class TomeView extends View
onSpellViewClick: (e) ->
@spellList.$el.hide()
onClick: (e) ->
Backbone.Mediator.publish 'focus-editor' unless $(e.target).parents('.popover').length
clearSpellView: ->
@spellView?.dismiss()
@spellView?.$el.after('<div id="' + @spellView.id + '"></div>').detach()

View file

@ -387,7 +387,6 @@ module.exports = class PlayLevelView extends View
team = team?.team unless _.isString team
team ?= 'humans'
me.team = team
console.log "level:team-set to", team
Backbone.Mediator.publish 'level:team-set', team: team
destroy: ->

View file

@ -100,8 +100,8 @@ _.extend LevelSessionSchema.properties,
type: 'object'
source:
type: 'string'
# TODO: specify this more
# TODO: specify this more
code:
type: 'object'
@ -134,6 +134,45 @@ _.extend LevelSessionSchema.properties,
default: false
index:true
submitDate:
type: c.date
title: 'Submitted'
submittedCode:
type: 'object'
matches:
type: 'array'
items:
type: 'object'
properties:
date: c.date
title: 'Time'
metrics:
type: 'object'
properties:
rank:
type: 'number'
opponents:
type: 'array'
items:
type: 'object'
properties:
id:
type: ['object', 'string']
codeSubmitDate: c.date
title: 'Submitted'
metrics:
type: 'object'
properties:
rank:
type: 'number'
c.extendBasicProperties LevelSessionSchema, 'level.session'
c.extendPermissionsProperties LevelSessionSchema, 'level.session'

View file

@ -174,7 +174,7 @@ module.exports.processTaskResult = (req, res) ->
if loggingError?
return errors.serverError res, "There as a problem logging the task computation: #{loggingError}"
updateScores clientResponseObject, (updatingScoresError, newScores) ->
updateSessions clientResponseObject, (updatingScoresError, newScores) ->
if updatingScoresError?
return errors.serverError res, "There was an error updating the scores.#{updatingScoresError}"
@ -204,10 +204,10 @@ logTaskComputation = (taskObject,taskLogObject, callback) ->
taskLogObject.save callback
updateScores = (taskObject,callback) ->
updateSessions = (taskObject,callback) ->
sessionIDs = _.pluck taskObject.sessions, 'sessionID'
async.map sessionIDs, retrieveOldScoreMetrics, (err, oldScores) ->
async.map sessionIDs, retrieveOldSessionData, (err, oldScores) ->
callback err, {"error": "There was an error retrieving the old scores"} if err?
oldScoreArray = _.toArray putRankingFromMetricsIntoScoreObject taskObject, oldScores
@ -245,7 +245,7 @@ putRankingFromMetricsIntoScoreObject = (taskObject,scoreObject) ->
scoreObject
retrieveOldScoreMetrics = (sessionID, callback) ->
retrieveOldSessionData = (sessionID, callback) ->
sessionQuery =
"_id":sessionID