From 013ace65f6e050b7d72fddb758d808ef2622c4a7 Mon Sep 17 00:00:00 2001
From: Michael Schmatz <michaelschmatz@gmail.com>
Date: Wed, 9 Jul 2014 16:24:14 -0700
Subject: [PATCH 01/58] Basic email structure plus distributed locking system

---
 app/schemas/models/mail_sent.coffee        | 16 +++++++++++++++
 app/schemas/models/mail_task.coffee        | 21 +++++++++++++++++++
 server/commons/LockManager.coffee          | 24 ++++++++++++++++++++++
 server/commons/mapping.coffee              |  2 ++
 server/mail/sent/MailSent.coffee           | 11 ++++++++++
 server/mail/sent/mail_sent_handler.coffee  | 12 +++++++++++
 server/mail/tasks/MailTask.coffee          |  7 +++++++
 server/mail/tasks/mail_task_handler.coffee | 12 +++++++++++
 server/routes/mail.coffee                  | 20 +++++++++++++++++-
 server_config.coffee                       |  4 ++++
 10 files changed, 128 insertions(+), 1 deletion(-)
 create mode 100644 app/schemas/models/mail_sent.coffee
 create mode 100644 app/schemas/models/mail_task.coffee
 create mode 100644 server/commons/LockManager.coffee
 create mode 100644 server/mail/sent/MailSent.coffee
 create mode 100644 server/mail/sent/mail_sent_handler.coffee
 create mode 100644 server/mail/tasks/MailTask.coffee
 create mode 100644 server/mail/tasks/mail_task_handler.coffee

diff --git a/app/schemas/models/mail_sent.coffee b/app/schemas/models/mail_sent.coffee
new file mode 100644
index 000000000..4236ad94b
--- /dev/null
+++ b/app/schemas/models/mail_sent.coffee
@@ -0,0 +1,16 @@
+c = require './../schemas'
+#This will represent transactional emails which have been sent
+
+MailSentSchema = c.object {
+  title: 'Sent mail'
+  description: 'Emails which have been sent through the system'
+}
+_.extend MailSentSchema.properties,
+  mailTask: c.objectId {}
+  user: c.objectId links: [{rel: 'extra', href: '/db/user/{($)}'}]
+  sent: c.date title: 'Sent', readOnly: true
+
+c.extendBasicProperties MailSentSchema, 'mail.sent'
+
+module.exports = MailSentSchema
+  
\ No newline at end of file
diff --git a/app/schemas/models/mail_task.coffee b/app/schemas/models/mail_task.coffee
new file mode 100644
index 000000000..ac450e0ee
--- /dev/null
+++ b/app/schemas/models/mail_task.coffee
@@ -0,0 +1,21 @@
+c = require './../schemas'
+#This will represent transactional emails which have been sent
+
+MailTaskSchema = c.object {
+  title: 'Mail task'
+  description: 'Mail tasks to call at certain intervals'
+}
+_.extend MailTaskSchema.properties,
+  url: 
+    title: 'URL'
+    description: 'The associated URL of the mailtask to call'
+    type: 'string'
+  frequency:
+    title: 'Frequency'
+    description: 'The number of seconds the servers should check whether or not to send the email'
+    type: 'integer'
+
+c.extendBasicProperties MailTaskSchema, 'mail.task'
+
+module.exports = MailTaskSchema
+  
\ No newline at end of file
diff --git a/server/commons/LockManager.coffee b/server/commons/LockManager.coffee
new file mode 100644
index 000000000..83dd43efc
--- /dev/null
+++ b/server/commons/LockManager.coffee
@@ -0,0 +1,24 @@
+config = require '../../server_config'
+redis = require 'redis'
+class LockManager
+  constructor: ->
+    unless config.isProduction or config.redis.host isnt "localhost"
+      throw "You shouldn't be instantiating distributed locks unless in production."
+    @redisClient = redis.createClient config.redis.port, config.redis.host
+    @lockValues = {}
+    @unlockScript = "if redis.call(\"get\",KEYS[1]) == ARGV[1] then return redis.call(\"del\",KEYS[1]) else return 0 end"
+  
+  setLock: (lockName, timeoutMs, cb) =>
+    randomNumber = Math.floor(Math.random() * 1000000000)
+    @redisClient.set [lockName,randomNumber, "NX", "PX", timeoutMs], (err, res) ->
+      if err? then return cb err, null
+      @lockValues[lockName] = randomNumber
+      cb null, res
+      
+  releaseLock: (lockName, cb) =>
+    @redisClient.eval [@unlockScript, 1, lockName, @lockValues[lockName]], (err, res) -> 
+      if err? then return cb err, null
+      #1 represents success, 0 failure
+      cb null, Boolean(Number(res))
+  
+module.exports = new RedisLock() 
\ No newline at end of file
diff --git a/server/commons/mapping.coffee b/server/commons/mapping.coffee
index 802b33790..faa0ef551 100644
--- a/server/commons/mapping.coffee
+++ b/server/commons/mapping.coffee
@@ -9,6 +9,8 @@ module.exports.handlers =
   'thang_type': 'levels/thangs/thang_type_handler'
   'user': 'users/user_handler'
   'user_remark': 'users/remarks/user_remark_handler'
+  'mail_task': 'mail/tasks/mail_task_handler'
+  'mail_sent': 'mail/sent/mail_sent_handler'
   'achievement': 'achievements/achievement_handler'
   'earned_achievement': 'achievements/earned_achievement_handler'
 
diff --git a/server/mail/sent/MailSent.coffee b/server/mail/sent/MailSent.coffee
new file mode 100644
index 000000000..7f59dd5b0
--- /dev/null
+++ b/server/mail/sent/MailSent.coffee
@@ -0,0 +1,11 @@
+mongoose = require 'mongoose'
+plugins = require '../../plugins/plugins'
+jsonschema = require '../../../app/schemas/models/mail_sent'
+
+MailSent = new mongoose.Schema({
+  sent:
+    type: Date
+    'default': Date.now
+}, {strict: false})
+
+module.exports = MailSent = mongoose.model('mailSent', MailSent)
diff --git a/server/mail/sent/mail_sent_handler.coffee b/server/mail/sent/mail_sent_handler.coffee
new file mode 100644
index 000000000..35e920c2b
--- /dev/null
+++ b/server/mail/sent/mail_sent_handler.coffee
@@ -0,0 +1,12 @@
+MailSent = require './MailSent'
+Handler = require '../../commons/Handler'
+
+class MailSentHandler extends Handler
+  modelClass: MailSent
+  editableProperties: ['mailTask','user','sent']
+  jsonSchema: require '../../../app/schemas/models/mail_sent'
+
+  hasAccess: (req) ->
+    req.user?.isAdmin()
+
+module.exports = new MailSentHandler()
diff --git a/server/mail/tasks/MailTask.coffee b/server/mail/tasks/MailTask.coffee
new file mode 100644
index 000000000..10a536787
--- /dev/null
+++ b/server/mail/tasks/MailTask.coffee
@@ -0,0 +1,7 @@
+mongoose = require 'mongoose'
+plugins = require '../../plugins/plugins'
+jsonschema = require '../../../app/schemas/models/mail_task'
+
+MailTaskSchema = new mongoose.Schema({}, {strict: false})
+
+module.exports = MailTask = mongoose.model('mail.task', MailTaskSchema)
diff --git a/server/mail/tasks/mail_task_handler.coffee b/server/mail/tasks/mail_task_handler.coffee
new file mode 100644
index 000000000..12b6be53a
--- /dev/null
+++ b/server/mail/tasks/mail_task_handler.coffee
@@ -0,0 +1,12 @@
+MailTask = require './MailTask'
+Handler = require '../../commons/Handler'
+
+class MailTaskHandler extends Handler
+  modelClass: MailTask
+  editableProperties: ['url','frequency']
+  jsonSchema: require '../../../app/schemas/models/mail_task'
+  
+  hasAccess: (req) ->
+    req.user?.isAdmin()
+    
+module.exports = new MailTaskHandler()
diff --git a/server/routes/mail.coffee b/server/routes/mail.coffee
index 4fdcef128..ae8b62e86 100644
--- a/server/routes/mail.coffee
+++ b/server/routes/mail.coffee
@@ -1,4 +1,5 @@
 mail = require '../commons/mail'
+MailTask = require '../mail/tasks/MailTask'
 User = require '../users/User'
 errors = require '../commons/errors'
 config = require '../../server_config'
@@ -6,11 +7,16 @@ LevelSession = require '../levels/sessions/LevelSession'
 Level = require '../levels/Level'
 log = require 'winston'
 sendwithus = require '../sendwithus'
-
+if config.isProduction || true
+  redis = require 'redis'
+  redisClient = redis.createClient(config.redis.port,config.redis.host)
 
 module.exports.setup = (app) ->
   app.all config.mail.mailchimpWebhook, handleMailchimpWebHook
   app.get '/mail/cron/ladder-update', handleLadderUpdate
+  app.post '/mail/task', createMailTask
+
+  #setInterval(handleScheduledMail, 5000)
   
 
 DEBUGGING = false
@@ -28,6 +34,18 @@ isRequestFromDesignatedCronHandler = (req, res) ->
     return false
   return true
 
+createMailTask = (req, res) ->
+  #unless req.user?.isAdmin() then return errors.forbidden(res)
+  unless req.body.url and req.body.frequency then return errors.badInput(res)
+  console.log "Creating mail task with url #{req.body.url} and frequency #{req.body.frequency}"
+  newMailTask = new MailTask {}
+  newMailTask.set("url",req.body.url)
+  newMailTask.set("frequency",req.body.frequency)
+  newMailTask.save (err) ->
+    if err? then return errors.serverError(res, err)
+    res.send("Created mail task!")
+    res.end()
+  
 handleLadderUpdate = (req, res) ->
   log.info('Going to see about sending ladder update emails.')
   requestIsFromDesignatedCronHandler = isRequestFromDesignatedCronHandler req, res
diff --git a/server_config.coffee b/server_config.coffee
index 6018bf84f..13fc4e7d1 100644
--- a/server_config.coffee
+++ b/server_config.coffee
@@ -12,6 +12,10 @@ config.mongo =
   host: process.env.COCO_MONGO_HOST or 'localhost'
   db: process.env.COCO_MONGO_DATABASE_NAME or 'coco'
   mongoose_replica_string: process.env.COCO_MONGO_MONGOOSE_REPLICA_STRING or ''
+  
+config.redis = 
+  port: process.env.COCO_REDIS_PORT or 6379
+  host: process.env.COCO_REDIS_HOST or 'localhost'
 
 if config.unittest
   config.port += 1

From b74bdfbf51e000af18c5537835a49c898b5030b7 Mon Sep 17 00:00:00 2001
From: Michael Schmatz <michaelschmatz@gmail.com>
Date: Wed, 16 Jul 2014 12:12:11 -0700
Subject: [PATCH 02/58] Added metadata to mail sent schema

---
 app/schemas/models/mail_sent.coffee | 1 +
 1 file changed, 1 insertion(+)

diff --git a/app/schemas/models/mail_sent.coffee b/app/schemas/models/mail_sent.coffee
index 4236ad94b..4cd54e241 100644
--- a/app/schemas/models/mail_sent.coffee
+++ b/app/schemas/models/mail_sent.coffee
@@ -9,6 +9,7 @@ _.extend MailSentSchema.properties,
   mailTask: c.objectId {}
   user: c.objectId links: [{rel: 'extra', href: '/db/user/{($)}'}]
   sent: c.date title: 'Sent', readOnly: true
+  metadata: c.object {}, {}
 
 c.extendBasicProperties MailSentSchema, 'mail.sent'
 

From 3ef5d88e2ac4f07500b0a5cd1e9616c01512d8bf Mon Sep 17 00:00:00 2001
From: Michael Schmatz <michaelschmatz@gmail.com>
Date: Wed, 16 Jul 2014 12:12:25 -0700
Subject: [PATCH 03/58] Updated sendwithus to fix memory leak

---
 package.json | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/package.json b/package.json
index cba6e383e..21231684c 100644
--- a/package.json
+++ b/package.json
@@ -59,7 +59,7 @@
     "express-useragent": "~0.0.9",
     "gridfs-stream": "0.4.x",
     "stream-buffers": "0.2.x",
-    "sendwithus": "2.0.x",
+    "sendwithus": "2.1.x",
     "aws-sdk": "~2.0.0",
     "bayesian-battle": "0.0.x",
     "redis": "",

From 449f1e1afcb0e1a7f6ac4b3386b78822d9c1adf6 Mon Sep 17 00:00:00 2001
From: Michael Schmatz <michaelschmatz@gmail.com>
Date: Wed, 16 Jul 2014 12:12:44 -0700
Subject: [PATCH 04/58] Updated locking/release procedure

---
 server/commons/LockManager.coffee | 20 +++++++++++++-------
 1 file changed, 13 insertions(+), 7 deletions(-)

diff --git a/server/commons/LockManager.coffee b/server/commons/LockManager.coffee
index 83dd43efc..56604381b 100644
--- a/server/commons/LockManager.coffee
+++ b/server/commons/LockManager.coffee
@@ -1,5 +1,6 @@
 config = require '../../server_config'
 redis = require 'redis'
+
 class LockManager
   constructor: ->
     unless config.isProduction or config.redis.host isnt "localhost"
@@ -10,15 +11,20 @@ class LockManager
   
   setLock: (lockName, timeoutMs, cb) =>
     randomNumber = Math.floor(Math.random() * 1000000000)
-    @redisClient.set [lockName,randomNumber, "NX", "PX", timeoutMs], (err, res) ->
+    @redisClient.set [lockName,randomNumber, "NX", "PX", timeoutMs], (err, res) =>
       if err? then return cb err, null
-      @lockValues[lockName] = randomNumber
-      cb null, res
+      if res is "OK"
+        @lockValues[lockName] = randomNumber
+        return cb null, "Lock set!"
+      unless res 
+        return cb "Lock already set!", null
       
   releaseLock: (lockName, cb) =>
     @redisClient.eval [@unlockScript, 1, lockName, @lockValues[lockName]], (err, res) -> 
       if err? then return cb err, null
-      #1 represents success, 0 failure
-      cb null, Boolean(Number(res))
-  
-module.exports = new RedisLock() 
\ No newline at end of file
+      if res
+        cb null, "The lock was released!"
+      else
+        cb "The lock was not released.", null
+
+module.exports = new LockManager() 

From 3a405e22f3ee2efe31f7a4f0b22e7c7bbcdc9de7 Mon Sep 17 00:00:00 2001
From: Michael Schmatz <michaelschmatz@gmail.com>
Date: Wed, 16 Jul 2014 12:12:54 -0700
Subject: [PATCH 05/58] Changed name of mail sent collection

---
 server/mail/sent/MailSent.coffee | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/server/mail/sent/MailSent.coffee b/server/mail/sent/MailSent.coffee
index 7f59dd5b0..f8479033a 100644
--- a/server/mail/sent/MailSent.coffee
+++ b/server/mail/sent/MailSent.coffee
@@ -8,4 +8,4 @@ MailSent = new mongoose.Schema({
     'default': Date.now
 }, {strict: false})
 
-module.exports = MailSent = mongoose.model('mailSent', MailSent)
+module.exports = MailSent = mongoose.model('mail.sent', MailSent)

From e218c2297db205a02cd701d97b37ff738ab347aa Mon Sep 17 00:00:00 2001
From: Michael Schmatz <michaelschmatz@gmail.com>
Date: Wed, 16 Jul 2014 12:13:21 -0700
Subject: [PATCH 06/58] Some emails working

---
 server/routes/mail.coffee | 201 +++++++++++++++++++++++++++++++++++++-
 1 file changed, 196 insertions(+), 5 deletions(-)

diff --git a/server/routes/mail.coffee b/server/routes/mail.coffee
index ae8b62e86..784f4c099 100644
--- a/server/routes/mail.coffee
+++ b/server/routes/mail.coffee
@@ -1,23 +1,213 @@
 mail = require '../commons/mail'
 MailTask = require '../mail/tasks/MailTask'
+MailSent = require '../mail/sent/MailSent'
 User = require '../users/User'
+async = require 'async'
 errors = require '../commons/errors'
 config = require '../../server_config'
 LevelSession = require '../levels/sessions/LevelSession'
 Level = require '../levels/Level'
 log = require 'winston'
 sendwithus = require '../sendwithus'
-if config.isProduction || true
-  redis = require 'redis'
-  redisClient = redis.createClient(config.redis.port,config.redis.host)
+if config.isProduction or config.redis.host isnt "localhost"
+  lockManager = require '../commons/LockManager'
+  
 
 module.exports.setup = (app) ->
   app.all config.mail.mailchimpWebhook, handleMailchimpWebHook
   app.get '/mail/cron/ladder-update', handleLadderUpdate
   app.post '/mail/task', createMailTask
-
-  #setInterval(handleScheduledMail, 5000)
+  if lockManager
+    setupScheduledEmails()
   
+setupScheduledEmails = ->
+  testForLockManager()
+  mailTaskMap = 
+    "test_mail_task": candidateUpdateProfileTask
+    
+  MailTask.find({}).lean().exec (err, mailTasks) ->
+    if err? then throw "Failed to schedule mailTasks! #{err}"
+    for mailTask in mailTasks
+      setInterval mailTaskMap[mailTask.url], mailTask.frequency*2
+      
+testForLockManager = -> unless lockManager then throw "The system isn't configured to do distributed locking!"
+  
+### Candidate Update Reminder Task ###
+emailTimeRange = (timeRange, finalCallback) ->
+  waterfallContext =
+    "timeRange": timeRange
+    "mailTaskName": @mailTaskName
+  async.waterfall [
+    findAllCandidatesWithinTimeRange.bind(waterfallContext)
+    (unfilteredCandidates, cb) -> #now filter the candidates to see if they are eligible
+      async.reject unfilteredCandidates, candidateFilter.bind(waterfallContext), (filtered) -> cb null, filtered
+    (filteredCandidates, cb) -> #Now send emails to the eligible candidates and record.
+      async.each filteredCandidates, sendReminderEmailToCandidate.bind(waterfallContext), cb
+  ], finalCallback
+  
+findAllCandidatesWithinTimeRange = (cb) ->
+  findParameters =
+    "jobProfile.updated":
+      $gt: @timeRange.start
+      $lte: @timeRange.end
+  selection =  "_id email jobProfile.name jobProfile.updated"
+  User.find(findParameters).select(selection).lean().exec cb
+  
+candidateFilter = (candidate, sentEmailFilterCallback) ->
+  findParameters =
+    "user": candidate._id
+    "mailTask": @mailTaskName
+    "metadata.timeRangeName": @timeRange.name
+    "metadata.updated": candidate.jobProfile.updated
+  MailSent.find(findParameters).lean().exec (err, sentMail) ->
+    if err? then return errors.serverError("Error fetching sent mail in email task")
+    sentEmailFilterCallback Boolean(sentMail.length)
+
+findEmployersSignedUpAfterDate = (dateObject, cb) ->
+  countParameters =
+    $or: [{"dateCreated": {$gte: dateObject}},{"signedEmployerAgreement":{$gte: dateObject}}]
+    employerAt: {$exists: true}
+    permissions: "employer"
+  User.count countParameters, cb
+  
+sendReminderEmailToCandidate = (candidate, sendEmailCallback) ->
+  findEmployersSignedUpAfterDate new Date(candidate.jobProfile.updated), (err, employersAfterCount) =>
+    context =
+      email_id: "tem_CtTLsKQufxrxoPMn7upKiL"
+      recipient:
+        address: candidate.email
+        name: candidate.jobProfile.name
+      email_data:
+        profile_updated: candidate.jobProfile.updated #format nicely
+        new_company: employersAfterCount
+    log.info "Sending #{@timeRange.name} update reminder to #{context.recipient.name}(#{context.recipient.address})"
+    newSentMail =
+      mailTask: @mailTaskName
+      user: candidate._id
+      metadata:
+        timeRangeName: @timeRange.name
+        updated: candidate.jobProfile.updated
+    MailSent.create newSentMail, (err) ->
+      if err? then return sendEmailCallback err
+      sendwithus.api.send context, (err, result) ->
+        log.error "Error sending ladder update email: #{err} with result #{result}" if err
+        sendEmailCallback err
+
+generateWeekOffset = (originalDate, numberOfWeeks) ->
+  return (new Date(originalDate.getTime() - numberOfWeeks * 7 * 24 * 60 * 60 * 1000)).toISOString()
+
+candidateUpdateProfileTask = ->
+  mailTaskName = "candidateUpdateProfileTask"
+  lockDurationMs = 6000
+  currentDate = new Date()
+  timeRanges = []
+  for weekPair in [[4, 2,'two weeks'], [8, 4, 'four weeks'], [8, 52, 'eight weeks']]
+    timeRanges.push 
+      start: generateWeekOffset currentDate, weekPair[0]
+      end: generateWeekOffset currentDate, weekPair[1]
+      name: weekPair[2]
+  lockManager.setLock mailTaskName, lockDurationMs, (err, lockResult) ->
+    if err? then return log.error "Error getting a task lock!"
+    async.each timeRanges, emailTimeRange.bind(mailTaskName: mailTaskName), (err) ->
+      if err then return log.error JSON.stringify err else log.info "Sent candidate update reminders!"
+      lockManager.releaseLock mailTaskName, (err, result) -> if err? then return log.error err
+        
+### End Candidate Update Reminder Task ###
+### Internal Candidate Update Reminder Email ###
+
+emailInternalCandidateUpdateReminder = (cb) ->
+  currentTime = new Date()
+  beginningOfUTCDay = new Date()
+  beginningOfUTCDay.setUTCHours(0,0,0,0)
+  asyncContext =
+    "beginningOfUTCDay": beginningOfUTCDay
+    "currentTime": currentTime
+    "mailTaskName": @mailTaskName
+    
+  async.waterfall [
+    findCandidatesWhoUpdatedJobProfileToday.bind(asyncContext)
+    (unfilteredCandidates, cb) ->
+      async.reject unfilteredCandidates, candidatesUpdatedTodayFilter.bind(asyncContext), cb.bind(null,null)
+    (filteredCandidates, cb) ->
+      async.each filteredCandidates, sendInternalCandidateUpdateReminder.bind(asyncContext), cb
+  ], cb
+    
+findCandidatesWhoUpdatedJobProfileToday = (cb) ->
+  findParameters = 
+    "jobProfile.updated":
+      $lte: @currentTime.toISOString()
+      gt: @beginningOfUTCDay.toISOString()
+  User.find(findParameters).select("_id jobProfile.name jobProfile.updated").lean().exec cb
+  
+candidatesUpdatedTodayFilter = (candidate, cb) ->
+  findParameters =
+    "user": candidate._id
+    "mailTask": @mailTaskName
+    "metadata.beginningOfUTCDay": @beginningOfUTCDay
+  MailSent.find(findParameters).lean().exec (err, sentMail) ->
+    if err? then return errors.serverError("Error fetching sent mail in #{@mailTaskName}")
+    cb Boolean(sentMail.length)
+    
+sendInternalCandidateUpdateReminder = (candidate, cb) ->
+  context =
+    email_id: "tem_Ac7nhgKqatTHBCgDgjF5pE"
+    recipient:
+      address: "team@codecombat.com" #Change to whatever email address is necessary
+      name: "The CodeCombat Team"
+  log.info "Sending candidate updated reminder for #{candidate.jobProfile.name}"
+  
+  newSentMail =
+    mailTask: @mailTaskName
+    user: candidate._id
+    metadata:
+      beginningOfUTCDay: @beginningOfUTCDay
+    
+  MailSent.create newSentMail, (err) ->
+    if err? then return cb err
+    sendwithus.api.send context, (err, result) ->
+      log.error "Error sending ladder update email: #{err} with result #{result}" if err
+      cb err
+  
+internalCandidateUpdateTask = ->
+  mailTaskName = "internalCandidateUpdateTask"
+  lockDurationMs = 6000
+  lockManager.setLock mailTaskName, lockDurationMs, (err, lockResult) ->
+    if err? then return log.error "Error getting a task lock!"
+    emailInternalCandidateUpdateReminder.apply {"mailTaskName":mailTaskName}, (err) ->
+      if err? then return log.error "There was an error sending the internal candidate update reminder."
+      lockManager.releaseLock mailTaskName, (err, result) -> if err? then return log.error err
+### End Internal Candidate Update Reminder Email ###
+  
+### Employer New Candidates Available Email ###
+employerNewCandidatesAvailableTask = ->
+  #  tem_CCcHKr95Nvu5bT7c7iHCtm
+  #initialize featuredDate to job profile updated
+  mailTaskName = "employerNewCandidatesAvailableTask"
+  lockDurationMs = 6000
+  lockManager.setLock mailTaskName, lockDurationMs, (err, lockResult) ->
+
+### End Employer New Candidates Available Email ###
+  
+### New Recruit Leaderboard Email ###
+newRecruitLeaderboardEmailTask = ->
+  # tem_kMQFCKX3v4DNAQDsMAsPJC
+  #maxRank and maxRankTime should be recorded if isSimulating is false
+  mailTaskName = "newRecruitLeaderboardEmailTask"
+  lockDurationMs = 6000
+  lockManager.setLock mailTaskName, lockDurationMs, (err, lockResult) ->
+
+### End New Recruit Leaderboard Email ###
+  
+### Employer Matching Candidate Notification Email ### 
+employerMatchingCandidateNotificationTask = ->
+  # tem_mYsepTfWQ265noKfZJcbBH
+  #save email filters in their own collection
+  mailTaskName = "employerMatchingCandidateNotificationTask"
+  lockDurationMs = 6000
+  lockManager.setLock mailTaskName, lockDurationMs, (err, lockResult) ->
+
+### End Employer Matching Candidate Notification Email ###
+### Ladder Update Email ###
 
 DEBUGGING = false
 LADDER_PREGAME_INTERVAL = 2 * 3600 * 1000  # Send emails two hours before players last submitted.
@@ -169,6 +359,7 @@ getScoreHistoryGraphURL = (session, daysAgo) ->
   chartData = times.join(',') + '|' + scores.join(',')
   "https://chart.googleapis.com/chart?chs=600x75&cht=lxy&chtt=Score%3A+#{currentScore}&chts=222222,12,r&chf=a,s,000000FF&chls=2&chd=t:#{chartData}&chxt=y&chxr=0,#{minScore},#{maxScore}"
 
+### End Ladder Update Email ###
 handleMailchimpWebHook = (req, res) ->
   post = req.body
 

From 67f2eeb584eda3232d74432b5639cf0512c8a820 Mon Sep 17 00:00:00 2001
From: Michael Schmatz <michaelschmatz@gmail.com>
Date: Wed, 16 Jul 2014 13:14:09 -0700
Subject: [PATCH 07/58] Progress on employer new candidates available email

---
 server/routes/mail.coffee | 64 ++++++++++++++++++++++++++++++++++++---
 1 file changed, 59 insertions(+), 5 deletions(-)

diff --git a/server/routes/mail.coffee b/server/routes/mail.coffee
index 784f4c099..dd09a5d02 100644
--- a/server/routes/mail.coffee
+++ b/server/routes/mail.coffee
@@ -23,7 +23,7 @@ module.exports.setup = (app) ->
 setupScheduledEmails = ->
   testForLockManager()
   mailTaskMap = 
-    "test_mail_task": candidateUpdateProfileTask
+    "test_mail_task": employerNewCandidatesAvailableTask
     
   MailTask.find({}).lean().exec (err, mailTasks) ->
     if err? then throw "Failed to schedule mailTasks! #{err}"
@@ -50,6 +50,7 @@ findAllCandidatesWithinTimeRange = (cb) ->
     "jobProfile.updated":
       $gt: @timeRange.start
       $lte: @timeRange.end
+    "jobProfileApproved": true
   selection =  "_id email jobProfile.name jobProfile.updated"
   User.find(findParameters).select(selection).lean().exec cb
   
@@ -109,7 +110,7 @@ candidateUpdateProfileTask = ->
   lockManager.setLock mailTaskName, lockDurationMs, (err, lockResult) ->
     if err? then return log.error "Error getting a task lock!"
     async.each timeRanges, emailTimeRange.bind(mailTaskName: mailTaskName), (err) ->
-      if err then return log.error JSON.stringify err else log.info "Sent candidate update reminders!"
+      if err then log.error JSON.stringify err else log.info "Sent candidate update reminders!"
       lockManager.releaseLock mailTaskName, (err, result) -> if err? then return log.error err
         
 ### End Candidate Update Reminder Task ###
@@ -125,18 +126,19 @@ emailInternalCandidateUpdateReminder = (cb) ->
     "mailTaskName": @mailTaskName
     
   async.waterfall [
-    findCandidatesWhoUpdatedJobProfileToday.bind(asyncContext)
+    findNonApprovedCandidatesWhoUpdatedJobProfileToday.bind(asyncContext)
     (unfilteredCandidates, cb) ->
       async.reject unfilteredCandidates, candidatesUpdatedTodayFilter.bind(asyncContext), cb.bind(null,null)
     (filteredCandidates, cb) ->
       async.each filteredCandidates, sendInternalCandidateUpdateReminder.bind(asyncContext), cb
   ], cb
     
-findCandidatesWhoUpdatedJobProfileToday = (cb) ->
+findNonApprovedCandidatesWhoUpdatedJobProfileToday = (cb) ->
   findParameters = 
     "jobProfile.updated":
       $lte: @currentTime.toISOString()
       gt: @beginningOfUTCDay.toISOString()
+    "jobProfileApproved": false
   User.find(findParameters).select("_id jobProfile.name jobProfile.updated").lean().exec cb
   
 candidatesUpdatedTodayFilter = (candidate, cb) ->
@@ -174,17 +176,69 @@ internalCandidateUpdateTask = ->
   lockManager.setLock mailTaskName, lockDurationMs, (err, lockResult) ->
     if err? then return log.error "Error getting a task lock!"
     emailInternalCandidateUpdateReminder.apply {"mailTaskName":mailTaskName}, (err) ->
-      if err? then return log.error "There was an error sending the internal candidate update reminder."
+      if err? then log.error "There was an error sending the internal candidate update reminder."
       lockManager.releaseLock mailTaskName, (err, result) -> if err? then return log.error err
 ### End Internal Candidate Update Reminder Email ###
   
 ### Employer New Candidates Available Email ###
+
+emailEmployerNewCandidatesAvailableEmail = (cb) ->
+  currentTime = new Date()
+  asyncContext = 
+    "currentTime": currentTime
+    "mailTaskName": @mailTaskName
+    
+  async.waterfall [
+    findAllEmployers
+    makeEmployerNamesEasilyAccessible
+    (allEmployers, cb) ->
+      console.log "Found #{allEmployers.length} employers to email about new candidates available"
+      async.reject allEmployers, employersEmailedDigestMoreThanWeekAgoFilter.bind(asyncContext), cb.bind(null,null)
+    (employersToEmail, cb) ->
+      async.each employersToEmail, sendEmployerNewCandidatesAvailableEmail.bind(asyncContext), cb
+  ], cb
+      
+findAllEmployers = (cb) ->
+  findParameters = 
+    "employerAt":
+      $exists: true
+    permissions: "employer"
+  User.find(findParameters).select("_id email employerAt signedEmployerAgreement.data.firstName signedEmployerAgreement.data.lastName").lean().exec cb
+  
+makeEmployerNamesEasilyAccessible = (allEmployers, cb) ->
+  #Make names easily accessible
+  for employer, index in allEmployers
+    if employer.signedEmployerAgreement?.data?.firstName
+      employer.name = employer.signedEmployerAgreement.data.firstName + " " + employer.signedEmployerAgreement.data.lastName
+      delete employer.signedEmployerAgreement
+    allEmployers[index] = employer
+  cb null, allEmployers
+  
+employersEmailedDigestMoreThanWeekAgoFilter = (employer, cb) ->
+  findParameters = 
+    "user": employer._id
+    "mailTask": @mailTaskName
+    "sent":
+      $lte: new Date(@currentTime.getTime() - 7 * 24 * 60 * 60 * 1000) 
+  MailSent.find(findParameters).lean().exec (err, sentMail) ->
+    if err? then return errors.serverError("Error fetching sent mail in #{@mailTaskName}")
+    cb Boolean(sentMail.length)
+
+sendEmployerNewCandidatesAvailableEmail = (employer, cb) ->
+  cb null
+  
+
 employerNewCandidatesAvailableTask = ->
   #  tem_CCcHKr95Nvu5bT7c7iHCtm
   #initialize featuredDate to job profile updated
   mailTaskName = "employerNewCandidatesAvailableTask"
   lockDurationMs = 6000
   lockManager.setLock mailTaskName, lockDurationMs, (err, lockResult) ->
+    if err? then return log.error "There was an error getting a task lock!"
+    emailEmployerNewCandidatesAvailableEmail.apply {"mailTaskName":mailTaskName}, (err) ->
+      if err? then return log.error "There was an error performing the #{mailTaskName} email task."
+      lockManager.releaseLock mailTaskName, (err, result) -> if err? then return log.error err
+
 
 ### End Employer New Candidates Available Email ###
   

From 3c257a488df971e0ad1e3b6d7167984e838a0be7 Mon Sep 17 00:00:00 2001
From: Michael Schmatz <michaelschmatz@gmail.com>
Date: Wed, 16 Jul 2014 13:54:05 -0700
Subject: [PATCH 08/58] Employer candidates available email completed

---
 server/routes/mail.coffee | 43 ++++++++++++++++++++++++++++++++++-----
 1 file changed, 38 insertions(+), 5 deletions(-)

diff --git a/server/routes/mail.coffee b/server/routes/mail.coffee
index dd09a5d02..ee1728f1f 100644
--- a/server/routes/mail.coffee
+++ b/server/routes/mail.coffee
@@ -203,7 +203,8 @@ findAllEmployers = (cb) ->
     "employerAt":
       $exists: true
     permissions: "employer"
-  User.find(findParameters).select("_id email employerAt signedEmployerAgreement.data.firstName signedEmployerAgreement.data.lastName").lean().exec cb
+  selection = "_id email employerAt signedEmployerAgreement.data.firstName signedEmployerAgreement.data.lastName activity dateCreated"
+  User.find(findParameters).select(selection).lean().exec cb
   
 makeEmployerNamesEasilyAccessible = (allEmployers, cb) ->
   #Make names easily accessible
@@ -219,17 +220,49 @@ employersEmailedDigestMoreThanWeekAgoFilter = (employer, cb) ->
     "user": employer._id
     "mailTask": @mailTaskName
     "sent":
-      $lte: new Date(@currentTime.getTime() - 7 * 24 * 60 * 60 * 1000) 
+      $gt: new Date(@currentTime.getTime() - 7 * 24 * 60 * 60 * 1000) 
   MailSent.find(findParameters).lean().exec (err, sentMail) ->
     if err? then return errors.serverError("Error fetching sent mail in #{@mailTaskName}")
     cb Boolean(sentMail.length)
 
 sendEmployerNewCandidatesAvailableEmail = (employer, cb) ->
-  cb null
-  
+  lastLoginDate = employer.activity?.login?.last ? employer.dateCreated
+  countParameters =
+    "jobProfileApproved": true
+    "jobProfile": 
+      $exists: true
+    $or: [
+        jobProfileApprovedDate: 
+          $gt: lastLoginDate.toISOString()
+      ,
+        jobProfileApprovedDate:
+          $exists: false
+        "jobProfile.updated":
+          $gt: lastLoginDate.toISOString()   
+    ]
+  User.count countParameters, (err, numberOfCandidatesSinceLogin) =>
+    if err? then return cb err
+    context =
+      email_id: "tem_CCcHKr95Nvu5bT7c7iHCtm"
+      recipient:
+        address: employer.email
+        name: employer.name
+      email_data:
+        new_candidates: numberOfCandidatesSinceLogin
+        employer_company_name: employer.employerAt
+        company_name: "CodeCombat"
+    
+    log.info "Sending available candidates update reminder to #{context.recipient.name}(#{context.recipient.address})"
+    newSentMail =
+      mailTask: @mailTaskName
+      user: employer._id
+    MailSent.create newSentMail, (err) ->
+      if err? then return cb err
+      sendwithus.api.send context, (err, result) ->
+        log.error "Error sending ladder update email: #{err} with result #{result}" if err
+        cb err
 
 employerNewCandidatesAvailableTask = ->
-  #  tem_CCcHKr95Nvu5bT7c7iHCtm
   #initialize featuredDate to job profile updated
   mailTaskName = "employerNewCandidatesAvailableTask"
   lockDurationMs = 6000

From 5c0c25ebd1235c9a225862496b40a031c966d21d Mon Sep 17 00:00:00 2001
From: Michael Schmatz <michaelschmatz@gmail.com>
Date: Wed, 16 Jul 2014 13:56:23 -0700
Subject: [PATCH 09/58] Async must not break upon sendwithus failure

---
 server/routes/mail.coffee | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/server/routes/mail.coffee b/server/routes/mail.coffee
index ee1728f1f..8983a7224 100644
--- a/server/routes/mail.coffee
+++ b/server/routes/mail.coffee
@@ -91,8 +91,8 @@ sendReminderEmailToCandidate = (candidate, sendEmailCallback) ->
     MailSent.create newSentMail, (err) ->
       if err? then return sendEmailCallback err
       sendwithus.api.send context, (err, result) ->
-        log.error "Error sending ladder update email: #{err} with result #{result}" if err
-        sendEmailCallback err
+        log.error "Error sending candidate update reminder email: #{err} with result #{result}" if err
+        sendEmailCallback null
 
 generateWeekOffset = (originalDate, numberOfWeeks) ->
   return (new Date(originalDate.getTime() - numberOfWeeks * 7 * 24 * 60 * 60 * 1000)).toISOString()
@@ -167,8 +167,8 @@ sendInternalCandidateUpdateReminder = (candidate, cb) ->
   MailSent.create newSentMail, (err) ->
     if err? then return cb err
     sendwithus.api.send context, (err, result) ->
-      log.error "Error sending ladder update email: #{err} with result #{result}" if err
-      cb err
+      log.error "Error sending interal candidate update email: #{err} with result #{result}" if err
+      cb null
   
 internalCandidateUpdateTask = ->
   mailTaskName = "internalCandidateUpdateTask"
@@ -259,8 +259,8 @@ sendEmployerNewCandidatesAvailableEmail = (employer, cb) ->
     MailSent.create newSentMail, (err) ->
       if err? then return cb err
       sendwithus.api.send context, (err, result) ->
-        log.error "Error sending ladder update email: #{err} with result #{result}" if err
-        cb err
+        log.error "Error sending employer candidates available email: #{err} with result #{result}" if err
+        cb null
 
 employerNewCandidatesAvailableTask = ->
   #initialize featuredDate to job profile updated

From 59a35c844fd0e04de3a9c75d9ea8dd53d7adc69a Mon Sep 17 00:00:00 2001
From: Michael Schmatz <michaelschmatz@gmail.com>
Date: Wed, 16 Jul 2014 14:29:30 -0700
Subject: [PATCH 10/58] Made mail system resilient to redis failures

---
 server/commons/LockManager.coffee | 12 ++++++++++++
 server/routes/mail.coffee         |  8 +++++---
 2 files changed, 17 insertions(+), 3 deletions(-)

diff --git a/server/commons/LockManager.coffee b/server/commons/LockManager.coffee
index 56604381b..bdd847bf7 100644
--- a/server/commons/LockManager.coffee
+++ b/server/commons/LockManager.coffee
@@ -1,15 +1,26 @@
 config = require '../../server_config'
 redis = require 'redis'
+log = require 'winston'
 
 class LockManager
   constructor: ->
     unless config.isProduction or config.redis.host isnt "localhost"
       throw "You shouldn't be instantiating distributed locks unless in production."
     @redisClient = redis.createClient config.redis.port, config.redis.host
+    @redisClient.on "ready", =>
+      log.info "Redis ready!"
+      @redisNotAvailable = false
+    @redisClient.on "error", (err) =>
+      @redisNotAvailable = true
+      log.error "Redis connection error! Err: #{err}"
+    @redisClient.on "end", =>
+      @redisNotAvailable = true
+      log.error "Redis connection ended!"
     @lockValues = {}
     @unlockScript = "if redis.call(\"get\",KEYS[1]) == ARGV[1] then return redis.call(\"del\",KEYS[1]) else return 0 end"
   
   setLock: (lockName, timeoutMs, cb) =>
+    if @redisNotAvailable is true then return cb "Redis not available!"
     randomNumber = Math.floor(Math.random() * 1000000000)
     @redisClient.set [lockName,randomNumber, "NX", "PX", timeoutMs], (err, res) =>
       if err? then return cb err, null
@@ -20,6 +31,7 @@ class LockManager
         return cb "Lock already set!", null
       
   releaseLock: (lockName, cb) =>
+    if @redisNotAvailable is true then return cb "Redis not available!"
     @redisClient.eval [@unlockScript, 1, lockName, @lockValues[lockName]], (err, res) -> 
       if err? then return cb err, null
       if res
diff --git a/server/routes/mail.coffee b/server/routes/mail.coffee
index 8983a7224..0e34e06db 100644
--- a/server/routes/mail.coffee
+++ b/server/routes/mail.coffee
@@ -274,25 +274,27 @@ employerNewCandidatesAvailableTask = ->
 
 
 ### End Employer New Candidates Available Email ###
-  
+
 ### New Recruit Leaderboard Email ###
+###
 newRecruitLeaderboardEmailTask = ->
   # tem_kMQFCKX3v4DNAQDsMAsPJC
   #maxRank and maxRankTime should be recorded if isSimulating is false
   mailTaskName = "newRecruitLeaderboardEmailTask"
   lockDurationMs = 6000
   lockManager.setLock mailTaskName, lockDurationMs, (err, lockResult) ->
-
+###
 ### End New Recruit Leaderboard Email ###
   
 ### Employer Matching Candidate Notification Email ### 
+###
 employerMatchingCandidateNotificationTask = ->
   # tem_mYsepTfWQ265noKfZJcbBH
   #save email filters in their own collection
   mailTaskName = "employerMatchingCandidateNotificationTask"
   lockDurationMs = 6000
   lockManager.setLock mailTaskName, lockDurationMs, (err, lockResult) ->
-
+###
 ### End Employer Matching Candidate Notification Email ###
 ### Ladder Update Email ###
 

From 24bcfd9f26b336a3ee98302e3b0ef12345f8fe63 Mon Sep 17 00:00:00 2001
From: Michael Schmatz <michaelschmatz@gmail.com>
Date: Wed, 16 Jul 2014 15:50:31 -0700
Subject: [PATCH 11/58] Reviewed code, almost ready for release

---
 server/routes/mail.coffee | 196 +++++++++++++++++++++-----------------
 1 file changed, 107 insertions(+), 89 deletions(-)

diff --git a/server/routes/mail.coffee b/server/routes/mail.coffee
index 0e34e06db..6939d8080 100644
--- a/server/routes/mail.coffee
+++ b/server/routes/mail.coffee
@@ -9,9 +9,20 @@ LevelSession = require '../levels/sessions/LevelSession'
 Level = require '../levels/Level'
 log = require 'winston'
 sendwithus = require '../sendwithus'
-if config.isProduction or config.redis.host isnt "localhost"
+if config.isProduction or config.redis.host isnt "localhost" #TODO: Ask Nick and Scott to change their environment variables and change the deploy ones
   lockManager = require '../commons/LockManager'
-  
+#TODO: Ask Nick about email unsubscriptions
+createMailTask = (req, res) -> #TODO: Ask Nick whether he thinks it is a good idea or not to hardcode the mail tasks
+  unless req.user?.isAdmin() then return errors.forbidden(res)
+  unless req.body.url and req.body.frequency then return errors.badInput(res)
+  console.log "Creating mail task with url #{req.body.url} and frequency #{req.body.frequency}"
+  newMailTask = new MailTask {}
+  newMailTask.set("url",req.body.url)
+  newMailTask.set("frequency",req.body.frequency)
+  newMailTask.save (err) ->
+    if err? then return errors.serverError(res, err)
+    res.send("Created mail task!")
+    res.end()
 
 module.exports.setup = (app) ->
   app.all config.mail.mailchimpWebhook, handleMailchimpWebHook
@@ -22,28 +33,52 @@ module.exports.setup = (app) ->
   
 setupScheduledEmails = ->
   testForLockManager()
-  mailTaskMap = 
-    "test_mail_task": employerNewCandidatesAvailableTask
+  mailTaskMap = #TODO: Edit this to include additional emails
+    "test_mail_task": candidateUpdateProfileTask
     
-  MailTask.find({}).lean().exec (err, mailTasks) ->
+  MailTask.find({}).lean().exec (err, mailTasks) -> #TODO: Ask Nick whether or not to remove this
     if err? then throw "Failed to schedule mailTasks! #{err}"
     for mailTask in mailTasks
-      setInterval mailTaskMap[mailTask.url], mailTask.frequency*2
+      setInterval mailTaskMap[mailTask.url], mailTask.frequency*2 #TODO: Have some random offset to prevent lock contention
       
 testForLockManager = -> unless lockManager then throw "The system isn't configured to do distributed locking!"
   
 ### Candidate Update Reminder Task ###
-emailTimeRange = (timeRange, finalCallback) ->
+
+candidateUpdateProfileTask = ->
+  mailTaskName = "candidateUpdateProfileTask"
+  lockDurationMs = 20000 #TODO: Change these to something appropriate for the mail frequency (ideally longer than the task but shorter than frequency)
+  currentDate = new Date()
+  timeRanges = []
+  for weekPair in [[4, 2,'two weeks'], [8, 4, 'four weeks'], [8, 52, 'eight weeks']]
+    timeRanges.push
+      start: generateWeekOffset currentDate, weekPair[0]
+      end: generateWeekOffset currentDate, weekPair[1]
+      name: weekPair[2]
+  lockManager.setLock mailTaskName, lockDurationMs, (err) ->
+    if err? then return log.error "Error getting a distributed lock for task #{mailTaskName}!"
+    async.each timeRanges, emailTimeRange.bind({mailTaskName: mailTaskName}), (err) ->
+      if err
+        log.error "There was an error sending the candidate profile update reminder emails: #{err}"
+      else
+        log.info "Completed mail task #{mailTaskName}"
+      lockManager.releaseLock mailTaskName, (err) ->
+        if err? then return log.error "There was an error releasing the distributed lock for task #{mailTaskName}: #{err}"
+
+generateWeekOffset = (originalDate, numberOfWeeks) ->
+  return (new Date(originalDate.getTime() - numberOfWeeks * 7 * 24 * 60 * 60 * 1000)).toISOString()
+
+emailTimeRange = (timeRange, emailTimeRangeCallback) ->
   waterfallContext =
     "timeRange": timeRange
     "mailTaskName": @mailTaskName
   async.waterfall [
     findAllCandidatesWithinTimeRange.bind(waterfallContext)
-    (unfilteredCandidates, cb) -> #now filter the candidates to see if they are eligible
-      async.reject unfilteredCandidates, candidateFilter.bind(waterfallContext), (filtered) -> cb null, filtered
-    (filteredCandidates, cb) -> #Now send emails to the eligible candidates and record.
+    (unfilteredCandidates, cb) -> 
+      async.reject unfilteredCandidates, candidateFilter.bind(waterfallContext), cb.bind(null, null)
+    (filteredCandidates, cb) ->
       async.each filteredCandidates, sendReminderEmailToCandidate.bind(waterfallContext), cb
-  ], finalCallback
+  ], emailTimeRangeCallback
   
 findAllCandidatesWithinTimeRange = (cb) ->
   findParameters =
@@ -61,8 +96,11 @@ candidateFilter = (candidate, sentEmailFilterCallback) ->
     "metadata.timeRangeName": @timeRange.name
     "metadata.updated": candidate.jobProfile.updated
   MailSent.find(findParameters).lean().exec (err, sentMail) ->
-    if err? then return errors.serverError("Error fetching sent mail in email task")
-    sentEmailFilterCallback Boolean(sentMail.length)
+    if err?
+      log.error "Error finding mail sent for task #{@mailTaskName} and user #{candidate._id}!"
+      sentEmailFilterCallback true
+    else
+      sentEmailFilterCallback Boolean(sentMail.length)
 
 findEmployersSignedUpAfterDate = (dateObject, cb) ->
   countParameters =
@@ -73,14 +111,18 @@ findEmployersSignedUpAfterDate = (dateObject, cb) ->
   
 sendReminderEmailToCandidate = (candidate, sendEmailCallback) ->
   findEmployersSignedUpAfterDate new Date(candidate.jobProfile.updated), (err, employersAfterCount) =>
+    if err?
+      log.error "There was an error finding employers who signed up after #{candidate.jobProfile.updated}: #{err}"
+      return sendEmailCallback err
     context =
       email_id: "tem_CtTLsKQufxrxoPMn7upKiL"
       recipient:
         address: candidate.email
         name: candidate.jobProfile.name
       email_data:
-        profile_updated: candidate.jobProfile.updated #format nicely
         new_company: employersAfterCount
+        company_name: "CodeCombat"
+        user_profile: "http://codecombat.com/account/profile/#{candidate._id}"
     log.info "Sending #{@timeRange.name} update reminder to #{context.recipient.name}(#{context.recipient.address})"
     newSentMail =
       mailTask: @mailTaskName
@@ -93,30 +135,22 @@ sendReminderEmailToCandidate = (candidate, sendEmailCallback) ->
       sendwithus.api.send context, (err, result) ->
         log.error "Error sending candidate update reminder email: #{err} with result #{result}" if err
         sendEmailCallback null
-
-generateWeekOffset = (originalDate, numberOfWeeks) ->
-  return (new Date(originalDate.getTime() - numberOfWeeks * 7 * 24 * 60 * 60 * 1000)).toISOString()
-
-candidateUpdateProfileTask = ->
-  mailTaskName = "candidateUpdateProfileTask"
-  lockDurationMs = 6000
-  currentDate = new Date()
-  timeRanges = []
-  for weekPair in [[4, 2,'two weeks'], [8, 4, 'four weeks'], [8, 52, 'eight weeks']]
-    timeRanges.push 
-      start: generateWeekOffset currentDate, weekPair[0]
-      end: generateWeekOffset currentDate, weekPair[1]
-      name: weekPair[2]
-  lockManager.setLock mailTaskName, lockDurationMs, (err, lockResult) ->
-    if err? then return log.error "Error getting a task lock!"
-    async.each timeRanges, emailTimeRange.bind(mailTaskName: mailTaskName), (err) ->
-      if err then log.error JSON.stringify err else log.info "Sent candidate update reminders!"
-      lockManager.releaseLock mailTaskName, (err, result) -> if err? then return log.error err
-        
 ### End Candidate Update Reminder Task ###
 ### Internal Candidate Update Reminder Email ###
+internalCandidateUpdateTask = ->
+  mailTaskName = "internalCandidateUpdateTask"
+  lockDurationMs = 6000 #TODO: Change lock duration
+  lockManager.setLock mailTaskName, lockDurationMs, (err) ->
+    if err? then return log.error "Error getting a distributed lock for task #{mailTaskName}!"
+    emailInternalCandidateUpdateReminder.apply {"mailTaskName":mailTaskName}, (err) ->
+      if err
+        log.error "There was an error sending the internal candidate update reminder.: #{err}"
+      else
+        log.info "Sent internal candidate update reminder email!"
+      lockManager.releaseLock mailTaskName, (err) ->
+        if err? then return log.error "There was an error releasing the distributed lock for task #{mailTaskName}: #{err}"
 
-emailInternalCandidateUpdateReminder = (cb) ->
+emailInternalCandidateUpdateReminder = (internalCandidateUpdateReminderCallback) ->
   currentTime = new Date()
   beginningOfUTCDay = new Date()
   beginningOfUTCDay.setUTCHours(0,0,0,0)
@@ -124,40 +158,43 @@ emailInternalCandidateUpdateReminder = (cb) ->
     "beginningOfUTCDay": beginningOfUTCDay
     "currentTime": currentTime
     "mailTaskName": @mailTaskName
-    
   async.waterfall [
     findNonApprovedCandidatesWhoUpdatedJobProfileToday.bind(asyncContext)
     (unfilteredCandidates, cb) ->
       async.reject unfilteredCandidates, candidatesUpdatedTodayFilter.bind(asyncContext), cb.bind(null,null)
     (filteredCandidates, cb) ->
       async.each filteredCandidates, sendInternalCandidateUpdateReminder.bind(asyncContext), cb
-  ], cb
+  ], internalCandidateUpdateReminderCallback
     
 findNonApprovedCandidatesWhoUpdatedJobProfileToday = (cb) ->
   findParameters = 
     "jobProfile.updated":
       $lte: @currentTime.toISOString()
       gt: @beginningOfUTCDay.toISOString()
-    "jobProfileApproved": false
+    "jobProfileApproved": false 
   User.find(findParameters).select("_id jobProfile.name jobProfile.updated").lean().exec cb
   
 candidatesUpdatedTodayFilter = (candidate, cb) ->
   findParameters =
     "user": candidate._id
     "mailTask": @mailTaskName
-    "metadata.beginningOfUTCDay": @beginningOfUTCDay
+    "metadata.beginningOfUTCDay": @beginningOfUTCDay 
   MailSent.find(findParameters).lean().exec (err, sentMail) ->
-    if err? then return errors.serverError("Error fetching sent mail in #{@mailTaskName}")
-    cb Boolean(sentMail.length)
+    if err?
+      log.error "Error finding mail sent for task #{@mailTaskName} and user #{candidate._id}!"
+      cb true
+    else
+      cb Boolean(sentMail.length)
     
 sendInternalCandidateUpdateReminder = (candidate, cb) ->
   context =
     email_id: "tem_Ac7nhgKqatTHBCgDgjF5pE"
-    recipient:
+    recipient: 
       address: "team@codecombat.com" #Change to whatever email address is necessary
       name: "The CodeCombat Team"
+    email_data:
+      new_candidate_profile: "https://codecombat.com/account/profile/#{candidate._id}"
   log.info "Sending candidate updated reminder for #{candidate.jobProfile.name}"
-  
   newSentMail =
     mailTask: @mailTaskName
     user: candidate._id
@@ -169,20 +206,23 @@ sendInternalCandidateUpdateReminder = (candidate, cb) ->
     sendwithus.api.send context, (err, result) ->
       log.error "Error sending interal candidate update email: #{err} with result #{result}" if err
       cb null
-  
-internalCandidateUpdateTask = ->
-  mailTaskName = "internalCandidateUpdateTask"
-  lockDurationMs = 6000
-  lockManager.setLock mailTaskName, lockDurationMs, (err, lockResult) ->
-    if err? then return log.error "Error getting a task lock!"
-    emailInternalCandidateUpdateReminder.apply {"mailTaskName":mailTaskName}, (err) ->
-      if err? then log.error "There was an error sending the internal candidate update reminder."
-      lockManager.releaseLock mailTaskName, (err, result) -> if err? then return log.error err
-### End Internal Candidate Update Reminder Email ###
-  
-### Employer New Candidates Available Email ###
 
-emailEmployerNewCandidatesAvailableEmail = (cb) ->
+### End Internal Candidate Update Reminder Email ###
+### Employer New Candidates Available Email ###
+employerNewCandidatesAvailableTask = ->
+  mailTaskName = "employerNewCandidatesAvailableTask"
+  lockDurationMs = 6000 #TODO: Update this lock duration
+  lockManager.setLock mailTaskName, lockDurationMs, (err) ->
+    if err? then return log.error "There was an error getting a task lock!"
+    emailEmployerNewCandidatesAvailable.apply {"mailTaskName":mailTaskName}, (err) ->
+      if err
+        log.error "There was an error completing the new candidates available task: #{err}"
+      else
+        log.info "Completed the employer new candidates available task!"
+      lockManager.releaseLock mailTaskName, (err) ->
+        if err? then return log.error "There was an error releasing the distributed lock for task #{mailTaskName}: #{err}"
+
+emailEmployerNewCandidatesAvailable = (emailEmployerNewCandidatesAvailableCallback) ->
   currentTime = new Date()
   asyncContext = 
     "currentTime": currentTime
@@ -192,22 +232,20 @@ emailEmployerNewCandidatesAvailableEmail = (cb) ->
     findAllEmployers
     makeEmployerNamesEasilyAccessible
     (allEmployers, cb) ->
-      console.log "Found #{allEmployers.length} employers to email about new candidates available"
       async.reject allEmployers, employersEmailedDigestMoreThanWeekAgoFilter.bind(asyncContext), cb.bind(null,null)
     (employersToEmail, cb) ->
       async.each employersToEmail, sendEmployerNewCandidatesAvailableEmail.bind(asyncContext), cb
-  ], cb
+  ], emailEmployerNewCandidatesAvailableCallback
       
 findAllEmployers = (cb) ->
   findParameters = 
     "employerAt":
-      $exists: true
+      $exists: true 
     permissions: "employer"
   selection = "_id email employerAt signedEmployerAgreement.data.firstName signedEmployerAgreement.data.lastName activity dateCreated"
   User.find(findParameters).select(selection).lean().exec cb
   
 makeEmployerNamesEasilyAccessible = (allEmployers, cb) ->
-  #Make names easily accessible
   for employer, index in allEmployers
     if employer.signedEmployerAgreement?.data?.firstName
       employer.name = employer.signedEmployerAgreement.data.firstName + " " + employer.signedEmployerAgreement.data.lastName
@@ -222,15 +260,16 @@ employersEmailedDigestMoreThanWeekAgoFilter = (employer, cb) ->
     "sent":
       $gt: new Date(@currentTime.getTime() - 7 * 24 * 60 * 60 * 1000) 
   MailSent.find(findParameters).lean().exec (err, sentMail) ->
-    if err? then return errors.serverError("Error fetching sent mail in #{@mailTaskName}")
-    cb Boolean(sentMail.length)
+    if err?
+      log.error "Error finding mail sent for task #{@mailTaskName} and employer #employer._id}!"
+      cb true
+    else
+      cb Boolean(sentMail.length)
 
 sendEmployerNewCandidatesAvailableEmail = (employer, cb) ->
-  lastLoginDate = employer.activity?.login?.last ? employer.dateCreated
+  lastLoginDate = employer.activity?.login?.last ? employer.dateCreated 
   countParameters =
     "jobProfileApproved": true
-    "jobProfile": 
-      $exists: true
     $or: [
         jobProfileApprovedDate: 
           $gt: lastLoginDate.toISOString()
@@ -246,12 +285,12 @@ sendEmployerNewCandidatesAvailableEmail = (employer, cb) ->
       email_id: "tem_CCcHKr95Nvu5bT7c7iHCtm"
       recipient:
         address: employer.email
-        name: employer.name
       email_data:
         new_candidates: numberOfCandidatesSinceLogin
         employer_company_name: employer.employerAt
         company_name: "CodeCombat"
-    
+    if employer.name
+      context.recipient.name = employer.name
     log.info "Sending available candidates update reminder to #{context.recipient.name}(#{context.recipient.address})"
     newSentMail =
       mailTask: @mailTaskName
@@ -262,17 +301,6 @@ sendEmployerNewCandidatesAvailableEmail = (employer, cb) ->
         log.error "Error sending employer candidates available email: #{err} with result #{result}" if err
         cb null
 
-employerNewCandidatesAvailableTask = ->
-  #initialize featuredDate to job profile updated
-  mailTaskName = "employerNewCandidatesAvailableTask"
-  lockDurationMs = 6000
-  lockManager.setLock mailTaskName, lockDurationMs, (err, lockResult) ->
-    if err? then return log.error "There was an error getting a task lock!"
-    emailEmployerNewCandidatesAvailableEmail.apply {"mailTaskName":mailTaskName}, (err) ->
-      if err? then return log.error "There was an error performing the #{mailTaskName} email task."
-      lockManager.releaseLock mailTaskName, (err, result) -> if err? then return log.error err
-
-
 ### End Employer New Candidates Available Email ###
 
 ### New Recruit Leaderboard Email ###
@@ -313,17 +341,7 @@ isRequestFromDesignatedCronHandler = (req, res) ->
     return false
   return true
 
-createMailTask = (req, res) ->
-  #unless req.user?.isAdmin() then return errors.forbidden(res)
-  unless req.body.url and req.body.frequency then return errors.badInput(res)
-  console.log "Creating mail task with url #{req.body.url} and frequency #{req.body.frequency}"
-  newMailTask = new MailTask {}
-  newMailTask.set("url",req.body.url)
-  newMailTask.set("frequency",req.body.frequency)
-  newMailTask.save (err) ->
-    if err? then return errors.serverError(res, err)
-    res.send("Created mail task!")
-    res.end()
+
   
 handleLadderUpdate = (req, res) ->
   log.info('Going to see about sending ladder update emails.')

From ae23679a26babc948d7b961ae4a7755e96ad5747 Mon Sep 17 00:00:00 2001
From: Michael Schmatz <michaelschmatz@gmail.com>
Date: Wed, 16 Jul 2014 16:37:06 -0700
Subject: [PATCH 12/58] Hard code mail tasks and add unsubscribe

---
 app/schemas/models/mail_task.coffee        | 21 ----------
 server/mail/tasks/MailTask.coffee          |  7 ----
 server/mail/tasks/mail_task_handler.coffee | 12 ------
 server/routes/auth.coffee                  |  5 ++-
 server/routes/mail.coffee                  | 49 +++++++++++-----------
 5 files changed, 28 insertions(+), 66 deletions(-)
 delete mode 100644 app/schemas/models/mail_task.coffee
 delete mode 100644 server/mail/tasks/MailTask.coffee
 delete mode 100644 server/mail/tasks/mail_task_handler.coffee

diff --git a/app/schemas/models/mail_task.coffee b/app/schemas/models/mail_task.coffee
deleted file mode 100644
index ac450e0ee..000000000
--- a/app/schemas/models/mail_task.coffee
+++ /dev/null
@@ -1,21 +0,0 @@
-c = require './../schemas'
-#This will represent transactional emails which have been sent
-
-MailTaskSchema = c.object {
-  title: 'Mail task'
-  description: 'Mail tasks to call at certain intervals'
-}
-_.extend MailTaskSchema.properties,
-  url: 
-    title: 'URL'
-    description: 'The associated URL of the mailtask to call'
-    type: 'string'
-  frequency:
-    title: 'Frequency'
-    description: 'The number of seconds the servers should check whether or not to send the email'
-    type: 'integer'
-
-c.extendBasicProperties MailTaskSchema, 'mail.task'
-
-module.exports = MailTaskSchema
-  
\ No newline at end of file
diff --git a/server/mail/tasks/MailTask.coffee b/server/mail/tasks/MailTask.coffee
deleted file mode 100644
index 10a536787..000000000
--- a/server/mail/tasks/MailTask.coffee
+++ /dev/null
@@ -1,7 +0,0 @@
-mongoose = require 'mongoose'
-plugins = require '../../plugins/plugins'
-jsonschema = require '../../../app/schemas/models/mail_task'
-
-MailTaskSchema = new mongoose.Schema({}, {strict: false})
-
-module.exports = MailTask = mongoose.model('mail.task', MailTaskSchema)
diff --git a/server/mail/tasks/mail_task_handler.coffee b/server/mail/tasks/mail_task_handler.coffee
deleted file mode 100644
index 12b6be53a..000000000
--- a/server/mail/tasks/mail_task_handler.coffee
+++ /dev/null
@@ -1,12 +0,0 @@
-MailTask = require './MailTask'
-Handler = require '../../commons/Handler'
-
-class MailTaskHandler extends Handler
-  modelClass: MailTask
-  editableProperties: ['url','frequency']
-  jsonSchema: require '../../../app/schemas/models/mail_task'
-  
-  hasAccess: (req) ->
-    req.user?.isAdmin()
-    
-module.exports = new MailTaskHandler()
diff --git a/server/routes/auth.coffee b/server/routes/auth.coffee
index 5c3298f44..36c836741 100644
--- a/server/routes/auth.coffee
+++ b/server/routes/auth.coffee
@@ -143,7 +143,10 @@ module.exports.setup = (app) ->
         emails.recruitNotes ?= {}
         emails.recruitNotes.enabled = false
         msg = "Unsubscribed #{req.query.email} from recruiting emails."
-
+      else if req.query.employerNotes
+        emails.employerNotes ?= {}
+        emails.employerNotes.enabled = false
+        msg = "Unsubscribed #{req.query.email} from employer emails."
       else
         msg = "Unsubscribed #{req.query.email} from all CodeCombat emails. Sorry to see you go!"
         emailSettings.enabled = false for emailSettings in _.values(emails)
diff --git a/server/routes/mail.coffee b/server/routes/mail.coffee
index 6939d8080..3a41e5316 100644
--- a/server/routes/mail.coffee
+++ b/server/routes/mail.coffee
@@ -1,5 +1,4 @@
 mail = require '../commons/mail'
-MailTask = require '../mail/tasks/MailTask'
 MailSent = require '../mail/sent/MailSent'
 User = require '../users/User'
 async = require 'async'
@@ -12,42 +11,36 @@ sendwithus = require '../sendwithus'
 if config.isProduction or config.redis.host isnt "localhost" #TODO: Ask Nick and Scott to change their environment variables and change the deploy ones
   lockManager = require '../commons/LockManager'
 #TODO: Ask Nick about email unsubscriptions
-createMailTask = (req, res) -> #TODO: Ask Nick whether he thinks it is a good idea or not to hardcode the mail tasks
-  unless req.user?.isAdmin() then return errors.forbidden(res)
-  unless req.body.url and req.body.frequency then return errors.badInput(res)
-  console.log "Creating mail task with url #{req.body.url} and frequency #{req.body.frequency}"
-  newMailTask = new MailTask {}
-  newMailTask.set("url",req.body.url)
-  newMailTask.set("frequency",req.body.frequency)
-  newMailTask.save (err) ->
-    if err? then return errors.serverError(res, err)
-    res.send("Created mail task!")
-    res.end()
 
 module.exports.setup = (app) ->
   app.all config.mail.mailchimpWebhook, handleMailchimpWebHook
   app.get '/mail/cron/ladder-update', handleLadderUpdate
-  app.post '/mail/task', createMailTask
   if lockManager
     setupScheduledEmails()
   
 setupScheduledEmails = ->
   testForLockManager()
-  mailTaskMap = #TODO: Edit this to include additional emails
-    "test_mail_task": candidateUpdateProfileTask
+  mailTasks = [
+      taskFunction: candidateUpdateProfileTask
+      frequencyMs: 30 * 60 * 1000 #30 minutes
+    ,
+      taskFunction: internalCandidateUpdateTask
+      frequencyMs: 10 * 60 * 1000 #10 minutes
+    ,
+      taskFunction: employerNewCandidatesAvailableTask
+      frequencyMs: 30 * 60 * 1000 #30 minutes
+  ]
+
+  for mailTask in mailTasks
+    setInterval mailTask.taskFunction, mailTask.frequencyMs 
     
-  MailTask.find({}).lean().exec (err, mailTasks) -> #TODO: Ask Nick whether or not to remove this
-    if err? then throw "Failed to schedule mailTasks! #{err}"
-    for mailTask in mailTasks
-      setInterval mailTaskMap[mailTask.url], mailTask.frequency*2 #TODO: Have some random offset to prevent lock contention
-      
 testForLockManager = -> unless lockManager then throw "The system isn't configured to do distributed locking!"
   
 ### Candidate Update Reminder Task ###
 
 candidateUpdateProfileTask = ->
   mailTaskName = "candidateUpdateProfileTask"
-  lockDurationMs = 20000 #TODO: Change these to something appropriate for the mail frequency (ideally longer than the task but shorter than frequency)
+  lockDurationMs = 2 * 60 * 1000 
   currentDate = new Date()
   timeRanges = []
   for weekPair in [[4, 2,'two weeks'], [8, 4, 'four weeks'], [8, 52, 'eight weeks']]
@@ -86,10 +79,13 @@ findAllCandidatesWithinTimeRange = (cb) ->
       $gt: @timeRange.start
       $lte: @timeRange.end
     "jobProfileApproved": true
-  selection =  "_id email jobProfile.name jobProfile.updated"
+  selection =  "_id email jobProfile.name jobProfile.updated emails" #make sure to check for anyNotes too.
   User.find(findParameters).select(selection).lean().exec cb
   
 candidateFilter = (candidate, sentEmailFilterCallback) ->
+  if candidate.emails?.anyNotes?.enabled is false or candidate.emails?.recruitNotes?.enabled is false
+    log.info "Candidate #{candidate.jobProfile.name} opted out of emails, not sending to them."
+    return sentEmailFilterCallback true
   findParameters =
     "user": candidate._id
     "mailTask": @mailTaskName
@@ -139,7 +135,7 @@ sendReminderEmailToCandidate = (candidate, sendEmailCallback) ->
 ### Internal Candidate Update Reminder Email ###
 internalCandidateUpdateTask = ->
   mailTaskName = "internalCandidateUpdateTask"
-  lockDurationMs = 6000 #TODO: Change lock duration
+  lockDurationMs = 2 * 60 * 1000 
   lockManager.setLock mailTaskName, lockDurationMs, (err) ->
     if err? then return log.error "Error getting a distributed lock for task #{mailTaskName}!"
     emailInternalCandidateUpdateReminder.apply {"mailTaskName":mailTaskName}, (err) ->
@@ -211,7 +207,7 @@ sendInternalCandidateUpdateReminder = (candidate, cb) ->
 ### Employer New Candidates Available Email ###
 employerNewCandidatesAvailableTask = ->
   mailTaskName = "employerNewCandidatesAvailableTask"
-  lockDurationMs = 6000 #TODO: Update this lock duration
+  lockDurationMs = 2 * 60 * 1000 
   lockManager.setLock mailTaskName, lockDurationMs, (err) ->
     if err? then return log.error "There was an error getting a task lock!"
     emailEmployerNewCandidatesAvailable.apply {"mailTaskName":mailTaskName}, (err) ->
@@ -242,7 +238,7 @@ findAllEmployers = (cb) ->
     "employerAt":
       $exists: true 
     permissions: "employer"
-  selection = "_id email employerAt signedEmployerAgreement.data.firstName signedEmployerAgreement.data.lastName activity dateCreated"
+  selection = "_id email employerAt signedEmployerAgreement.data.firstName signedEmployerAgreement.data.lastName activity dateCreated emails"
   User.find(findParameters).select(selection).lean().exec cb
   
 makeEmployerNamesEasilyAccessible = (allEmployers, cb) ->
@@ -254,6 +250,9 @@ makeEmployerNamesEasilyAccessible = (allEmployers, cb) ->
   cb null, allEmployers
   
 employersEmailedDigestMoreThanWeekAgoFilter = (employer, cb) ->
+  if employer.emails?.employerNotes?.enabled is false
+    log.info "Employer #{employer.name}(#{employer.email}) opted out of emails, not sending to them."
+    return sentEmailFilterCallback true
   findParameters = 
     "user": employer._id
     "mailTask": @mailTaskName

From fc4568a100dcc922e10564b5fabf58715c4885b4 Mon Sep 17 00:00:00 2001
From: Michael Schmatz <michaelschmatz@gmail.com>
Date: Wed, 16 Jul 2014 17:02:40 -0700
Subject: [PATCH 13/58] Fixed misc bugs

---
 server/routes/mail.coffee | 12 +++++-------
 1 file changed, 5 insertions(+), 7 deletions(-)

diff --git a/server/routes/mail.coffee b/server/routes/mail.coffee
index 3a41e5316..45f90ac2d 100644
--- a/server/routes/mail.coffee
+++ b/server/routes/mail.coffee
@@ -10,8 +10,7 @@ log = require 'winston'
 sendwithus = require '../sendwithus'
 if config.isProduction or config.redis.host isnt "localhost" #TODO: Ask Nick and Scott to change their environment variables and change the deploy ones
   lockManager = require '../commons/LockManager'
-#TODO: Ask Nick about email unsubscriptions
-
+  
 module.exports.setup = (app) ->
   app.all config.mail.mailchimpWebhook, handleMailchimpWebHook
   app.get '/mail/cron/ladder-update', handleLadderUpdate
@@ -84,7 +83,6 @@ findAllCandidatesWithinTimeRange = (cb) ->
   
 candidateFilter = (candidate, sentEmailFilterCallback) ->
   if candidate.emails?.anyNotes?.enabled is false or candidate.emails?.recruitNotes?.enabled is false
-    log.info "Candidate #{candidate.jobProfile.name} opted out of emails, not sending to them."
     return sentEmailFilterCallback true
   findParameters =
     "user": candidate._id
@@ -138,7 +136,7 @@ internalCandidateUpdateTask = ->
   lockDurationMs = 2 * 60 * 1000 
   lockManager.setLock mailTaskName, lockDurationMs, (err) ->
     if err? then return log.error "Error getting a distributed lock for task #{mailTaskName}!"
-    emailInternalCandidateUpdateReminder.apply {"mailTaskName":mailTaskName}, (err) ->
+    emailInternalCandidateUpdateReminder.call {"mailTaskName":mailTaskName}, (err) ->
       if err
         log.error "There was an error sending the internal candidate update reminder.: #{err}"
       else
@@ -166,7 +164,7 @@ findNonApprovedCandidatesWhoUpdatedJobProfileToday = (cb) ->
   findParameters = 
     "jobProfile.updated":
       $lte: @currentTime.toISOString()
-      gt: @beginningOfUTCDay.toISOString()
+      $gt: @beginningOfUTCDay.toISOString()
     "jobProfileApproved": false 
   User.find(findParameters).select("_id jobProfile.name jobProfile.updated").lean().exec cb
   
@@ -209,8 +207,8 @@ employerNewCandidatesAvailableTask = ->
   mailTaskName = "employerNewCandidatesAvailableTask"
   lockDurationMs = 2 * 60 * 1000 
   lockManager.setLock mailTaskName, lockDurationMs, (err) ->
-    if err? then return log.error "There was an error getting a task lock!"
-    emailEmployerNewCandidatesAvailable.apply {"mailTaskName":mailTaskName}, (err) ->
+    if err? then return log.error "There was an error getting a task lock!: #{err}"
+    emailEmployerNewCandidatesAvailable.call {"mailTaskName":mailTaskName}, (err) ->
       if err
         log.error "There was an error completing the new candidates available task: #{err}"
       else

From d821e459d171d438b62ea750c01864258686aea8 Mon Sep 17 00:00:00 2001
From: Michael Schmatz <michaelschmatz@gmail.com>
Date: Wed, 16 Jul 2014 19:46:06 -0700
Subject: [PATCH 14/58] Encode/decode emails as URIs

This helps to handle special characters like plusses.
---
 server/routes/auth.coffee |  6 ++++--
 server/routes/mail.coffee | 15 +++++++++------
 2 files changed, 13 insertions(+), 8 deletions(-)

diff --git a/server/routes/auth.coffee b/server/routes/auth.coffee
index 36c836741..dd9dffee7 100644
--- a/server/routes/auth.coffee
+++ b/server/routes/auth.coffee
@@ -117,7 +117,8 @@ module.exports.setup = (app) ->
     )
   )
 
-  app.get '/auth/unsubscribe', (req, res) ->
+  app.get '/auth/unsubscribe', (req, res) ->  
+    req.query.email = decodeURIComponent(req.query.email)
     email = req.query.email
     unless req.query.email
       return errors.badInput res, 'No email provided to unsubscribe.'
@@ -131,7 +132,7 @@ module.exports.setup = (app) ->
           return errors.serverError res, 'Database failure.' if err
           res.send "Unsubscribed #{req.query.email} from CodeCombat emails for #{session.levelName} #{session.team} ladder updates. Sorry to see you go! <p><a href='/play/ladder/#{session.levelID}#my-matches'>Ladder preferences</a></p>"
           res.end()
-
+    
     User.findOne({emailLower: req.query.email.toLowerCase()}).exec (err, user) ->
       if not user
         return errors.notFound res, "No user found with email '#{req.query.email}'"
@@ -146,6 +147,7 @@ module.exports.setup = (app) ->
       else if req.query.employerNotes
         emails.employerNotes ?= {}
         emails.employerNotes.enabled = false
+        
         msg = "Unsubscribed #{req.query.email} from employer emails."
       else
         msg = "Unsubscribed #{req.query.email} from all CodeCombat emails. Sorry to see you go!"
diff --git a/server/routes/mail.coffee b/server/routes/mail.coffee
index 45f90ac2d..6490b4394 100644
--- a/server/routes/mail.coffee
+++ b/server/routes/mail.coffee
@@ -21,13 +21,13 @@ setupScheduledEmails = ->
   testForLockManager()
   mailTasks = [
       taskFunction: candidateUpdateProfileTask
-      frequencyMs: 30 * 60 * 1000 #30 minutes
+      frequencyMs: 10 * 60 * 1000 #10 minutes
     ,
       taskFunction: internalCandidateUpdateTask
       frequencyMs: 10 * 60 * 1000 #10 minutes
     ,
       taskFunction: employerNewCandidatesAvailableTask
-      frequencyMs: 30 * 60 * 1000 #30 minutes
+      frequencyMs: 10 * 60 * 1000 #10 minutes
   ]
 
   for mailTask in mailTasks
@@ -48,7 +48,7 @@ candidateUpdateProfileTask = ->
       end: generateWeekOffset currentDate, weekPair[1]
       name: weekPair[2]
   lockManager.setLock mailTaskName, lockDurationMs, (err) ->
-    if err? then return log.error "Error getting a distributed lock for task #{mailTaskName}!"
+    if err? then return log.error "Error getting a distributed lock for task #{mailTaskName}: #{err}"
     async.each timeRanges, emailTimeRange.bind({mailTaskName: mailTaskName}), (err) ->
       if err
         log.error "There was an error sending the candidate profile update reminder emails: #{err}"
@@ -108,6 +108,8 @@ sendReminderEmailToCandidate = (candidate, sendEmailCallback) ->
     if err?
       log.error "There was an error finding employers who signed up after #{candidate.jobProfile.updated}: #{err}"
       return sendEmailCallback err
+    if employersAfterCount < 2
+      employersAfterCount = 2
     context =
       email_id: "tem_CtTLsKQufxrxoPMn7upKiL"
       recipient:
@@ -117,6 +119,7 @@ sendReminderEmailToCandidate = (candidate, sendEmailCallback) ->
         new_company: employersAfterCount
         company_name: "CodeCombat"
         user_profile: "http://codecombat.com/account/profile/#{candidate._id}"
+        recipient_address: encodeURIComponent(candidate.email)
     log.info "Sending #{@timeRange.name} update reminder to #{context.recipient.name}(#{context.recipient.address})"
     newSentMail =
       mailTask: @mailTaskName
@@ -135,7 +138,7 @@ internalCandidateUpdateTask = ->
   mailTaskName = "internalCandidateUpdateTask"
   lockDurationMs = 2 * 60 * 1000 
   lockManager.setLock mailTaskName, lockDurationMs, (err) ->
-    if err? then return log.error "Error getting a distributed lock for task #{mailTaskName}!"
+    if err? then return log.error "Error getting a distributed lock for task #{mailTaskName}: #{err}"
     emailInternalCandidateUpdateReminder.call {"mailTaskName":mailTaskName}, (err) ->
       if err
         log.error "There was an error sending the internal candidate update reminder.: #{err}"
@@ -207,7 +210,7 @@ employerNewCandidatesAvailableTask = ->
   mailTaskName = "employerNewCandidatesAvailableTask"
   lockDurationMs = 2 * 60 * 1000 
   lockManager.setLock mailTaskName, lockDurationMs, (err) ->
-    if err? then return log.error "There was an error getting a task lock!: #{err}"
+    if err? then return log.error "Error getting a distributed lock for task #{mailTaskName}: #{err}"
     emailEmployerNewCandidatesAvailable.call {"mailTaskName":mailTaskName}, (err) ->
       if err
         log.error "There was an error completing the new candidates available task: #{err}"
@@ -249,7 +252,6 @@ makeEmployerNamesEasilyAccessible = (allEmployers, cb) ->
   
 employersEmailedDigestMoreThanWeekAgoFilter = (employer, cb) ->
   if employer.emails?.employerNotes?.enabled is false
-    log.info "Employer #{employer.name}(#{employer.email}) opted out of emails, not sending to them."
     return sentEmailFilterCallback true
   findParameters = 
     "user": employer._id
@@ -286,6 +288,7 @@ sendEmployerNewCandidatesAvailableEmail = (employer, cb) ->
         new_candidates: numberOfCandidatesSinceLogin
         employer_company_name: employer.employerAt
         company_name: "CodeCombat"
+        recipient_address: encodeURIComponent(employer.email)
     if employer.name
       context.recipient.name = employer.name
     log.info "Sending available candidates update reminder to #{context.recipient.name}(#{context.recipient.address})"

From c717e609eaace0e9e46ef06f05ba9f427cfba476 Mon Sep 17 00:00:00 2001
From: Michael Schmatz <michaelschmatz@gmail.com>
Date: Wed, 16 Jul 2014 19:46:30 -0700
Subject: [PATCH 15/58] Initialize value of this.redisNotAvailable

---
 server/commons/LockManager.coffee | 1 +
 1 file changed, 1 insertion(+)

diff --git a/server/commons/LockManager.coffee b/server/commons/LockManager.coffee
index bdd847bf7..bd0a89171 100644
--- a/server/commons/LockManager.coffee
+++ b/server/commons/LockManager.coffee
@@ -6,6 +6,7 @@ class LockManager
   constructor: ->
     unless config.isProduction or config.redis.host isnt "localhost"
       throw "You shouldn't be instantiating distributed locks unless in production."
+    @redisNotAvailable = true
     @redisClient = redis.createClient config.redis.port, config.redis.host
     @redisClient.on "ready", =>
       log.info "Redis ready!"

From 2a865a0ca06ddf453d9d02200f291a47d8def9dc Mon Sep 17 00:00:00 2001
From: Michael Schmatz <michaelschmatz@gmail.com>
Date: Wed, 16 Jul 2014 19:49:48 -0700
Subject: [PATCH 16/58] Remove testing conditions

---
 server/commons/LockManager.coffee | 2 +-
 server/routes/mail.coffee         | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/server/commons/LockManager.coffee b/server/commons/LockManager.coffee
index bd0a89171..36936b236 100644
--- a/server/commons/LockManager.coffee
+++ b/server/commons/LockManager.coffee
@@ -4,7 +4,7 @@ log = require 'winston'
 
 class LockManager
   constructor: ->
-    unless config.isProduction or config.redis.host isnt "localhost"
+    unless config.isProduction
       throw "You shouldn't be instantiating distributed locks unless in production."
     @redisNotAvailable = true
     @redisClient = redis.createClient config.redis.port, config.redis.host
diff --git a/server/routes/mail.coffee b/server/routes/mail.coffee
index 6490b4394..4098402b0 100644
--- a/server/routes/mail.coffee
+++ b/server/routes/mail.coffee
@@ -8,7 +8,7 @@ LevelSession = require '../levels/sessions/LevelSession'
 Level = require '../levels/Level'
 log = require 'winston'
 sendwithus = require '../sendwithus'
-if config.isProduction or config.redis.host isnt "localhost" #TODO: Ask Nick and Scott to change their environment variables and change the deploy ones
+if config.isProduction
   lockManager = require '../commons/LockManager'
   
 module.exports.setup = (app) ->

From c56be0222295aa404ddcbd167b7e590eecd1e9d6 Mon Sep 17 00:00:00 2001
From: Alan Shen <sunzenshen@gmail.com>
Date: Thu, 17 Jul 2014 01:16:08 -0600
Subject: [PATCH 17/58] Fixed typo: Chose -> Choose

It may be late to describe incoming targets with past tense.
---
 app/views/play_view.coffee | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/app/views/play_view.coffee b/app/views/play_view.coffee
index bd7a412e7..c6679a3f4 100644
--- a/app/views/play_view.coffee
+++ b/app/views/play_view.coffee
@@ -117,7 +117,7 @@ module.exports = class PlayView extends View
         difficulty: 2
         id: 'emphasis-on-aim'
         image: '/file/db/level/525f384d96cd77000000000f/munchkin_masher_icon.png'
-        description: 'Chose your targets carefully.'
+        description: 'Choose your targets carefully.'
       }
       {
         name: 'Zone of Danger'

From 1b6fc95d7721d4d1cc0820c00eb68a6a30b80901 Mon Sep 17 00:00:00 2001
From: Imperadeiro98 <Imperadeiro98@users.noreply.github.com>
Date: Thu, 17 Jul 2014 13:25:25 +0100
Subject: [PATCH 18/58] Update pt-PT.coffee

---
 app/locale/pt-PT.coffee | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/app/locale/pt-PT.coffee b/app/locale/pt-PT.coffee
index 278fc30f6..709320fc5 100644
--- a/app/locale/pt-PT.coffee
+++ b/app/locale/pt-PT.coffee
@@ -186,7 +186,7 @@ module.exports = nativeDescription: "Português (Portugal)", englishDescription:
     error_saving: "Erro ao Guardar"
     saved: "Alterações Guardadas"
     password_mismatch: "As palavras-passe não coincidem."
-#    password_repeat: "Please repeat your password."
+    password_repeat: "Por favor repita a sua palavra-passe."
     job_profile: "Perfil de Emprego"
     job_profile_approved: "O seu perfil de emprego foi aprovado pelo CodeCombat. Os empregadores poderão vê-lo até que o defina como inativo ou não o tenha alterado à 4 semanas."
     job_profile_explanation: "Olá! Preencha isto e entraremos em contacto consigo sobre encontrar um emprego de desenvolvedor de software para si."
@@ -327,7 +327,7 @@ module.exports = nativeDescription: "Português (Portugal)", englishDescription:
 #    pass_screen_blurb: "Review each candidate's code before reaching out. One employer found that 5x as many of our devs passed their technical screen than hiring from Hacker News."
 #    make_hiring_easier: "Make my hiring easier, please."
     what: "O que é o CodeCombat?"
-    what_blurb: "O CodeCombat é um jogo de programação, no navegador e multijogador. Os jogadores escrevem código para controlar as forças deles em batalha contra outros desenvolvedores. Nós suportamos JavaScript, Python, Lua, Clojure, CoffeeScript e Io."
+    what_blurb: "O CodeCombat é um jogo de programação, no navegador e multijogador. Os jogadores escrevem código para controlar as forças deles em batalha contra outros desenvolvedores. Os nossos jogadores têm experiência com todos os conceitos tecnológicos principais."
     cost: "Quanto é que cobramos?"
     cost_blurb: "Cobramos 15% do salário do primeiro ano e ofereçemos uma garantia de devolução de 100% do dinheiro durante 90 dias. Não cobramos por candidatos que já estejam a ser ativamente entrevistados na sua companhia."
     candidate_name: "Nome"

From 991ef61d6220da3e8eabbf7c8f872f9d9ed5b6e4 Mon Sep 17 00:00:00 2001
From: Imperadeiro98 <Imperadeiro98@users.noreply.github.com>
Date: Thu, 17 Jul 2014 13:44:14 +0100
Subject: [PATCH 19/58] Update pt-PT.coffee

---
 app/locale/pt-PT.coffee | 36 ++++++++++++++++++------------------
 1 file changed, 18 insertions(+), 18 deletions(-)

diff --git a/app/locale/pt-PT.coffee b/app/locale/pt-PT.coffee
index 709320fc5..155289e42 100644
--- a/app/locale/pt-PT.coffee
+++ b/app/locale/pt-PT.coffee
@@ -503,13 +503,13 @@ module.exports = nativeDescription: "Português (Portugal)", englishDescription:
     pick_a_terrain: "Escolha Um Terreno"
     small: "Pequeno"
     grassy: "Com Relva"
-#    fork_title: "Fork New Version"
-#    fork_creating: "Creating Fork..."
+    fork_title: "Bifurcar Nova Versão"
+    fork_creating: "A Criar Bifurcação..."
 #    randomize: "Randomize"
-#    more: "More"
-#    wiki: "Wiki"
-#    live_chat: "Live Chat"
-    level_some_options: "Algumas opções?"
+    more: "Mais"
+    wiki: "Wiki"
+    live_chat: "Chat Ao Vivo"
+    level_some_options: "Algumas Opções?"
     level_tab_thangs: "Thangs"
     level_tab_scripts: "Scripts"
     level_tab_settings: "Configurações"
@@ -522,19 +522,19 @@ module.exports = nativeDescription: "Português (Portugal)", englishDescription:
 #    delete: "Delete"
 #    duplicate: "Duplicate"
     level_settings_title: "Configurações"
-    level_component_tab_title: "Componentes atuais"
-    level_component_btn_new: "Cria um novo Componente"
-    level_systems_tab_title: "Sistemas atuais"
-    level_systems_btn_new: "Cria um novo Sistema"
-    level_systems_btn_add: "Adiciona um Sistema"
+    level_component_tab_title: "Componentes Atuais"
+    level_component_btn_new: "Criar Novo Componente"
+    level_systems_tab_title: "Sistemas Atuais"
+    level_systems_btn_new: "Cria Novo Sistema"
+    level_systems_btn_add: "Adicionar Sistema"
     level_components_title: "Voltar para Todos os Thangs"
     level_components_type: "Tipo"
     level_component_edit_title: "Editar Componente"
 #    level_component_config_schema: "Config Schema"
     level_component_settings: "Configurações"
     level_system_edit_title: "Editar Sistema"
-    create_system_title: "Criar novo Sistema"
-    new_component_title: "Criar novo Componente"
+    create_system_title: "Criar Novo Sistema"
+    new_component_title: "Criar Novo Componente"
     new_component_field_system: "Sistema"
     new_article_title: "Criar um Novo Artigo"
     new_thang_title: "Criar um Novo Tipo de Thang"
@@ -559,20 +559,20 @@ module.exports = nativeDescription: "Português (Portugal)", englishDescription:
     name: "Nome"
     body: "Corpo"
     version: "Versão"
-    commit_msg: "Mensagem de Commit"
-#    version_history: "Version History"
-    version_history_for: "Histórico de versões por: "
+    commit_msg: "Enviar Mensagem"
+    version_history: "Histórico de Versões"
+    version_history_for: "Histórico de Versões para: "
     result: "Resultado"
     results: "Resultados"
     description: "Descrição"
     or: "ou"
-#    subject: "Subject"
+    subject: "Assunto"
     email: "E-mail"
     password: "Palavra-passe"
     message: "Mensagem"
     code: "Código"
     ladder: "Classificação"
-    when: "quando"
+    when: "Quando"
     opponent: "Adversário"
     rank: "Classificação"
     score: "Resultado"

From 17a4a689e4a73340a2453e1174ef05ba58200e2d Mon Sep 17 00:00:00 2001
From: Imperadeiro98 <Imperadeiro98@users.noreply.github.com>
Date: Thu, 17 Jul 2014 14:18:29 +0100
Subject: [PATCH 20/58] Update pt-PT.coffee

---
 app/locale/pt-PT.coffee | 46 ++++++++++++++++++++---------------------
 1 file changed, 23 insertions(+), 23 deletions(-)

diff --git a/app/locale/pt-PT.coffee b/app/locale/pt-PT.coffee
index 155289e42..ec504f6db 100644
--- a/app/locale/pt-PT.coffee
+++ b/app/locale/pt-PT.coffee
@@ -768,17 +768,17 @@ module.exports = nativeDescription: "Português (Portugal)", englishDescription:
     ambassador_title_description: "(Suporte)"
 
   ladder:
-    please_login: "Por favor, faz log in antes de jogar um jogo para o campeonato."
-    my_matches: "Os meus jogos"
+    please_login: "Por favor inicie sessão antes de jogar um jogo do campeonato."
+    my_matches: "Os Meus Jogos"
     simulate: "Simular"
-    simulation_explanation: "Simulando jogos podes fazer com que o teu jogo seja classificado mais rapidamente!"
+    simulation_explanation: "Ao simular jogos pode ter o seu jogo classificado mais rapidamente!"
     simulate_games: "Simular Jogos!"
 #    simulate_all: "RESET AND SIMULATE GAMES"
-#    games_simulated_by: "Games simulated by you:"
-#    games_simulated_for: "Games simulated for you:"
-#    games_simulated: "Games simulated"
-#    games_played: "Games played"
-#    ratio: "Ratio"
+    games_simulated_by: "Jogos simulados por si:"
+    games_simulated_for: "Jogos simulados para si:"
+    games_simulated: "Jogos simulados"
+    games_played: "Jogos jogados"
+    ratio: "Rácio"
     leaderboard: "Tabela de Classificação"
     battle_as: "Lutar como "
     summary_your: "As tuas "
@@ -868,29 +868,29 @@ module.exports = nativeDescription: "Português (Portugal)", englishDescription:
 #    server_error: "Server error."
 #    unknown: "Unknown error."
 
-#  resources:
-#    your_sessions: "Your Sessions"
-#    level: "Level"
+  resources:
+    your_sessions: "As Suas Sessões"
+    level: "Nível"
 #    social_network_apis: "Social Network APIs"
 #    facebook_status: "Facebook Status"
-#    facebook_friends: "Facebook Friends"
+    facebook_friends: "Amigos do Facebook"
 #    facebook_friend_sessions: "Facebook Friend Sessions"
-#    gplus_friends: "G+ Friends"
+    gplus_friends: "Amigos do Google+"
 #    gplus_friend_sessions: "G+ Friend Sessions"
-#    leaderboard: "Leaderboard"
+    leaderboard: "Tabela de Classificação"
 #    user_schema: "User Schema"
 #    user_profile: "User Profile"
 #    patches: "Patches"
 #    patched_model: "Source Document"
 #    model: "Model"
-#    system: "System"
-#    component: "Component"
-#    components: "Components"
-#    thang: "Thang"
-#    thangs: "Thangs"
-#    level_session: "Your Session"
-#    opponent_session: "Opponent Session"
-#    article: "Article"
+    system: "Sistema"
+    component: "Componente"
+    components: "Componentes"
+    thang: "Thang"
+    thangs: "Thangs"
+    level_session: "A Sua Sessão"
+    opponent_session: "Sessão Do Oponente"
+    article: "Artigo"
 #    user_names: "User Names"
 #    thang_names: "Thang Names"
 #    files: "Files"
@@ -900,7 +900,7 @@ module.exports = nativeDescription: "Português (Portugal)", englishDescription:
 #    sprite_sheet: "Sprite Sheet"
 #    candidate_sessions: "Candidate Sessions"
 #    user_remark: "User Remark"
-#    versions: "Versions"
+    versions: "Versões"
 
 #  delta:
 #    added: "Added"

From 337de506dd9786dc7b0d65a29b4d98e4fcc9ca9d Mon Sep 17 00:00:00 2001
From: Michael Schmatz <michaelschmatz@gmail.com>
Date: Thu, 17 Jul 2014 07:15:14 -0700
Subject: [PATCH 21/58] Removed mail task from server mapping

---
 server/commons/mapping.coffee | 1 -
 1 file changed, 1 deletion(-)

diff --git a/server/commons/mapping.coffee b/server/commons/mapping.coffee
index faa0ef551..69f8abfc0 100644
--- a/server/commons/mapping.coffee
+++ b/server/commons/mapping.coffee
@@ -9,7 +9,6 @@ module.exports.handlers =
   'thang_type': 'levels/thangs/thang_type_handler'
   'user': 'users/user_handler'
   'user_remark': 'users/remarks/user_remark_handler'
-  'mail_task': 'mail/tasks/mail_task_handler'
   'mail_sent': 'mail/sent/mail_sent_handler'
   'achievement': 'achievements/achievement_handler'
   'earned_achievement': 'achievements/earned_achievement_handler'

From 58a80f2512e9d32bd83659985faf16d3f1191e8f Mon Sep 17 00:00:00 2001
From: Michael Schmatz <michaelschmatz@gmail.com>
Date: Thu, 17 Jul 2014 07:17:25 -0700
Subject: [PATCH 22/58] Removed old comment

---
 server/routes/mail.coffee | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/server/routes/mail.coffee b/server/routes/mail.coffee
index 4098402b0..0f648178e 100644
--- a/server/routes/mail.coffee
+++ b/server/routes/mail.coffee
@@ -187,7 +187,7 @@ sendInternalCandidateUpdateReminder = (candidate, cb) ->
   context =
     email_id: "tem_Ac7nhgKqatTHBCgDgjF5pE"
     recipient: 
-      address: "team@codecombat.com" #Change to whatever email address is necessary
+      address: "team@codecombat.com"
       name: "The CodeCombat Team"
     email_data:
       new_candidate_profile: "https://codecombat.com/account/profile/#{candidate._id}"

From c145f8088c6c1f64189413de990e9287728af817 Mon Sep 17 00:00:00 2001
From: Scott Erickson <sderickson@gmail.com>
Date: Thu, 17 Jul 2014 09:12:12 -0700
Subject: [PATCH 23/58] Fixed the avatar endpoint handling when the user object
 DNE.

---
 server/users/user_handler.coffee | 1 +
 1 file changed, 1 insertion(+)

diff --git a/server/users/user_handler.coffee b/server/users/user_handler.coffee
index 020d30f20..275807ad7 100644
--- a/server/users/user_handler.coffee
+++ b/server/users/user_handler.coffee
@@ -219,6 +219,7 @@ UserHandler = class UserHandler extends Handler
   avatar: (req, res, id) ->
     @modelClass.findById(id).exec (err, document) =>
       return @sendDatabaseError(res, err) if err
+      return @sendNotFoundError(res) unless document
       photoURL = document?.get('photoURL')
       if photoURL
         photoURL = "/file/#{photoURL}"

From 7454c051f0f228a2bd4705b64b19f2e5c4b94b8b Mon Sep 17 00:00:00 2001
From: Scott Erickson <sderickson@gmail.com>
Date: Thu, 17 Jul 2014 09:12:21 -0700
Subject: [PATCH 24/58] Added a job profile view demo.

---
 .../views/user/JobProfileView.demo.coffee     | 627 ++++++++++++++++++
 1 file changed, 627 insertions(+)
 create mode 100644 test/demo/views/user/JobProfileView.demo.coffee

diff --git a/test/demo/views/user/JobProfileView.demo.coffee b/test/demo/views/user/JobProfileView.demo.coffee
new file mode 100644
index 000000000..71e26022d
--- /dev/null
+++ b/test/demo/views/user/JobProfileView.demo.coffee
@@ -0,0 +1,627 @@
+ProfileView = require 'views/account/profile_view'
+
+responses =
+  '/db/user/joe/nameToID':'512ef4805a67a8c507000001'
+  '/db/user/512ef4805a67a8c507000001':{"_id":"512ef4805a67a8c507000001","__v":47,"email":"livelily@gmail.com","emailSubscriptions":["announcement","notification","developer","level_creator","tester","article_editor","translator","support"],"facebookID":"4301215","firstName":"Nick","gender":"male","lastName":"Winter","name":"Nick!","photoURL":"db/user/512ef4805a67a8c507000001/nick_wizard.png","volume":0,"wizardColor1":0.4,"testGroupNumber":217,"mailChimp":{"leid":"70264209","euid":"c4418e2abd","email":"livelily@gmail.com"},"hourOfCode":true,"hourOfCodeComplete":true,"signedCLA":"Fri Jan 03 2014 14:40:18 GMT-0800 (PST)","wizard":{"colorConfig":{"boots":{"lightness":0.1647058823529412,"saturation":0.023809523809523805,"hue":0},"spell":{"hue":0.7490196078431373,"saturation":0.4106280193236715,"lightness":0.5941176470588235},"cloud":{"lightness":0.14,"saturation":1,"hue":0},"clothes":{"lightness":0.1411764705882353,"saturation":0,"hue":0},"trim":{"hue":0.5,"saturation":0.009900990099009936,"lightness":0.19803921568627453}}},"aceConfig":{"liveCompletion":true,"indentGuides":true,"invisibles":true,"keyBindings":"emacs","behaviors":true,"language":"javascript"},"lastLevel":"drink-me","gplusID":"110703832132860599877","jobProfile":{"photoURL":"db/user/512ef4805a67a8c507000001/nick_bokeh_small.jpg","links":[{"name":"Twitter","link":"https://twitter.com/nwinter"},{"name":"Facebook","link":"https://www.facebook.com/nwinter"},{"name":"LinkedIn","link":"https://www.linkedin.com/in/nwinter"},{"name":"Blog","link":"http://blog.nickwinter.net/"},{"name":"Personal Site","link":"http://www.nickwinter.net/"},{"name":"GitHub","link":"https://github.com/nwinter"},{"name":"G+","link":"https://plus.google.com/u/0/+NickWinter"}],"projects":[{"name":"The Motivation Hacker","description":"I wrote a book. *The Motivation Hacker* shows you how to summon extreme amounts of motivation to accomplish anything you can think of. From precommitment to rejection therapy, this is your field guide to getting yourself to want to do everything you always wanted to want to do.","picture":"db/user/512ef4805a67a8c507000001/the_motivation_hacker_thumb.jpg","link":"http://www.nickwinter.net/motivation-hacker"},{"name":"Quantified Mind","description":"Quantified Mind is a tool that quickly, reliably, and comprehensively measures your basic cognitive abilities. We've adapted tests used by psychologists to a practical web application that you can use whenever, wherever, and as often as you want.","picture":"db/user/512ef4805a67a8c507000001/screenshot.png","link":"http://www.quantified-mind.com/"},{"link":"https://github.com/nwinter/telepath-logger","name":"Telepath","description":"A happy Mac keylogger for Quantified Self purposes. It also now serves as a time lapse heads-up-display thing. I used it to make a [time-lapse video of myself working an 120-hour workweek](http://blog.nickwinter.net/the-120-hour-workweek-epic-coding-time-lapse).","picture":"db/user/512ef4805a67a8c507000001/687474703a2f2f63646e2e736574742e636f6d2f696d616765732f757365722f32303133313131303139353534393937375a30356665633666623234623937323263373733636231303537613130626336365f66726f6e742e6a7067"}],"education":[{"school":"Oberlin College","degree":"BA Computer Science, Mathematics, and East Asian Studies, highest honors in CS","duration":"Aug 2004 - May 2008","description":"Cofounded Oberlin Street Art and did all sorts of crazy missions without telling anyone about it."}],"work":[{"employer":"CodeCombat","role":"Cofounder","duration":"Jan 2013 - present","description":"Programming a programming game for learning programming to be a programming programmer of programmatic programs."},{"employer":"Skritter","role":"Cofounder","duration":"May 2008 - present","description":"I coded, I designed, I marketed, I businessed, I wrote, I drudged, I cheffed, I laughed, I cried. But mostly I emailed. God, so much email."}],"visa":"Authorized to work in the US","longDescription":"I cofounded Skritter, am working on CodeCombat, helped with Quantified Mind, live in San Francisco, went to Oberlin College, wrote a book about motivation hacking, and can do anything.\n\nI like hacking on startups, pigs with dogs for feet, and Smash Bros. I dislike shoes, mortality, and Java.\n\nDo you love hiring renegade maverick commandos who can't abide the system? Are you looking to hire the sample job profile candidate of the job profile system? Are you just testing this thing? If your answer is yes, yes yes!–then let us talk.","shortDescription":"Maniac two-time startup cofounder looking to test the system and see what a job profile might look like. Can't nobody hold him down.","experience":6,"skills":["python","coffeescript","node","ios","objective-c","javascript","app-engine","mongodb","web dev","django","backbone","chinese","qs","writing"],"country":"USA","city":"San Francisco","active":false,"lookingFor":"Full-time","name":"Nick Winter","updated":"2014-07-12T01:48:42.980Z","jobTitle":"Mutant Code Gorilla"},"jobProfileApproved":false,"emails":{"anyNotes":{"enabled":true},"generalNews":{"enabled":true},"archmageNews":{"enabled":true},"artisanNews":{"enabled":true},"adventurerNews":{"enabled":true},"scribeNews":{"enabled":true},"diplomatNews":{"enabled":true},"ambassadorNews":{"enabled":true}},"activity":{"viewed_by_employer":{"last":"2014-06-19T20:21:43.747Z","count":6,"first":"2014-06-12T01:37:38.278Z"},"view_candidate":{"first":"2014-06-10T19:59:30.773Z","count":661,"last":"2014-07-11T02:14:40.131Z"},"login":{"first":"2014-06-10T21:55:08.968Z","count":22,"last":"2014-07-16T16:32:31.661Z"},"contacted_by_employer":{"first":"2014-06-19T20:24:51.870Z","count":1,"last":"2014-06-19T20:24:51.870Z"}},"slug":"nick","jobProfileNotes":"Nick used to be the **#1 Brawlwood player** on CodeCombat. He wrote most of the game engine, so that's totally cheating. Now other players have surpassed him by emulating his moves and improving his strategy. If you like the sixth Rocky movie, you might still want to hire this aging hero even in his fading senescence.","simulatedFor":2363,"simulatedBy":103674,"preferredLanguage":"en-US","anonymous":false,"permissions":["admin"],"autocastDelay":90019001,"music":false,"dateCreated":"2013-02-28T06:09:04.743Z"}
+  '/db/user/5162fab9c92b4c751e000274/track/view_candidate': {"result":"success"}
+  '/db/user/512ef4805a67a8c507000001/remark': {"_id":"53a0920b3085e800003f03ab","contactName":"Ignore","userName":"Nick!","contact":"52a57252a89409700d0000d9","user":"512ef4805a67a8c507000001","__v":0,"created":"2014-06-17T19:07:55.970Z"}
+  '/db/user/512ef4805a67a8c507000001/level.sessions/employer': [
+    {
+      "_id": "53179b49b483edfcdb7ef13e",
+      "code": {
+        "human-base": {
+          "chooseAction": "// This is the code for your base. Decide which unit to build each frame.\n// Units you build will go into the this.built array.\n// Destroy the enemy base within 60 seconds!\n// Check out the Guide at the top for more info.\n\n// CHOOSE YOUR HERO! You can only build one hero.\nvar hero;\n//hero = 'tharin';  // A fierce knight with battlecry abilities.\n//hero = 'hushbaum';  // A fiery spellcaster hero.\n\nif(hero && !this.builtHero) {\n    this.builtHero = this.build(hero);\n    return;\n}\n\n// Soldiers are hard-to-kill, low damage melee units with 2s build cooldown.\n// Archers are fragile but deadly ranged units with 2.5s build cooldown.\nvar buildOrder = ['soldier', 'soldier', 'soldier', 'soldier', 'archer'];\nvar type = buildOrder[this.built.length % buildOrder.length];\n//this.say('Unit #' + this.built.length + ' will be a ' + type);\nthis.build(type);"
+        },
+        "programmable-tharin": {
+          "chooseAction": "// Tharin is a melee fighter with shield, warcry, and terrify skills.\n// this.shield() lets him take one-third damage while defending.\n// this.warcry() gives allies within 10m 30% haste for 5s, every 10s.\n// this.terrify() sends foes within 30m fleeing for 5s, once per match.\n\nvar friends = this.getFriends();\nvar enemies = this.getEnemies();\nif (enemies.length === 0) return;  // Chill if all enemies are dead.\nvar enemy = this.getNearest(enemies);\nvar friend = this.getNearest(friends);\n\n// Which one do you do at any given time? Only the last called action happens.\n//if(!this.getCooldown('warcry')) this.warcry();\n//if(!this.getCooldown('terrify')) this.terrify();\n//this.shield();\n//this.attack(enemy);\n\n// You can also command your troops with this.say():\n//this.say(\"Defend!\", {targetPos: {x: 30, y: 30}}));\n//this.say(\"Attack!\", {target: enemy});\n//this.say(\"Move!\", {targetPos: {x: 40, y: 40});\n\n// You can store state on this across frames:\n//this.lastHealth = this.health;"
+        },
+        "programmable-librarian": {
+          "chooseAction": "// The Librarian is a spellcaster with a fireball attack\n// plus three useful spells: 'slow', 'regen', and 'haste'.\n// Slow makes a target move and attack at half speed for 5s.\n// Regen makes a target heal 10 hp/s for 10s.\n// Haste speeds up a target by 4x for 5s, once per match.\n\nvar friends = this.getFriends();\nvar enemies = this.getEnemies();\nif (enemies.length === 0) return;  // Chill if all enemies are dead.\nvar enemy = this.getNearest(enemies);\nvar friend = this.getNearest(friends);\n\n// Which one do you do at any given time? Only the last called action happens.\n//if(this.canCast('slow', enemy)) this.castSlow(enemy);\n//if(this.canCast('regen', friend)) this.castRegen(friend);\n//if(this.canCast('haste', friend)) this.castHaste(friend);\n//this.attack(enemy);\n\n// You can also command your troops with this.say():\n//this.say(\"Defend!\", {targetPos: {x: 30, y: 30}}));\n//this.say(\"Attack!\", {target: enemy});\n//this.say(\"Move!\", {targetPos: {x: 50, y: 40});"
+        },
+        "nazgareth": {
+          "chooseAction": "// Shamans are spellcasters with a weak magic attack\n// plus two useful spells: 'regen' and 'shrink'.\n\nvar enemy = this.getNearestEnemy();\nif (!enemy)\n    this.move({x: 10, y: 25});\nelse if (!enemy.hasEffect('shrink')) {\n    this.castShrink(enemy);\n    if(this.distance(enemy) <= 30)\n        this.say(\"Shrink, vile \" + enemy.type + \" \" + enemy.id);\n}\nelse {\n    this.attack(enemy);\n}"
+        },
+        "ironjaw": {
+          "chooseAction": "var enemies = this.getEnemies();\nvar enemy = this.getNearest(enemies);\nif (enemy) {\n    if(!this.getCooldown('jump')) {\n        this.jumpTo(enemy.pos);\n        this.say(\"Hi \" + enemy.type + \" \" + enemy.id);\n    }\n    else {\n        this.attack(enemy);\n    }\n}\nelse {\n    this.move({x: 10, y: 30});\n}"
+        },
+        "poult": {
+          "chooseAction": "// Shamans are spellcasters with a weak magic attack\n// plus two useful spells: 'regen' and 'shrink'.\n\nvar enemy = this.getNearestEnemy();\nif (!enemy)\n    this.move({x: 10, y: 25});\nelse if (!enemy.hasEffect('shrink')) {\n    this.castShrink(enemy);\n    if(this.distance(enemy) <= 30)\n        this.say(\"Shrink, vile \" + enemy.type + \" \" + enemy.id);\n}\nelse {\n    this.attack(enemy);\n}"
+        }
+      },
+      "submitted": false,
+      "levelID": "dungeon-arena",
+      "levelName": "Dungeon Arena",
+      "submittedCodeLanguage": "javascript",
+      "playtime": 33,
+      "codeLanguage": "javascript"
+    },
+    {
+      "_id": "53336ee91506ed33756f73e5",
+      "code": {
+        "tharin": {
+          "chooseAction": "this.say(\"Say, who's in charge around here?\");  // Should fill in some default source"
+        },
+        "programmable-coin": {
+          "chooseAction": "//this.say(\"Say, who's in charge around here?\");  // Should fill in some default source\n\n//var time = this.now();\n//if(Math.round(time) % 20 === 0) {\n    this.teleportRandom();\n//}o"
+        },
+        "wizard-purple": {
+          "chooseAction": "//this.say(\"Say, who's in charge around here?\");  // Should fill in some default source\n\n//var time = this.now();\n\n//if(Math.round(time) % 20 == 0) {\n    this.build('coin');\n//    console.log(\"build coin\");\n//}"
+        }
+      },
+      "levelID": "gold-rush",
+      "levelName": "Resource gathering multiplayer",
+      "submittedCodeLanguage": "javascript",
+      "playtime": 0,
+      "codeLanguage": "javascript"
+    },
+    {
+      "_id": "52ae32cbef42c52f1300000d",
+      "levelID": "gridmancer",
+      "levelName": "Gridmancer",
+      "code": {
+        "captain-anya": {
+          "plan": "function largestRectangle(grid, bottomY, leftX, width, height) {\n    var coveredRows = [];\n    var shortestCoveredRow = width - leftX;\n    var done = false;\n    for(var y = bottomY; !done && y < height; ++y) {\n        var coveredRow = 0, done2 = false;\n        for(var x = leftX; !done2 && x < leftX + shortestCoveredRow; ++x) {\n            if(!grid[y][x].length)\n                ++coveredRow;\n            else\n                done2 = true;\n        }\n        if(!coveredRow)\n            done = true;\n        else {\n            coveredRows.push(coveredRow);\n            shortestCoveredRow = Math.min(shortestCoveredRow, coveredRow);\n        }\n    }\n    var maxArea = 0, maxAreaRows = 0, maxAreaRowLength = 0, shortestRow = 0;\n    for(var rowIndex = 0; rowIndex < coveredRows.length; ++rowIndex) {\n        var rowLength = coveredRows[rowIndex];\n        if(!shortestRow)\n            shortestRow = rowLength;\n        area = rowLength * (rowIndex + 1);\n        if(area > maxArea) {\n            maxAreaRows = rowIndex +1;\n            maxAreaRowLength = shortestRow;\n            maxArea = area;\n        }\n        shortestRow = Math.min(rowLength, shortestRow);\n    }\n    return {x: leftX + maxAreaRowLength / 2, y: bottomY + maxAreaRows / 2, width: maxAreaRowLength, height: maxAreaRows};\n}\n\n\nvar grid = this.getNavGrid().grid;\nvar tileSize = 4;\nfor(var y = 0; y < grid.length - tileSize / 2; y += tileSize) {\n    for(var x = 0; x < grid[0].length - tileSize / 2; x += tileSize) {\n        var occupied = grid[y][x].length > 0;\n        if(!occupied) {\n            var rect = largestRectangle(grid, y, x, grid[0].length, grid.length);\n            this.addRect(rect.x, rect.y, rect.width, rect.height);\n            //this.say(\"Placed rect \" + rect.x + \", \" + rect.y + \", \" + rect.width + \", \" + rect.height + \" for \" + grid[0].length + \",  \" + grid.length + \", \" + x + \", \" + y);\n            this.wait(0.1);\n            for(var y2 = rect.y - rect.height / 2; y2 < rect.y + rect.height / 2; ++y2) {\n                for(var x2 = rect.x - rect.width / 2; x2 < rect.x + rect.width / 2; ++x2) {\n                    grid[y2][x2] = [rect];\n                }\n            }\n        }\n    }\n}\n"
+        },
+        "thoktar": {
+          "plan": "var grid = this.getNavGrid().grid;\nvar tileSize = 4;\nvar canOverlap = false;\nvar i, rect;\nthis.doWait = function() {\n    this.wait(1);\n    this.say(\"hi\");\n    this.wait(1);\n    this.say(\"there\");\n    this.wait(1);\n};\nthis.doWait();\nfor (var y = 0; y + tileSize < grid.length; y += tileSize) {\n    for (var x = 0; x + tileSize < grid[0].length;) {\n        // check if wall\n        var occupied = grid[y][x].length > 0;\n        // check if already covered by another rect\n        if (!occupied) {\n            for (i = 0; i < this.spawnedRectangles.length; ++i) {\n                rect = this.spawnedRectangles[i];\n                if (rect.pos.x - rect.width / 2 <= x && x < rect.pos.x + rect.width / 2 && rect.pos.y - rect.height / 2 < y && rect.pos.y + rect.height / 2 > y)\n                    occupied = true;\n            }\n        }\n        if (!occupied) {\n            var x2 = x,\n                y2 = y;\n            // expand to the right until we find a wall\n            while (x2 < grid[0].length - 1 && grid[y][x2 + tileSize].length === 0)\n                x2 += tileSize;\n            // expand current horizontal rectangle vertically until wall\n            var ok = true;\n            while (y2 + tileSize < grid.length && ok) {\n                var yt = y2 + tileSize;\n                // check each cell\n                for (var xt = x; xt <= x2; xt += tileSize) {\n                    if (grid[yt][xt].length > 0) {\n                        ok = false;\n                    }\n                }\n                if (!canOverlap) {\n                    // check if tile to the left is non-wall\n                    if (x > 0 && grid[yt][x - tileSize].length === 0) {\n                        // check if already has a rect\n                        var covered = false;\n                        for (i = 0; i < this.spawnedRectangles.length; ++i) {\n                            rect = this.spawnedRectangles[i];\n                            if (rect.pos.x - rect.width / 2 <= x - tileSize &&\n                                x - tileSize < rect.pos.x + rect.width / 2 &&\n                                rect.pos.y - rect.height / 2 < yt &&\n                                rect.pos.y + rect.height / 2 > yt)\n                                covered = true;\n                        }\n                        // if no wall and no rect leave open to avoid future overlap\n                        if (!covered)\n                            ok = false;\n                    }\n                }\n                // advance\n                if (ok)\n                    y2 += tileSize;\n            }\n            // done\n            this.addRect(x + tileSize / 2 + (x2 - x) / 2, y + tileSize / 2 + (y2 - y) / 2,\n                tileSize + (x2 - x), tileSize + (y2 - y));\n            x = x2 + tileSize;\n            this.wait();\n        } else {\n            x += tileSize;\n        }\n    }\n}\n\n/*\nvar tileSize = 4;\n\nvar grid;\nvar occupied, occupiedArray;\nvar numTilesX, numTilesY;\nvar x, y, y2, x2, x3, y3, lastX, lastY;\nvar width, height;\n\ngrid = this.getNavGrid().grid;\noccupiedArray = [];\n\nfor(y = 0; y + tileSize < grid.length; y += tileSize) \n{\n    occupiedArray[y] = [];\n    for(x = 0; x + tileSize < grid[y].length; x += tileSize) \n    {\n        occupiedArray[y][x] = (grid[y][x].length > 0);\n    }\n}\n\nfor(y = 0; y + tileSize < grid.length; y += tileSize) \n{\n    for(x = 0; x + tileSize < grid[y].length; x += tileSize) \n    {\n        if(!occupiedArray[y][x])\n        {\n            //Check width of rectangle\n            lastX = x;\n            y2 = y;\n            numTilesX = 0;\n            var okay = true;\n            for(x2 = x; okay &&x2 + tileSize < grid[y].length; x2 += tileSize)\n            {\n                if(occupiedArray[y2][x2])\n                {\n                    okay = false;\n                    //x2 = grid[y].length;\n                }\n                else\n                {\n                    lastX = x2;\n                    numTilesX++;\n                }\n            }\n\n            // Check height of rectangle\n            lastY = y;\n            x2 = x;\n            numTilesY = 0;\n            okay = true;\n            for(y2 = y; okay && y2 + tileSize < grid.length; y2 += tileSize)\n            {\n                var okay2 = true;\n                for(x3 = x; okay2 && x3 <= lastX; x3 += tileSize)\n                {\n                    occupied = occupiedArray[y2][x3];\n                    if(occupied)\n                    {\n                        okay2 = false;\n                        //x3 = grid[y].length;\n                    }\n                }\n                if(occupied)\n                {\n                    okay = false;\n                    //y2 = grid.length;\n                }\n                else\n                {\n                    lastY = y2;\n                    numTilesY++;\n                }\n            }\n\n            for(y3 = y; y3 <= lastY; y3 += tileSize)            \n            {\n                for(x3 = x; x3 <= lastX; x3 += tileSize)\n                {\n                    occupiedArray[y3][x3] = true;\n                }\n            }\n  \n            width = numTilesX * tileSize;\n            height = numTilesY * tileSize;\n            this.addRect( x  + (width / 2), y + (height / 2), width, height);\n            \n            this.wait();  // Hover over the timeline to help debug!\n        }       \n    }\n}\n*/\n\n\n/*\nvar todoGrid = this.getNavGrid().grid;\nvar tileSize = 4;\nvar yGridSize = todoGrid.length;\nvar xGridSize = todoGrid[0].length;\nvar x, y;\n//store all tiles which actually need to be filled\nfor(y = 0; y + tileSize < yGridSize; y += tileSize) {\n    for(x = 0; x + tileSize < xGridSize; x += tileSize) {\n        todoGrid[y][x] = todoGrid[y][x].length === 0;\n    }\n}\n\n//determine how many tiles to fill\nvar todoAnz = 0;\nfor(y = 0; y + tileSize < yGridSize; y += tileSize) {\n    for(x = 0; x + tileSize < xGridSize; x += tileSize) {\n        if(todoGrid[y][x]) {\n            todoAnz++;\n        }\n    }\n}\n\n//fill all tiles from biggest to smallest rectangle possible\nwhile(todoAnz > 0) {\n    var biggestLeftX, biggestLeftY, biggestRightX, biggestRightY, tmpX, tmpY;\n    var bigRect = 0;\n    for(y = 0; y + tileSize < yGridSize; y += tileSize) {\n        for(x = 0; x + tileSize < xGridSize; x += tileSize) {\n            if(todoGrid[y][x]) {\n            var width = 1, height = 1;\n            while(todoGrid[y][x + width * tileSize] && x + width * tileSize + tileSize < xGridSize) {\n                width++;\n            }\n            var higher = true;\n            while(higher) {\n                for(tmpX = x; tmpX < x + tileSize * width; tmpX += tileSize)\n                    if(!todoGrid[y + height * tileSize][tmpX] || y + height * tileSize + tileSize >= yGridSize) higher = false;\n                if(higher) height++;\n            }\n            if(width * height > bigRect) {\n                bigRect = width * height;\n                biggestLeftX = x;\n                biggestLeftY = y;\n                biggestRightX = x + width * tileSize;\n                biggestRightY = y + height * tileSize;\n            }\n        }\n    }\n}\nfor(tmpY = biggestLeftY; tmpY < biggestRightY; tmpY += tileSize)\n    for(tmpX = biggestLeftX; tmpX < biggestRightX; tmpX += tileSize)\n        todoGrid[tmpY][tmpX] = false;\n    this.addRect( (biggestLeftX + biggestRightX) / 2,\n                  (biggestLeftY + biggestRightY) / 2,\n                  biggestRightX - biggestLeftX,\n                  biggestRightY - biggestLeftY );\n    this.wait(0.2);\n    todoAnz -= bigRect;\n    // this.say(\"Found a \"+bigRect+\" tile Rectangle, \"+todoAnz+\" tile(s) left\");\n}\n// André\n*/\n\n/*\nvar grid = this.getNavGrid().grid;\nvar tileSize = 4;\nfor(var y = 0; y + tileSize < grid.length; y += tileSize) {\n    for(var x = 0; x + tileSize < grid[0].length; ) {\n\n        var occupied = grid[y][x].length > 0;\n\n        if (!occupied) {\n            for (var i = 0; i < this.spawnedRectangles.length; ++i) {\n                var rect = this.spawnedRectangles[i];\n                if (rect.pos.x - rect.width / 2 <= x && x <= rect.pos.x + rect.width / 2 \n                    && rect.pos.y - rect.height / 2 < y && rect.pos.y + rect.height / 2 > y)\n                    occupied = true;\n            }\n        }\n\n        if(!occupied) {\n            var x2 = x, y2 = y;\n            while (x2 < grid[0].length-1 && grid[y][x2+tileSize].length===0)\n                x2 += tileSize;\n\n            var ok = true;\n            while (y2 + tileSize < grid.length && ok) {\n                var yt = y2 + tileSize; \n                for (var xt = x; xt <= x2; xt += tileSize) {\n                    if (grid[yt][xt].length > 0) {\n                        ok = false;\n                    }\n                }\n                if (x > 0 && grid[yt][x - tileSize].length === 0)\n                    ok = false;\n                if (x2 < grid[0].length-tileSize && grid[yt][x2+tileSize].length === 0)\n                    ok = false;\n                if (ok)\n                    y2 += tileSize; \n            }\n\n\n            this.addRect(x + tileSize / 2 + (x2-x)/2, y + tileSize / 2 + (y2-y)/2, tileSize + (x2-x), tileSize + (y2-y));\n            x = x2 + tileSize;\n            this.wait();\n        } else {\n            x += tileSize;\n        }\n    }\n}\n*/\n\n/*\nvar grid = this.getNavGrid().grid;\nvar tileSize = 4;\nvar isCounting;\nvar adyacentX;\nvar startPos;\n\nfor(var y = 0; y + tileSize < grid.length; y += tileSize) {\n    isCounting = 0;\n    adyacentX = 0;\n    for(var x = 0; x + tileSize < grid[0].length; x += tileSize) {\n        var occupied = grid[y][x].length > 0;\n        if(!occupied) {\n            if(isCounting === 0)\n                startPos = x;\n            isCounting = 1;\n            adyacentX++;\n     // this.say(\"Pos(\"+x+\",\"+y+\") is occupied\");\n     // this.addRect(x + tileSize / 2, y + tileSize / 2, tileSize, tileSize);\n    // this.wait(); // Hover over the timeline to help debug!\n        }\n        else {\n       // this.say(\"Pos(\"+x+\",\"+y+\") is not occupied\");\n            isCounting = 0;\n            if(adyacentX > 0){\n      // this.say(\"writing \" + adyacentX + \"width rectangle= \" + tileSize*adyacentX);\n                this.addRect((startPos + x)/2,y+tileSize / 2,tileSize*adyacentX,tileSize);\n                }\n            adyacentX = 0;\n        }\n    }\n\n}\n\nthis.say(\"Finish!\");\n*/\n\n/*\nfunction largestRectangle(grid, bottomY, leftX, width, height) {\n    var coveredRows = [];\n    var shortestCoveredRow = width - leftX;\n    var done = false;\n    for(var y = bottomY; !done && y < height; ++y) {\n        var coveredRow = 0, done2 = false;\n        for(var x = leftX; !done2 && x < leftX + shortestCoveredRow; ++x) {\n            if(!grid[y][x].length)\n                ++coveredRow;\n            else\n                done2 = true;\n        }\n        if(!coveredRow)\n            done = true;\n        else {\n            coveredRows.push(coveredRow);\n            shortestCoveredRow = Math.min(shortestCoveredRow, coveredRow);\n        }\n    }\n    var maxArea = 0, maxAreaRows = 0, maxAreaRowLength = 0, shortestRow = 0;\n    for(var rowIndex = 0; rowIndex < coveredRows.length; ++rowIndex) {\n        var rowLength = coveredRows[rowIndex];\n        if(!shortestRow)\n            shortestRow = rowLength;\n        area = rowLength * (rowIndex + 1);\n        if(area > maxArea) {\n            maxAreaRows = rowIndex +1;\n            maxAreaRowLength = shortestRow;\n            maxArea = area;\n        }\n        shortestRow = Math.min(rowLength, shortestRow);\n    }\n    return {x: leftX + maxAreaRowLength / 2, y: bottomY + maxAreaRows / 2, width: maxAreaRowLength, height: maxAreaRows};\n}\n\nvar grid = this.getNavGrid().grid;\nvar tileSize = 4;\nfor(var y = 0; y < grid.length - tileSize / 2; y += tileSize) {\n    for(var x = 0; x < grid[0].length - tileSize / 2; x += tileSize) {\n        var occupied = grid[y][x].length > 0;\n        if(!occupied) {\n            var rect = largestRectangle(grid, y, x, grid[0].length, grid.length);\n            this.addRect(rect.x, rect.y, rect.width, rect.height);\n            //this.say(\"Placed rect \" + rect.x + \", \" + rect.y + \", \" + rect.width + \", \" + rect.height + \" for \" + grid[0].length + \",  \" + grid.length + \", \" + x + \", \" + y);\n            this.wait(0.1);\n            for(var y2 = rect.y - rect.height / 2; y2 < rect.y + rect.height / 2; ++y2) {\n                for(var x2 = rect.x - rect.width / 2; x2 < rect.x + rect.width / 2; ++x2) {\n                    grid[y2][x2] = [rect];\n                }\n            }\n        }\n    }\n}\n*/"
+        }
+      },
+      "submitted": false,
+      "submittedCodeLanguage": "javascript",
+      "playtime": 302,
+      "codeLanguage": "javascript"
+    },
+    {
+      "_id": "5334901f0a0f9b286f57382c",
+      "team": "humans",
+      "code": {
+        "coin-generator-9000": {
+          "chooseAction": "var buildOrder = ['coin2', 'coin3', 'coin4'];\n//if (Math.random() < 0.25)\n//    this.build(buildOrder[this.built.length % buildOrder.length]);\nif (Math.random() < 0.05)\n    this.build('gem');\nelse if (Math.random() < 0.25)\n    this.build(buildOrder[this.built.length % buildOrder.length])\nelse if (Math.random() < 0.5)\n    this.build('coin');\n\n\n\nvar human = this.getThangByID(\"Tharin\");\nvar ogre = this.getThangByID(\"Mak Fod\");\n\n//this.say(human.gold);\n\n//this.say(\"Humans: \" + human.gold + \", \" + \"Ogres: \" + ogre.gold);\n\nif(ogre.gold >= 150) {\n    this.say(\"Ogres win!\");\n    this.setGoalState(\"goldOgres\", \"success\");\n}\n\nelse if(human.gold >= 150) {\n    this.say(\"Humans win!\");\n    this.setGoalState(\"goldHumans\", \"success\");\n}"
+        },
+        "programmable-coin": {
+          "chooseAction": "//this.say(\"Say, who's in charge around here?\");  // Should fill in some default source\n\n//var time = this.now();\n//if(Math.round(time) % 20 === 0) {\nif (typeof this.teleportOnce === 'undefined') {\n    this.teleportRandom();\n    this.teleportOnce = true;\n}\n//}"
+        },
+        "tharin": {
+          "chooseAction": "var t = this;\nvar e = t.getNearestEnemy();\nvar vec = new Vector(0, 0);\n\nfunction item_worth(item) {\n    return item.bountyGold/Math.pow(item.distance(e) - t.distance(item), 1.5);\n}\n\nvar items = this.getItems();\nfor (var i = 0; i < items.length; i++) {\n    var item = items[i];\n    var direction = Vector.normalize(Vector.subtract(item.pos, this.pos));\n    var weighted_dir = Vector.multiply(direction, 1000 * item_worth(item));\n    vec = Vector.add(vec, weighted_dir);\n}\n\nvar action = \"move\";\nif (typeof this.used_terrify == \"undefined\") {\n    var enemy = this.getNearestEnemy();\n    \n    if (enemy.gold >= 140 || this.distance(enemy) <= 15) {\n        action = \"terrify\";\n    }\n}\n\nif (action == \"move\") {\n    var best_item = null;\n    var best_item_value = 0;\n    for (var i = 0; i < items.length; i++) {\n        var item = items[i];\n        var direction = Vector.subtract(item.pos, this.pos);\n        \n        var angle = Math.acos(vec.dot(direction) / (vec.magnitude() * direction.magnitude()))\n        if (angle < Math.PI / 16 || angle > Math.PI * (31/16)) {\n            if (item_worth(item) > best_item_value) {\n                best_item_value = item_worth(item);\n                best_item = item;\n            }\n        }\n    }\n    \n    if (best_item_value > 0.05) {\n        this.move(best_item.pos);\n    } else {\n        this.say(\"Move to \" + Vector.add(this.pos, vec).x + \" \" + Vector.add(this.pos, vec).y);\n        this.move(Vector.add(this.pos, vec));\n    }\n} else if (action == \"terrify\") {\n    //this.terrify();\n    this.used_terrify = true;\n}\n/*\n\n// This code runs once per frame. Choose where to move to grab gold!\n// First player to 150 gold wins.\n\n// This is an example of grabbing the 0th coin from the items array.\nvar items = this.getItems();\nif (items[0]) {\n    this.move(items[0].pos);\n} else {\n    this.moveXY(18, 36);\n}\n\n\n// You can surely pick a better coin using the methods below.\n// Click on a coin to see its API.\n*/\n"
+        },
+        "wizard-purple": {
+          "chooseAction": "//this.say(\"Say, who's in charge around here?\");  // Should fill in some default source\n\n//var time = this.now();\n\n//if(Math.round(time) % 20 == 0) {\n    this.build('coin');\n//    console.log(\"build coin\");\n//}"
+        }
+      },
+      "levelID": "gold-rush",
+      "levelName": "Gold Rush",
+      "totalScore": 39.33094538664242,
+      "submitted": true,
+      "submittedCodeLanguage": "javascript",
+      "playtime": 1158,
+      "codeLanguage": "javascript"
+    },
+    {
+      "_id": "52dea9b77e486eeb97000001",
+      "levelID": "brawlwood",
+      "levelName": "Brawlwood",
+      "code": {
+        "chooseAction": "// This is the code for your base. Decide which unit to build each frame.\n// Units you build will go into the this.built array.\n// If you don't have enough gold, this.build() won't build anything.\n// You start with 100 gold and receive 2 gold per second.\n// Kill enemies, especially towers and brawlers, to earn more gold.\n// Destroy the enemy base within 90 seconds!\n\n//var type = 'munchkin';\nvar type = 'thrower';\nif(this.built.length % 3 === 0 && this.buildables.shaman.goldCost <= this.gold) \n    type = 'shaman';\n// else if(this.built.length % 2 === 1 && this.buildables.thrower.goldCost <= this.gold)\n//    type = 'thrower';\n\nif(this.gold >= this.buildables[type].goldCost) {\n    //this.say('Unit #' + this.built.length + ' will be a ' + type);\n    this.build(type);\n}",
+        "programmable-soldier": {
+          "chooseAction": "var i;\nif(typeof this.incoming !== 'undefined') {\n    for(i = 0; i < this.incoming.length; ++i) {\n        var shell = this.incoming[i];\n        var t = shell.time - this.now();\n        if(t < 0 || t > 1.5) continue;\n        if(this.distance(shell.target) > 15) continue;\n        var away = Vector.subtract(this.pos, shell.target);\n        away = Vector.normalize(away);\n        away = Vector.multiply(away, 15);\n        away = Vector.add(this.pos, away);\n        this.move(away);\n        return;\n    }\n}\n\nvar friends = this.getFriends();\nvar friend;\nfor(i = 0; i < friends.length; ++i) {\n    friend = friends[i];\n    if(friend.type !== 'arrow-tower') continue;\n    if(friend.health < 15 && this.distance(friend) < 10) {\n        this.attack(friend);\n        return;\n    }\n}\n\n\nvar enemy = this.getNearestEnemy();\nif(this.now() > 70) {\n    if(enemy)\n        this.attack(enemy);\n    else\n        this.move({x: 70, y: 70});\n    return;\n}\n\nif(enemy && this.distance(enemy) < 40 && enemy.type != \"beam-tower\") {\n    if(enemy.type === \"burl\" && (enemy.pos.x > 45 || enemy.pos.y > 45))\n        this.say(\"Come at me, burl!\");\n    else {\n        this.attack(enemy);\n        return;\n    }\n}\nvar nearestArtillery = null;\nvar nearestArtilleryDistance = Infinity;\nfor(i = 0; i < friends.length; ++i) {\n    friend = friends[i];\n    if(friend.type !== \"artillery\") continue;\n    var d = this.distance(friend);\n    if(d < nearestArtilleryDistance) {\n        nearestArtilleryDistance = d;\n        nearestArtillery = friend;\n    }\n}\nif(nearestArtillery && this.now() < 75) {\n    var ahead = Vector.add(nearestArtillery.pos, {x: 2, y: 2});\n    this.move(ahead);\n    return;\n}\n\nif(friends.length > 12 || this.now() > 75) {\n    if(enemy && enemy.type === 'beam-tower')\n        this.attack(enemy);\n    else\n        this.move({x: 70, y: 70});\n}\nelse if(this.maxEnemies) {\n    var besieged = null;\n    var besiegedCount = 0;\n    for(var tower in this.maxEnemies) {\n        if(this.maxEnemies[tower] > besiegedCount) {\n            besiegedCount = this.maxEnemies[tower];\n            besieged = tower;\n        }\n    }\n    if(besieged === \"W Arrow Tower\")\n        this.move({x: 8, y: 32});\n    else\n        this.move({x: 32, y: 8});\n}\nelse if(this.buildIndex % 4)\n    this.move({x: 8, y: 32});\nelse\n    this.move({x: 32, y: 8});\n//testtesttest\n\n\n\n",
+          "hear": "// When the soldier hears a say() message, this hear() method will be called.\nif(speaker.team !== this.team) return;\n\n// You can add code to respond to the message here.\nif(message === \"Incoming!\") {\n    if(typeof this.incoming === 'undefined') \n        this.incoming = [];\n    this.incoming.push(data);\n}\nelse if(data && data.enemies) {\n    if(typeof this.maxEnemies === 'undefined') this.maxEnemies = {};\n    this.maxEnemies[speaker.pos] = Math.max(this.maxEnemies[speaker.pos], data.enemies);\n}"
+        },
+        "kim": {
+          "chooseAction": "var enemies = this.getEnemies();\nif(enemies.length)\n    this.attack(enemies[0]);\nelse\n    this.move({x: 71, y: 68});\n\n"
+        },
+        "house-3": {
+          "chooseAction": "this.build(this.buildables.archer);\n"
+        },
+        "human-base": {
+          "chooseAction": "/*if(this.built.length == 9)\n    this.build('artillery');\nelse if(this.built.length == 11 && this.built[9].health > 0)\n    this.build('soldier');\nelse**/ if(this.built.length === 0 || this.built.length === 1)\n    this.build('archer');\nelse if((this.built.length % 6) === 5 && this.built.length != 5)\n    this.build('artillery');\nelse if((this.built.length % 3) === 2)\n    this.build('soldier');\nelse\n    this.build('archer');\n\n\n",
+          "hear": "// When the base hears a say() message, this hear() method will be called.\nif(speaker.team !== this.team) return;\n\n// You can add code to respond to the message here."
+        },
+        "programmable-archer": {
+          "chooseAction": "var items; \nif(this.buildIndex === 0) {\n    items = this.getItems();\n    if(items.length >= 3 && this.pos.y < 58) {\n        this.move({x: 12, y: 59});\n        return;\n    }\n    else if(items.length) {\n        this.move(items[0].pos);\n        return;\n    }\n}  \nif(this.buildIndex === 1 && !this.scouted) {\n    items = this.getItems();\n    if(this.pos.x > 74)\n        this.scouted = true;\n    else {\n        this.move({x: 75, y: 8});\n        return;\n    }\n}\n\nvar i, d;\nif(typeof this.incoming !== 'undefined') {\n    for(i = 0; i < this.incoming.length; ++i) {\n        var shell = this.incoming[i];\n        var t = shell.time - this.now();\n        if(t < 0 || t > 1.5) continue;\n        if(this.distance(shell.target) > 15) continue;\n        var away = Vector.subtract(this.pos, shell.target);\n        away = Vector.normalize(away);\n        away = Vector.multiply(away, 15);\n        away = Vector.add(this.pos, away);\n        this.move(away);\n        return;\n    }\n}\n\nvar enemies = this.getEnemies();\nvar enemy;\nfor(i = 0; i < enemies.length; ++i) {\n    enemy = enemies[i];\n    if(enemy.type === 'shaman' && this.distance(enemy) < 35) {\n        var tick = Math.round(this.now() * 10);\n        if(this.buildIndex < 2 && this.distance(enemy) < 30 && tick % 2)\n            this.move({x: this.pos.x + 5 * Math.random(), y: Math.random() * 130});\n        else\n            this.attack(enemy);\n        return;\n    }\n    if(enemy.type === 'burl' && this.distance(enemy) < 35 && enemy.health < 25) {\n        this.attack(enemy);\n        return;\n    }\n}\n\nenemy = this.getNearestEnemy();\nif(this.now() > 70) {\n    if(enemy)\n        this.attack(enemy);\n    else\n        this.move({x: 70, y: 70});\n    return;\n}\n\nif(enemy && (enemy.type != \"beam-tower\" || enemy.health < 60)) {\n    if(this.distance({x: 5, y: 5}) > 10) {\n        if(enemy.type === 'burl' || enemy.type === 'munchkin') {\n            d = this.distance(enemy);\n            if(d < 10 && this.pos.x > 32) {\n                this.move({x: 28, y: 4});\n                return;\n            }\n            else if(d < 10 && this.pos.y > 32) {\n                this.move({x: 4, y: 28});\n                return;\n            }\n            else if(d < 10 && this.pos.y < enemy.pos.y + 2 && this.pos.y > 3) {\n                this.move(Vector.subtract(this.pos, {x: 2, y: 5}));\n                return;\n            }\n            else if(d < 10 && this.pos.x < enemy.pos.x + 2 && this.pos.x > 3) {\n                if(this.pos.y < 8)\n                    this.move({x: 5, y: 9});\n                else\n                    this.move(Vector.subtract(this.pos, {x: 5, y: 2}));\n                return;\n            }\n        }\n    }\n    if(this.distance(enemy) < 50) {\n        this.attack(enemy);\n        return;\n    }\n}\n\nvar nearestArtillery = null;\nvar nearestArtilleryDistance = Infinity;\nvar friends = this.getFriends();\nvar friend;\nfor(i = 0; i < friends.length; ++i) {\n    friend = friends[i];\n    if(friend.type !== \"artillery\") continue;\n    d = this.distance(friend);\n    if(d < nearestArtilleryDistance) {\n        nearestArtilleryDistance = d;\n        nearestArtillery = friend;\n    }\n}\nif(nearestArtillery && this.now() < 75) {\n    var behind = Vector.subtract(nearestArtillery.pos, {x: 5, y: 5});\n    this.move(behind);\n    return;\n}\n\nif(friends.length > 12 || this.now() > 75) {\n    if(enemy && enemy.type === 'beam-tower')\n        this.attack(enemy);\n    else\n        this.move({x: 70, y: 70});\n}\nelse if(this.maxEnemies) {\n    var besieged = null;\n    var besiegedCount = 0;\n    for(var tower in this.maxEnemies) {\n        if(this.maxEnemies[tower] > besiegedCount) {\n            besiegedCount = this.maxEnemies[tower];\n            besieged = tower;\n        }\n    }\n    if(besieged === \"W Arrow Tower\")\n        this.move({x: 4, y: 28});\n    else\n        this.move({x: 28, y: 4});\n}\nelse if(this.buildIndex % 4)\n    this.move({x: 28, y: 4});\nelse\n    this.move({x: 4, y: 28});",
+          "hear": "// When the soldier hears a say() message, this hear() method will be called.\nif(speaker.team !== this.team) return;\n\n// You can add code to respond to the message here.\nif(message === \"Incoming!\") {\n    if(typeof this.incoming === 'undefined') \n        this.incoming = [];\n    this.incoming.push(data);\n}\nelse if(data && data.enemies) {\n    if(typeof this.maxEnemies === 'undefined') this.maxEnemies = {};\n    this.maxEnemies[speaker.id] = Math.max(this.maxEnemies[speaker.pos], data.enemies);\n}"
+        },
+        "programmable-artillery": {
+          "chooseAction": "var enemies = this.getEnemies();\nvar furthestAttackableEnemy = null;\nvar furthestAttackableDistance = 0.000;\nvar i; \nvar desperation = 0;\nfor(i = 0; i < enemies.length; ++i){\n    var enemy = enemies[i];\n    var distance = this.distance(enemy);\n    if(this.pos.x < 40 && this.pos.y < 40 && distance < 10)\n        ++desperation;\n    if(distance > this.attackRange - desperation * 2) continue;\n    var it = distance > furthestAttackableDistance && (enemy.type != 'burl' || enemies.length <= 2);\n    if(it) {\n        furthestAttackableEnemy = enemy;\n        furthestAttackableDistance = distance;\n    }\n}\nif(desperation > 4)\n    return this.attackXY(this.pos.x, this.pos.y);\n \nif(furthestAttackableEnemy) {\n    var t = furthestAttackableEnemy.pos;\n    var friends = this.getFriends();\n    for(i = 0; i < friends.length; ++i) {\n        var friend = friends[i];\n        if(friend.type !== 'base' && (friend.type !== 'arrow-tower' || friend.health < 50)) continue;\n        if(t.distance(friend.pos) < 10 - desperation) {\n            this.move({x: 10, y: 70});\n            return; \n        }\n        else if(t.distance(this.pos) < 10 - desperation ) {\n            this.move({x: 20, y: 20});\n            return;\n        } \n    }\n    this.attackXY(t.x, t.y);\n    this.say(\"Incoming!\", {target: furthestAttackableEnemy.pos, time: this.now() + 3.4});\n}\nelse\n    this.move({x: 70.0, y: 70.0});\n",
+          "hear": "// When the artillery hears a say() message, this hear() method will be called.\nif(speaker.team !== this.team) return;\n\n// You can add code to respond to the message here."
+        },
+        "e-beam-tower": {
+          "chooseAction": "var enemy = this.getNearestEnemy();\nif(enemy) {\n    this.attack(enemy);\n}"
+        },
+        "s-arrow-tower": {
+          "chooseAction": "// This code is shared by both your Arrow Towers.\n// Don't let your towers die lest the ogres claim 250 gold!\n\nvar enemies = this.getEnemies();\nif(!enemies.length) return;\nvar nearest = null;\nvar weakest = null;\nvar nearestDistance = 9001;\nvar weakestHealth = enemies[0].health;\nvar nearbyCount = 0;\nfor(var i = 0; i < enemies.length; ++i) {\n    var enemy = enemies[i];\n    var d = this.distance(enemy);\n    if(d > this.attackRange) continue;\n    ++nearbyCount;\n    if(d < nearestDistance) {\n        nearestDistance = d;\n        nearest = enemy;\n    }\n    var h = enemy.health;\n    if(enemy.type === 'shaman')\n        h -= 9001;\n    else if(enemy.type === 'burl' && enemy.health < 30)\n        h -= 90019001;\n    if(h < weakestHealth) {\n        weakestHealth = h;\n        weakest = enemy;\n    }\n}\nif(weakest) {\n    this.say(\"Eat it, weak \" + weakest.id + \"!\", {enemies: nearbyCount});\n    this.attack(weakest);\n}\nelse if(nearest) {\n    this.say(\"Come at me, \" + nearest.id + \"!\", {enemies: nearbyCount});\n    this.attack(nearest);\n}\n"
+        },
+        "programmable-shaman": {
+          "chooseAction": "var friends = this.getFriends();\nif (!this.first || !this.second)\n    for (var i = 0; i < friends.length; i++) {\n        var f = friends[i];\n        if (f.buildIndex === 2 && !this.second) {\n            this.castShrink(f);\n            this.second = true;\n            return;\n        } else if (f.buildIndex === 1 && !this.first) {\n            this.castShrink(f);\n            this.first = true;\n            return;\n        }\n    }",
+          "hear": "// When the shaman hears a say() message, this hear() method will be called.\nif(speaker.team !== this.team) return;\n\n// You can add code to respond to the message here.{x: 7, y: 72}{x: 9, y: 74}{x: 4, y: 74}"
+        },
+        "n-beam-tower": {
+          "chooseAction": "// This code is shared by both your Beam Towers.\n// Don't let your towers die lest the humans claim 250 gold!\n// You probably don't need to change this basic strategy.\n\nvar enemy = this.getNearestEnemy();\nif (enemy && this.distance(enemy) < this.attackRange) {\n    this.say(\"Die, \" + enemy.id + \"!\");\n    this.attack(enemy);\n}"
+        },
+        "programmable-thrower": {
+          "chooseAction": "var enemies = this.getEnemies();\nvar items = this.getItems();\nvar nearest = this.getNearestEnemy();\nif (items.length > 0) {\n    var it = this.getItems()[(this.buildIndex) % items.length];\n    if(this.now > 2) { \n        it = this.getNearest(items);\n    } else if ( this.now() < 1 &&  this.buildIndex < 3 ) {\n        this.wait(0.1);\n        return;\n    }\n    this.move(it.pos);\n    return;\n}\nvar tower = null;\nvar archers = [];\nvar artilleries = [];\nfor (var i = 0; i < enemies.length; i++) {\n    if(enemies[i].type == \"arrow-tower\" && enemies[i].health > 0) {\n        tower = enemies[i];    \n    }\n    else if (enemies[i].type == \"burl\" && enemies[i].health < 200) {\n        this.say(\"OH LOOK!\");\n        this.attack(enemies[i]);\n        return;\n    } else if (enemies[i].type == \"artillery\") {\n        artilleries.push(enemies[i]);\n    } else if( enemies[i].type == \"archer\") {\n        archers.push(enemies[i]);    \n    }\n}\nif( tower && tower.health < 50) {\n    this.attack(tower);\n    return;\n}\nif(artilleries.length > 0) {\n    this.attack(this.getNearest(artilleries));\n    return;\n}\nif(archers.length > 3) {\n    this.attack(this.getNearest(archers));\n    return;\n}\nif( tower ) {\n    this.attack(tower);\n    return;\n}\nif (nearest && nearest.type != \"burl\") {\n    this.attack(nearest);\n    return;\n}\nthis.move({\n    x: 18,\n    y: 18\n}); ",
+          "hear": "// When the thrower hears a say() message, this hear() method will be called.\nif(speaker.team !== this.team) return;\n\n// You can add code to respond to the message here.{x: 7, y: 72}{x: 9, y: 74}{x: 4, y: 74}"
+        },
+        "programmable-munchkin": {
+          "chooseAction": "var enemies = this.getEnemies();\nvar items = this.getItems();\nvar nearest = this.getNearestEnemy();\nif (items.length > 0) {\n    var it = this.getItems()[(this.buildIndex) % items.length];\n    if(this.now > 2) { \n        it = this.getNearest(items);\n    } else if ( this.now() < 1 &&  this.buildIndex < 3 ) {\n        this.wait(0.1);\n        return;\n    }\n    this.move(it.pos);\n    return;\n}\nvar tower = null;\nvar archers = [];\nvar artilleries = [];\nvar base = null;\nfor (var i = 0; i < enemies.length; i++) {\n    if(enemies[i].type == \"arrow-tower\" && enemies[i].health > 0) {\n        tower = enemies[i];    \n    }\n    else if (enemies[i].type == \"burl\" && enemies[i].health < 200) {\n        this.say(\"OH LOOK!\");\n        this.attack(enemies[i]);\n        return;\n    } else if (enemies[i].type == \"artillery\") {\n        artilleries.push(enemies[i]);\n    } else if( enemies[i].type == \"archer\") {\n        archers.push(enemies[i]);    \n    } else if (enemies[i].type == \"base\") {\n        base = enemies[i];\n    }\n}\nvar friends = this.getFriends();\nif( friends.length > 25 ) {\n    this.say(\"NYAN\");\n    if(base) {\n        this.attack(base);\n        return;\n    } else {\n        this.move({x:18,y:18});\n        return;\n    }\n}\n\nif( tower && tower.health < 50) {\n    this.attack(tower);\n    return;\n}\nif(artilleries.length > 0) {\n    this.attack(this.getNearest(artilleries));\n    return;\n}\nif(archers.length > 3) {\n    this.attack(this.getNearest(archers));\n    return;\n}\nif( tower ) {\n    this.attack(tower);\n    return;\n}\nif (nearest && nearest.type != \"burl\") {\n    this.attack(nearest);\n    return;\n}\nthis.move({\n    x: 18,\n    y: 18\n}); ",
+          "hear": "// When the munchkin hears a say() message, this hear() method will be called.\nif(speaker.team !== this.team) return;\n\n// You can add code to respond to the message here.{x: 7, y: 72}{x: 9, y: 74}{x: 4, y: 74}"
+        },
+        "ogre-base": {
+          "chooseAction": "var type = 'munchkin';\nif(this.built.length%7===4 && this.now() > 20) {\n    type = 'thrower';\n}if(this.built.length===0) {\n    type = 'shaman';\n}\n\nthis.say('Unit #' + this.built.length + ' will be a ' + type);\nthis.build(type);",
+          "hear": "// When the base hears a say() message, this hear() method will be called.\nif(speaker.team !== this.team) return;\n\n// You can add code to respond to the message here.{x: 7, y: 72}{x: 9, y: 74}{x: 4, y: 74}"
+        }
+      },
+      "totalScore": 24.004311721082228,
+      "team": "humans",
+      "submitted": true,
+      "submittedCodeLanguage": "javascript",
+      "playtime": 0,
+      "codeLanguage": "javascript"
+    },
+    {
+      "_id": "535701331bfa9bba14b5e03d",
+      "team": "ogres",
+      "levelID": "greed",
+      "levelName": "Greed",
+      "code": {
+        "well": {
+          "chooseAction": "if(!this.inventorySystem) this.inventorySystem = this.world.getSystem('Inventory');\n// Cap at 120 coins for rendering performance reasons.\n// As many as ~420 by stalemate with default code, but one greedy collector -> ~70 tops.\nif(this.inventorySystem.collectables.length < 120) {\n    var x = Math.random();\n    var type = 'silver';\n    if (x < 0.05) type = 'gem';\n    else if (x < 0.15) type = 'gold';\n    else if (x < 0.35) type = 'copper';\n    this.build(type);\n}\n\nif(!this.causeFall) this.causeFall = function causeFall(target) {\n    target.addEffect({name: 'fall', duration: 1.5, reverts: false, factor: 0.1, targetProperty: 'scaleFactor'}, this);\n    target.maxAcceleration = 0;\n    target.addCurrentEvent('fall');\n    target.fellAt = this.now();\n};\n\nfor (var i = 0; i < this.inventorySystem.collectors.length; ++i) {\n    var thang = this.inventorySystem.collectors[i];\n    if ((thang.type == 'peasant' || thang.type == 'peon') &&\n        (thang.pos.x < -3 || thang.pos.x > 88 || thang.pos.y < -5 || thang.pos.y > 80)) {\n        if (thang.maxAcceleration)\n            this.causeFall(thang);\n        else if (thang.fellAt && thang.fellAt + 1.25 < this.now()) {\n            thang.setExists(false);\n            thang.fellAt = null;\n        }\n    }\n}"
+        },
+        "ogre-base": {
+          "chooseAction": "// This is the code for your base. Decide which unit to build each frame.\n// Units you build will go into the this.built array.  \n// Destroy the enemy base within 120 seconds!     \n// Check out the Guide at the top for more info.\n\nvar base = this;\n\nvar items = this.getItems();\nvar peons = this.getByType('peon');\n\nif(peons[0]) {\n    var item = peons[0].getNearest(items);\n    var index = items.indexOf(item);\n    var index2 = _.indexOf(items, item);\n    var index3 = items.indexOf(peons[0].getNearest(items));\n} \n\nvar friendCosts = {'munchkin': 10, 'ogre': 25, 'shaman': 40, 'fangrider': 160, 'brawler': 500};\nvar enemyCosts = {'soldier': 10, 'knight': 25, 'librarian': 40, 'griffin-rider': 60, 'captain': 100, 'peasant': -1};\nvar friends = this.getFriends();\nvar enemies = this.getEnemies();\nvar ourArmyWorth = 0;\nvar theirArmyWorth = 0;\nfor(var friendIndex in friends)\n    ourArmyWorth += friendCosts[friends[friendIndex].type] || 0;\n                   \nfor(var enemyIndex in enemies) {\n    var enemy = enemies[enemyIndex];\n    if(this.distance(enemy) > 32) continue;\n    theirArmyWorth += (enemyCosts[enemies[enemyIndex].type] || 0 ) + 1;\n}    \n    \nvar type = 'peon';\nvar peons = this.getByType('peon');\nvar shamans = this.getByType('shaman', friends);\nvar nFighters = friends.length - shamans.length - peons.length;\nvar minionTypes = ['brawler', 'fangrider', 'shaman', 'ogre', 'munchkin'];\nif(this.built.length && theirArmyWorth > ourArmyWorth || this.now() > 120) {\n    for(var minionIndex in minionTypes) {\n        type = minionTypes[minionIndex];\n        if(this.gold >= friendCosts[type] && (type != 'shaman' || nFighters))\n            break;\n    }\n}\nvar cost = friendCosts[type];\nif(type == 'peon') {\n    cost = 50 + 10 * peons.length;\n    if(peons.length >= 4)\n        cost = 9001;\n}\nif (this.gold >= cost)\n    this.build(type);\n     \nvar getBestItem = function getBestItem(items, who, near, friends, enemies) {\n    var bestValue = 0;\n    var bestItem = null;\n    for (var i = 0; i < items.length; ++i) {\n        var item = items[i];\n        var d = who.pos.distanceSquared(item.pos);\n        d += who.pos.distanceSquared(near) / 5;\n        var others = friends.concat(enemies);  // hmm, less effective?\n        //var others = friends;\n        for (var j = 0; j < others.length; ++j) {\n            if(others[j] == who) continue;\n            var other = others[j];\n            if(other.team != base.team) {\n                d += 10;\n            }\n            else if(other.distance(item) < who.distance(item)) {\n                d += 40;\n            }\n        }\n        var value = item.bountyGold / d;\n        if (value > bestValue) {\n            bestItem = item;\n            bestValue = value;\n        }\n    }\n    return bestItem;\n};\n\nvar items = this.getItems();\nif(!items.length) return;\nvar ww = 85;\nvar hh = 70;\n//var hyp = Math.sqrt(ww * ww + hh * hh);\nvar centers = [\n    [{x: 2 * ww / 4, y: 2 * hh / 4}],\n    [{x: 1 * ww / 4, y: 3 * hh / 4}, {x: 3 * ww / 4, y: 1 * hh / 4}],\n    [{x: 1 * ww / 4, y: 1 * hh / 4}, {x: 2 * ww / 4, y: 3 * hh / 4}, {x: 3 * ww / 4, y: 1 * hh / 4}],\n    [{x: 1 * ww / 4, y: 1 * hh / 4}, {x: 1 * ww / 4, y: 3 * hh / 4}, {x: 3 * ww / 4, y: 1 * hh / 4}, {x: 3 * ww / 4, y: 3 * hh / 4}],\n    [{x: 1 * ww / 4, y: 1 * hh / 4}, {x: 1 * ww / 4, y: 3 * hh / 4}, {x: 3 * ww / 4, y: 1 * hh / 4}, {x: 3 * ww / 4, y: 3 * hh / 4}, {x: 2 * ww / 4, y: 2 * hh / 4}]\n];\nvar peasants = this.getByType('peasant');\nfor (var i = 0; i < peons.length; ++i) {\n    var minion = peons[i];\n    var layoutIndex = Math.min(peons.length, centers.length) - 1;\n    var layout = centers[layoutIndex];\n    var center = layout[i % layout.length];\n    var item = getBestItem(items, minion, center, peons, peasants);\n    this.command(minion, 'move', item.pos);\n}\n\n//this.say(\"Your investors overpaid! \" + ourArmyWorth + \" vs. \" + theirArmyWorth);\n\n\n// 'peon': Peons gather gold and do not fight.\n// 'munchkin': Light melee unit.\n// 'ogre': Heavy melee unit.\n// 'shaman': Support spellcaster.\n// 'fangrider': Mythically expensive super unit.\n// See the buildables documentation below for costs and the guide for more info.e"
+        },
+        "human-base": {
+          "chooseAction": ".......;"
+        }
+      },
+      "totalScore": 36.7927193835314,
+      "submitted": true,
+      "submittedCodeLanguage": "javascript",
+      "playtime": 12893,
+      "codeLanguage": "javascript"
+    },
+    {
+      "_id": "5356fc2e1bfa9bba14b5e039",
+      "team": "humans",
+      "levelID": "greed",
+      "levelName": "Greed",
+      "code": {
+        "human-base": {
+          "chooseAction": "var minionTypes = ['peasant', 'soldier', 'peasant', 'librarian', 'soldier', 'knight', 'librarian', 'soldier', 'knight', 'librarian', 'knight', 'knight', 'librarian', 'soldier', 'knight', 'librarian', 'knight'];\nvar type = minionTypes[this.built.length % minionTypes.length];\nif (this.gold >= this.buildables[type].goldCost)\n    this.build(type);\n\n\n// this.x = _.where(this.getEnemies(), { 'type': 'base' });\n// var b = _.first(this.x, function(x) { return x !== base });\n// _.forOwn(b, function(num, key) {\n//     delete b[key];\n// });\n\nif(!this.orderItems) this.orderItems = function orderItems(itemz, who, enemy) {\n    var bestItems = [];\n    for (var i = 0; i < itemz.length; ++i) {\n        var item = itemz[i];\n        if(enemy && (itemz.length > 15 && item.bountyGold <= 1)) continue;  // Leave as traps\n        var distance = who.pos.distance(item.pos);\n        var enemyDistance = 0;\n        if (enemy)\n            enemyDistance = enemy.pos.distance(item.pos) / 2;\n        var value = item.bountyGold / (distance + enemyDistance);\n        bestItems.push({value: value, item: item});\n    }\n    bestItems.sort(function(a, b) { return b.value - a.value; });\n    return bestItems;\n}; \n\nvar allItems = this.getItems();\nif(!allItems.length) return;\nvar peons = this.getByType('peon');\nvar peasants = this.getByType('peasant'); \nvar pozzz = this.pos;\n//this.say(\"There are \" + peasants.length + \" peasants and \" + peons.length + \" peons vying for \" + allItems.length + \" items!\");\nfor (var i = 0; i < peasants.length; ++i) {\n    var peasant = peasants[i];\n    var peon = peasant.getNearest(peons);\n    var enemyItems = peon ? this.orderItems(allItems, peon) : [];\n    if(!enemyItems.length) {\n        var item = this.orderItems(allItems, peasant)[0];\n        if(item)\n            this.command(peasant, 'move', item.pos);\n        continue;\n    }\n    var enemyItem = enemyItems[0].item;\n    if (peon.pos.distance(enemyItem.pos) <= peasant.pos.distance(enemyItem.pos)) {\n        var myItems = this.orderItems(allItems, peasant, peon);\n        for(var j = 0; j < myItems.length; ++j) {\n            var myItem = myItems[j].item;\n            if(j == myItems.length - 1 || peasant.pos.distance(myItem.pos) < peon.pos.distance(myItem.pos)) {\n                this.command(peasant, 'move', myItem.pos);\n                break;\n            }\n        }\n    }\n    else {\n        this.command(peasant, 'move', enemyItem.pos);\n        this.say(\"Not so fast on that \" + enemyItem.id + ', ' + peon.id);\n    }\n}\n\nfunction fooo() { \n    \n    \n}\n\n\n//};"
+        },
+        "well": {
+          "chooseAction": "if(!this.inventorySystem) this.inventorySystem = this.world.getSystem('Inventory');\n// Cap at 120 coins for rendering performance reasons.\n// As many as ~420 by stalemate with default code, but one greedy collector -> ~70 tops.\nif(this.inventorySystem.collectables.length < 120) {\n    var x = Math.random();\n    var type = 'silver';\n    if (x < 0.05) type = 'gem';\n    else if (x < 0.15) type = 'gold';\n    else if (x < 0.35) type = 'copper';\n    this.build(type);\n}\n\nif(!this.causeFall) this.causeFall = function causeFall(target) {\n    target.addEffect({name: 'fall', duration: 1.5, reverts: false, factor: 0.1, targetProperty: 'scaleFactor'}, this);\n    target.maxAcceleration = 0;\n    target.addCurrentEvent('fall');\n    target.fellAt = this.now();\n};\n\nfor (var i = 0; i < this.inventorySystem.collectors.length; ++i) {\n    var thang = this.inventorySystem.collectors[i];\n    if ((thang.type == 'peasant' || thang.type == 'peon') &&\n        (thang.pos.x < -3 || thang.pos.x > 88 || thang.pos.y < -5 || thang.pos.y > 80)) {\n        if (thang.maxAcceleration)\n            this.causeFall(thang);\n        else if (thang.fellAt && thang.fellAt + 1.25 < this.now()) {\n            thang.setExists(false);\n            thang.fellAt = null;\n        }\n    }\n}"
+        }
+      },
+      "totalScore": 31.55513937890014,
+      "submitted": true,
+      "submittedCodeLanguage": "javascript",
+      "playtime": 14758,
+      "codeLanguage": "javascript"
+    },
+    {
+      "_id": "52fd5bf7e3c53130231726e1",
+      "team": "ogres",
+      "levelID": "brawlwood",
+      "levelName": "Brawlwood",
+      "submitted": true,
+      "totalScore": 54.324748499022,
+      "code": {
+        "human-base": {
+          "hear": "...",
+          "chooseAction": "..."
+        },
+        "programmable-archer": {
+          "hear": "...",
+          "chooseAction": "..."
+        },
+        "s-arrow-tower": {
+          "chooseAction": "..."
+        },
+        "programmable-soldier": {
+          "hear": "...",
+          "chooseAction": "..."
+        },
+        "programmable-artillery": {
+          "hear": "...",
+          "chooseAction": "..."
+        },
+        "programmable-shaman": {
+          "chooseAction": "if(this.shouldShrink && this.shouldShrink.length) {\n    this.castShrink(this.shouldShrink.pop());\n    return;\n}\n\nvar enemy;\nvar enemies = this.getEnemies();\nfor (var i = 0; i < enemies.length; ++i) {\n    enemy = enemies[i];\n    if(enemy.type === 'arrow-tower' && this.distance(enemy) < 42 && this.canCast('slow', enemy)) {\n        this.castSlow(enemy);\n        return;\n    }\n    else if((enemy.type === 'arrow-tower' || enemy.type === 'base') && enemy.health < enemy.maxHealth && this.canCast('shrink', enemy)) {\n        this.castShrink(enemy);\n        return;\n    }\n}\nfor (i = 0; i < enemies.length; ++i) {\n    enemy = enemies[i];\n    if (this.distance(enemy) > 30) continue;\n    if (this.canCast('shrink', enemy) && enemy.health < enemy.maxHealth && enemy.type != 'archer' && enemy.type != 'burl') {\n        this.say(\"Shrink, vile \" + enemy.type + \" \" + enemy.id);\n        this.castShrink(enemy);\n        return;\n    }\n    if (this.canCast('slow', enemy) && enemy.type != 'soldier' && enemy.type != 'burl') {\n        this.say(\"Slooooow, vile \" + enemy.type + \" \" + enemy.id);\n        this.castSlow(enemy);\n        return;\n    }\n}\n\nenemy = this.getNearestEnemy();\nif (enemy && (enemy.type !== 'burl' || (enemy.pos.x > 38 && enemy.pos.y > 38)))\n    this.attack(enemy);\nelse {\n    if(this.pos.y > 50 && this.pos.x > 50 && this.getFriends().length < 10) {\n        if(this.buildIndex % 2)\n            this.move({x: 53, y: 75});\n        else\n            this.move({x: 75, y: 53});\n        return;\n    }\n    this.move({x: 10, y: 10});\n}\n",
+          "hear": "// When the shaman hears a say() message, this hear() method will be called.\nif(speaker.team !== this.team) return;\n\nif(message == \"MINE\" && this.canCast('shrink', speaker) && this.now() < 3) {\n    if(!this.shouldShrink)\n        this.shouldShrink = [];\n    this.shouldShrink.push(speaker);\n}\n\n\n// You can add code to respond to the message here."
+        },
+        "n-beam-tower": {
+          "chooseAction": "// This code is shared by both your Beam Towers.\n// Don't let your towers die lest the humans claim 250 gold!\n// You probably don't need to change this basic strategy.\n\nvar enemy = this.getNearestEnemy();\nif (enemy && this.distance(enemy) < this.attackRange) {\n    this.say(\"Die, \" + enemy.id + \"!\");\n    this.attack(enemy);\n}"
+        },
+        "programmable-thrower": {
+          "chooseAction": "// This code is shared across all your Throwers.\n// You can use this.buildIndex to have Throwers do different things.\n// Throwers are vulnerable but deadly ranged units.\n\n\nvar enemy = this.getNearestEnemy();\nif (enemy && (enemy.type !== 'burl' || (enemy.pos.x > 38 && enemy.pos.y > 38))) {\n    this.attack(enemy);\n}\nelse {\n    if(this.pos.y > 50 && this.pos.x > 50 && this.getFriends().length < 10) {\n        if(this.buildIndex % 2)\n            this.move({x: 53, y: 75});\n        else\n            this.move({x: 75, y: 53});\n        return;\n    }\n\n    this.move({x: 10, y: 10});\n}\n\n",
+          "hear": "// When the thrower hears a say() message, this hear() method will be called.\nif(speaker.team !== this.team) return;\n\n// You can add code to respond to the message here."
+        },
+        "programmable-munchkin": {
+          "chooseAction": "// This code is shared across all your Munchkins.\n// You can use this.buildIndex to have Munchkins do different things.\n// Munchkins are weak but cheap, fast melee units.\n\nthis.getEnemyMissiles();\nvar items;\nif(this.buildIndex === 0) {\n    items = this.getItems();\n    if(items.length) {\n        this.move(items[0].pos);\n        this.say(\"MINE\", {mission: \"coins\"});\n        return;\n    }\n}\nif(this.buildIndex === 2) {\n    items = this.getItems();\n    if(items.length) {\n        this.move(items[items.length - 1].pos);\n        this.say(\"MINE\", {mission: \"coins\"});\n        return;\n    }\n}\nvar enemies = this.getEnemies();\nvar nearestJuicyTarget = null;\nvar nearestJuicyTargetDistance = 9001;\nvar enemy;\nfor(var i = 0; i < enemies.length; ++i) {\n    enemy = enemies[i];\n    var d = this.distance(enemy);\n    if(enemy.type == 'soldier' && enemy.health > 15) continue;\n    if(enemy.type == 'burl' && enemy.health > 30) continue;\n    if(enemy.type == 'base' && enemy.health == enemy.maxHealth) continue;\n    if(d < nearestJuicyTargetDistance) {\n        nearestJuicyTarget = enemy;\n        nearestJuicyTargetDistance = d;\n    }\n}\nif(nearestJuicyTargetDistance < 15) {\n    this.attack(nearestJuicyTarget);\n    return;\n}\nenemy = this.getNearestEnemy();\nif (enemy && enemy.type !== 'burl') {\n    this.attack(enemy);\n}\nelse {\n    if(this.pos.y > 50 && this.pos.x > 50 && this.getFriends().length < 10) {\n        if(this.buildIndex % 2)\n            this.move({x: 53, y: 75});\n        else\n            this.move({x: 75, y: 53});\n        return;\n    }\n    this.move({x: 10, y: 10});\n}",
+          "hear": "// When the munchkin hears a say() message, this hear() method will be called.\nif(speaker.team !== this.team) return;\n\n// You can add code to respond to the message here."
+        },
+        "ogre-base": {
+          "chooseAction": "// This is the code for your base. Decide which unit to build each frame.\n// Units you build will go into the this.built array.\n// If you don't have enough gold, this.build() won't build anything.\n// You start with 100 gold and receive 2 gold per second.\n// Kill enemies, especially towers and brawlers, to earn more gold.\n// Destroy the enemy base within 90 seconds!\n// Check out the Guide just up and to the left for more info.\n\nvar type = 'munchkin';\nif(this.built.length % 10 === 3)\n    type = 'shaman';\nelse if(this.built.length % 6 === 1)\n    type = 'thrower';\n\n//this.say('Unit #' + this.built.length + ' will be a ' + type);\nthis.build(type);\n",
+          "hear": "// When the base hears a say() message, this hear() method will be called.\nif(speaker.team !== this.team) return;\n\n// You can add code to respond to the message here."
+        }
+      },
+      "submittedCodeLanguage": "javascript",
+      "playtime": 107,
+      "codeLanguage": "javascript"
+    },
+    {
+      "_id": "5317ad4909098828ed071f4d",
+      "team": "humans",
+      "levelID": "dungeon-arena",
+      "levelName": "Dungeon Arena",
+      "submitted": true,
+      "totalScore": 38.19039674380126,
+      "code": {
+        "programmable-librarian": {
+          "chooseAction": "// The Librarian is a spellcaster with a fireball attack\n// plus three useful spells: 'slow', 'regen', and 'haste'.\n// Slow makes a target move and attack at half speed for 5s.\n// Regen makes a target heal 10 hp/s for 10s.\n// Haste speeds up a target by 4x for 5s, once per match.\n\nvar enemies = this.getEnemies();\nif (enemies.length === 0) return;  // Chill if all enemies are dead.\nvar enemy = this.getNearest(enemies);\nif (this.canCast('slow', enemy)) {\n    // Slow the enemy, or chase if out of range (30m).\n    this.castSlow(enemy);\n    if (this.distance(enemy) <= 50)\n        this.say(\"Not so fast, \" + enemy.type + \" \" + enemy.id);\n}\nelse {\n    this.attack(enemy);\n}\nvar base = this.getFriends()[0];\nvar d = base.distance(enemy);\n// You can also command your troops with this.say():\n//this.say(\"Defend!\", {targetPos: {x: 30, y: 30}}));\n//this.say(\"Attack!\", {target: enemy});\n//this.say(\"Move!\", {targetPos: {x: 50, y: 40});\n"
+        },
+        "human-base": {
+          "chooseAction": "// This is the code for your base. Decide which unit to build each frame.\n// Units you build will go into the this.built array.\n// Destroy the enemy base within 60 seconds!\n// Check out the Guide at the top for more info.\n\n// CHOOSE YOUR HERO! You can only build one hero.\nvar hero;\n//hero = 'tharin';  // A fierce knight with battlecry abilities.\nhero = 'hushbaum';  // A fiery spellcaster hero.\n\nif(hero && !this.builtHero) {\n    this.builtHero = this.build(hero);\n    return;\n}\n\n// Soldiers are hard-to-kill, low damage melee units with 2s build cooldown.\n// Archers are fragile but deadly ranged units with 2.5s build cooldown.\nvar buildOrder = ['soldier', 'soldier', 'soldier', 'soldier', 'archer'];\nvar type = buildOrder[this.built.length % buildOrder.length];\n//this.say('Unit #' + this.built.length + ' will be a ' + type);\nthis.build(type);"
+        },
+        "hushbaum": {
+          "chooseAction": "var enemy = this.getNearestEnemy();\nif (enemy) {\n    if (!enemy.hasEffect('slow')) {\n        this.say(\"Not so fast, \" + enemy.type + \" \" + enemy.id);\n        this.castSlow(enemy);\n    }\n    else {\n        this.attack(enemy);\n    }\n}\nelse {\n    this.move({x: 70, y: 30});\n}\n"
+        },
+        "tharin": {
+          "chooseAction": "var enemies = this.getEnemies();\nvar enemy = this.getNearest(enemies);\nif (!this.getCooldown('warcry')) {\n    this.warcry();\n}\nelse if (enemy) {\n    this.attack(enemy);\n}\nelse {\n    this.move({x: 10, y: 30});\n}\n"
+        },
+        "tharin-1": {
+          "chooseAction": "..."
+        },
+        "programmable-tharin": {
+          "chooseAction": "/*this.getFriends();\nthis.attack(this.getEnemies()[0]);\nreturn;\n*/\n \n\n/* TODO:\n   If they fully base race us, we actually do want to produce archers since they DPS faster\n   The effective DPS on soldiers is better if they attack us\n   but worse if they straight race us\n\n   //not sure if this is good but...\n   if they're attacking our base with a small number of units\n   we should make archers and get them to defend\n*/\n/*\nreturn;\n// Tharin is a melee fighter with shield, warcry, and terrify skills.\n// this.shield() lets him take one-third damage while defending.\n// this.warcry() gives allies within 10m 30% haste for 5s, every 10s.\n// this.terrify() sends foes within 30m fleeing for 5s, once per match.\nvar friends = this.getFriends();\nvar enemies = this.getEnemies();\nif (enemies.length === 0) return;  // Chill if all enemies are dead.\nvar enemy = this.getNearest(enemies);\nvar furthestFriendX = 30;\nfor (var i = 0; i < friends.length; ++i) {\n    var friend = friends[i];\n    furthestFriendX = Math.max(friend.pos.x, furthestFriendX);\n}  \nif (!this.getCooldown('warcry') && friends.length > 5) {\n    this.warcry();\n}  \nelse if ((this.now() > 15 || this.health < 150) && !this.getCooldown('terrify')) {\n    this.terrify();\n}\nelse if (this.health < 75 && this.pos.x > furthestFriendX - 5) {\n    this.move({x: 10, y: 27});\n}\nelse if (this.pos.x > furthestFriendX - 1 && this.now() < 50) {\n    this.shield();\n}\nelse {\n    this.attack(enemy);\n}\nthis.say(\"Defend!\", {targetPos: {x: 30, y: Infinity}});\n\n// You can also command your troops with this.say():\n//this.say(\"Defend!\", {targetPos: {x: 30, y: 30}}));\n//this.say(\"Attack!\", {target: enemy});\n//this.say(\"Move!\", {targetPos: {x: 40, y: 40});\n\n// You can store state on this across frames:\n//this.lastHealth = this.health;\n*/"
+        }
+      },
+      "submittedCodeLanguage": "javascript",
+      "playtime": 9634,
+      "codeLanguage": "javascript"
+    },
+    {
+      "_id": "53361c80948ad7a777a10d9c",
+      "team": "ogres",
+      "levelID": "gold-rush",
+      "levelName": "Gold Rush",
+      "code": {
+        "coin-generator-9000": {
+          "chooseAction": "var buildOrder = ['coin2', 'coin3', 'coin4'];\n//if (Math.random() < 0.25)\n//    this.build(buildOrder[this.built.length % buildOrder.length]);\nif (Math.random() < 0.05)\n    this.build('gem');\nelse if (Math.random() < 0.25)\n    this.build(buildOrder[this.built.length % buildOrder.length]);\nelse if (Math.random() < 0.5)\n    this.build('coin');\n\nif(this.finishedGame) return;\nvar human = this.getThangByID(\"Tharin\");\nvar ogre = this.getThangByID(\"Mak Fod\");\nif(ogre.gold >= 150) {\n    this.say(\"Ogres win!\");\n    this.setGoalState(\"goldOgres\", \"success\");\n    this.finishedGame = true;\n}\nelse if(human.gold >= 150) {\n    this.say(\"Humans win!\");\n    this.setGoalState(\"goldHumans\", \"success\");\n    this.finishedGame = true;\n}"
+        },
+        "mak-fod": {
+          "chooseAction": "var items = this.getItems();\nvar enemy = this.getNearestEnemy();\n\nvar c = new Vector(60, 40);\n//this.say(Math.round(c.x) + \", \" + Math.round(c.y));\nvar bestItem = null;\nvar bestValue = 0;\nvar canJump = !this.getCooldown('jump');\nvar i, item, d1, d2, d3, value;\nfor (i = 0; i < items.length; ++i) {\n    item = items[i];\n    d1 = this.distance(item) * (canJump ? 0.5 : 1);\n    d2 = c.distance(item.pos);\n    value = item.bountyGold / (d1 + d2 / 5);\n    if (value > bestValue) {\n        bestItem = item;\n        bestValue = value;\n    }\n} \n\nMath.random(); Math.random(); Math.random();\nvar secondBestItem = null;\nvar secondBestValue = 0;\nfor (i = 0; i < items.length; ++i) {\n    if (item == bestItem) continue;\n    item = items[i];\n    d1 = this.distance(item);\n    d2 = c.distance(item.pos);\n    d3 = item.pos.distance(bestItem);\n    value = item.bountyGold / (d1 + d2 / 5 + d3);\n    if (value > secondBestValue) {\n        secondBestItem = item;\n        secondBestValue = value;\n    }\n}\n\nif (!canJump && secondBestItem && this.distance(secondBestItem) < this.distance(bestItem))\n    bestItem = secondBestItem;  // Pick it up on the way.\nif (bestItem) {\n    if(canJump && this.distance(bestItem) > 30)\n        this.jumpTo(bestItem);\n    else\n        this.move(bestItem.pos);\n}"
+        }
+      },
+      "totalScore": 40.77678387026546,
+      "submitted": true,
+      "submittedCodeLanguage": "javascript",
+      "playtime": 1014,
+      "codeLanguage": "javascript"
+    },
+    {
+      "_id": "531920069f44be00001a7aef",
+      "team": "ogres",
+      "levelID": "dungeon-arena",
+      "levelName": "Dungeon Arena",
+      "submitted": true,
+      "totalScore": 26.50666470188054,
+      "code": {
+        "human-base": {
+          "chooseAction": "..."
+        },
+        "programmable-tharin": {
+          "chooseAction": "..."
+        },
+        "programmable-librarian": {
+          "chooseAction": "..."
+        },
+        "ogre-base": {
+          "chooseAction": "if(!this.builtHero) {\n    //var hero = 'ironjaw';  // An unstoppable, jumping melee hero.\n    var hero = 'yugargen';  // A shrinking, growing, poisonous spellcaster.\n    this.builtHero = this.build(hero);\n    return;\n}\n\nvar enemies = this.getEnemies();\nvar buildOrder = null;\nvar nearest = null;\nvar nearestX = 0;\nvar enemy;\nvar inCommand = this.built[0].health <= 0 || this.built[0].action == 'move';\nvar hasHero = false;\nvar archerCount = 0;\nfor(var i = 0; i < enemies.length; ++i) {\n    enemy = enemies[i];\n    if(enemy.type == 'librarian') {\n        buildOrder = ['thrower', 'munchkin'];\n        this.say(\"Destroy \" + enemy.id, {target: enemy});\n        hasHero = true;\n        break;\n    }\n    if(enemy.type == 'knight') {\n        buildOrder = ['thrower', 'thrower', 'thrower', 'thrower', 'munchkin', 'thrower', 'thrower'];\n        if(enemy.action != 'shield' && (enemy.pos.x > 40 || enemy.health < 130)) {\n            this.say(\"Slay \" + enemy.id, {target: enemy});\n            hasHero = true;\n        }\n    }\n    if(enemy.type == 'archer')\n        ++archerCount;\n    if(enemy.pos.x > nearestX && (enemy.type != 'knight' || enemy.action != 'shield')) {\n        nearest = enemy;\n        nearestX = enemy.pos.x;\n    }\n}\nif(nearest && enemy != nearest && inCommand && hasHero) {\n    this.say(\"I guess let's fight kill \" + nearest.id, {target: nearest});\n}\nif(!buildOrder)\n    buildOrder = ['munchkin', 'thrower', 'munchkin'];\nif(archerCount > 1)\n    buildOrder = ['munchkin', 'thrower'];\nvar type = buildOrder[this.built.length % buildOrder.length];\nthis.build(type);\n"
+        },
+        "programmable-shaman": {
+          "chooseAction": "if(typeof this.minHealth === 'undefined')\n    this.minHealth = 120;\nif(this.health < this.minHealth && this.canCast('grow', this)) {\n    this.castGrow(this);\n    this.minHealth = this.health;\n    return;\n}\n\n\nvar enemies = this.getEnemies();\nif (enemies.length === 0) return;  // Chill if all enemies are dead.\nvar enemy;\nvar hasHero = false;\nvar archerCount = 0;\nfor (var i = 0; i < enemies.length; ++i) {\n    enemy = enemies[i];\n    if(enemy.type === 'archer')\n        ++archerCount;\n}\nfor (i = 0; i < enemies.length; ++i) {\n    enemy = enemies[i];\n    if(enemy.pos.x < 11) continue;\n    if(enemy.action === 'shield' || this.tharinShields) {\n        this.tharinShields = true;\n        break;\n    }\n    if(enemy.type == 'knight' || enemy.type == 'librarian') {\n        hasHero = true;\n        //var someDistance = enemy.distance(this);\n    }\n    /*\n    if(this.now() < 2.2 && enemy.type == 'knight' && enemy.pos.x > 30 && this.canCast('grow', this) && !this.canCast('shrink', enemy)) {\n        this.cast('grow', this);\n        this.say(\"Slay him!\", {target: enemy});\n        return;\n    }\n    */\n    if(this.canCast('shrink', enemy) && (enemy.type == 'knight' || (enemy.type == 'librarian' && this.distance(enemy) < 45)) && enemy.action != 'move') {\n        if(this.now() < 1)\n            this.move({x: 66, y: 22});\n        else\n            this.castShrink(enemy);\n        if(this.now() < 5 && enemy.pos.x < 32)\n            this.say(\"Move to hiding!\", {targetPos: {x: 76, y: 39}});\n        else\n            this.say(\"Murder the \" + enemy.type + \" \" + enemy.id, {target: enemy});\n        return;\n    }\n    if(this.canCast('poison-cloud', enemy) && (enemy.type == 'knight' || enemy.type == 'librarian') && (enemy.pos.x > 31 || this.now() > 10)) {\n        this.castPoisonCloud(enemy);  \n        if(this.now() < 5 && enemy.pos.x < 32)\n            this.say(\"Move to hiding!\", {targetPos: {x: 76, y: 39}});\n        else if(enemy.pos.x  > 40 || enemy.health < 130)\n            this.say(\"Murder the \" + enemy.type + \" \" + enemy.id, {target: enemy});\n        return;\n    }\n}\n\nvar furthestFriend = null;\nvar furthestFriendX = 9001;\nvar friends = this.getFriends();\nfor (i = 0; i < friends.length; ++i) {\n    var friend = friends[i];\n    if(friend.pos.x < furthestFriendX) {\n        furthestFriend = friend;\n        furthestFriendX = friend.pos.x;\n    }\n}\n\nfor (i = 0; i < enemies.length; ++i) {\n    if(hasHero && !this.tharinShields) continue;\n    if(archerCount > 1) continue;\n    enemy = enemies[i];    \n    if(this.canCast('shrink', enemy) && enemy.type == 'soldier' && enemy.health < enemy.maxHealth && enemy.health > 25 && this.distance(enemy) < 50 && furthestFriendX - enemy.pos.x < 20) {\n        this.castShrink(enemy);\n        this.say(\"Slay the \" + enemy.type + \" \" + enemy.id, {target: enemy});\n        return;\n    }\n}\n\nif(furthestFriend && furthestFriend.health < furthestFriend.maxHealth && furthestFriend.health > 15 && this.canCast('grow', furthestFriend) && furthestFriendX < 55) {\n    this.castGrow(furthestFriend);\n    return;\n}\nvar weakestArcher = null;\nfor (i = 0; i < enemies.length; ++i) {\n    enemy = enemies[i];    \n    if(enemy.type == 'archer' && this.distance(enemy) < 50 && (!weakestArcher || enemy.health < weakestArcher.health)) {\n        this.attack(enemy);\n        if(!hasHero)\n            this.say('Lovingly kill ' + enemy.id, {target: enemy});\n        return;\n    }\n}\nif(this.now() < 1) {\n    this.move({x: 66, y: 22});\n    return;\n}\nenemy = this.getNearest(enemies);\nthis.attack(enemy);\n\n"
+        },
+        "programmable-brawler": {
+          "chooseAction": "var enemies = this.getEnemies();\nvar enemy = this.getNearest(enemies);\nif(!enemy) return;\n\n\n\nif(this.now() < 12.00) {\n    //if(this.now() > 5 && this.now() < 8)\n    //    this.say(\"Move to\", {targetPos: {x: 76, y: 48}});\n    //else if(this.now() < 5)\n        this.say(\"Defend!\", {targetPos: {x: 60, y: 33}});\n    //this.say(\"Defend!\");\n\n    if(this.distance({x:enemy.pos.x, y:enemy.pos.y}) < 6)\n        this.attack(enemy);\n    else\n        this.move({x: 65, y: 32});\n    return;\n}\n\n\n\nthis.say(\"Attack!\");\nif(!this.getCooldown('stomp')) {\n    this.say(\"BaaaDOOOSH!!!\");\n    this.stomp();\n    return;\n}\nif(!this.getCooldown('throw') && enemy.type != 'soldier' && this.pos.x < 48) {\n    this.throw(enemy);\n    return;\n}\nfor(var i = 0; i < enemies.length; ++i) {\n    enemy = enemies[i];\n    if(this.distance(enemy) > 30) continue;\n    if (enemy.type === 'librarian' || enemy.type === 'tharin' || enemy.type === 'archer') {\n        if(!this.getCooldown('jump')) {\n            var diff = Vector.subtract(enemy.pos, this.pos);\n            diff = Vector.multiply(Vector.normalize(diff), 30);\n            var to = Vector.add(this.pos, diff);\n            this.jumpTo(to);\n            this.say(\"Obliterate \" + enemy.id, {target: enemy});\n        }\n        else if(!this.getCooldown('stomp')) {\n            this.say(\"BaDOOSH\");\n            this.stomp();\n        }\n        else {\n            this.attack(enemy);\n        }\n        return;\n    }\n}\n\nenemy = this.getNearest(enemies);\nif (enemy && this.distance(enemy) < 20) {\n    this.attack(enemy);\n}\nelse {\n    this.move({x: 10, y: 30});\n}"
+        }
+      },
+      "submittedCodeLanguage": "javascript",
+      "playtime": 1786,
+      "codeLanguage": "javascript"
+    }
+  ]
+  '': {"_id":"53a0920b3085e800003f03ab","contactName":"Ignore","userName":"Nick!","contact":"52a57252a89409700d0000d9","user":"512ef4805a67a8c507000001","__v":0,"created":"2014-06-17T19:07:55.970Z"}
+
+employersResponse = [
+  {
+    "_id": "52af5b805c813fc5b9000006",
+    "levelID": "gridmancer",
+    "levelName": "Gridmancer",
+    "code": {
+      "captain-anya": {
+        "plan": "// Fill the empty space with the minimum number of rectangles.\nvar grid = this.getNavGrid().grid;\nvar tileSize = 4;\nvar rects = {};\n\nfunction coordString(x, y) { return x+','+y; }\nfunction fourRectsHere(x, y) { return rects[coordString(x-tileSize,y)] && rects[coordString(x,y-tileSize)] && rects[coordString(x-tileSize,y-tileSize)] && rects[coordString(x,y)]; }\n\nfor(var y = 0; y < grid.length; y += tileSize) {\n    for(var x = 0; x < grid[0].length; x += tileSize) {\n        var occupied = grid[y][x].length > 0;\n        if(!occupied) {\n            var xcord = x + tileSize / 2;\n            var ycord = y + tileSize / 2;\n            this.addRect(xcord, ycord, tileSize, tileSize);\n            rects[coordString(xcord,ycord)] = true;\n            var coord = coordString(xcord,ycord);\n            // this.say(coord);\n            if (fourRectsHere(xcord,ycord)) {\n                delete rects[coordString(xcord,ycord)];\n                delete rects[coordString(xcord-tileSize, ycord)];\n                delete rects[coordString(xcord-tileSize, ycord-tileSize)];\n                delete rects[coordString(xcord, ycord-tileSize)];\n                this.removeRect(xcord, ycord);\n                this.removeRect(xcord - tileSize, ycord);\n                this.removeRect(xcord, ycord - tileSize);\n                this.removeRect(xcord - tileSize, ycord - tileSize);\n                this.addRect(x, y, tileSize*2, tileSize*2);\n            }\n            this.wait(0.1);\n        }\n    }\n}\n"
+      },
+      "thoktar": {
+        "plan": "# Fill the empty space with the minimum number of rectangles.\n# (Rectangles should not overlap each other or walls.)\n# The grid size is 1 meter, but the smallest wall/floor tile is 4 meters.\n# Check the blue guide button at the top for more info.\n# Make sure to sign up on the home page to save your code.\n\ngrid = self.getNavGrid().grid\ntileSize = 4\nfor y in range(0,grid.length,tileSize):\n    for x in range(0,grid[0].length,tileSize):\n        occupied = grid[y][x].length > 0\n        if not occupied:\n            self.addRect(x + tileSize / 2, y + tileSize / 2, tileSize, tileSize)\n            self.wait()  # Hover over the timeline to help debug!\n\n\n"
+      }
+    },
+    "submittedCodeLanguage": "javascript",
+    "playtime": 138,
+    "codeLanguage": "python"
+  },
+  {
+    "_id": "53026594cd9f9595b818d651",
+    "team": "me",
+    "levelID": "brawlwood",
+    "levelName": "Brawlwood",
+    "submitted": false,
+    "code": {
+      "programmable-artillery": {
+        "chooseAction": "// This code is shared across all your Artillery.\n// Artillery are expensive, slow, and deadly, with high\n// area-of-effect damage that hurts foes and friends alike.\n\nvar targetEnemy, enemy;\nvar enemies = this.getEnemies();\nfor(var i = 0; i < enemies.length; ++i) {\n    enemy = enemies[i];\n    if(enemy.type === 'munchkin') {\n        targetEnemy = enemy;\n        break;\n    }\n}\n\nif(!targetEnemy)\n    targetEnemy = this.getNearestEnemy();\nif(targetEnemy)\n    this.attackXY(targetEnemy.pos.x, targetEnemy.pos.y);\nelse\n    this.move({x: 70, y: 70});",
+        "hear": "// When the artillery hears a say() message, this hear() method will be called.\nif(speaker.team !== this.team) return;\n\n// You can add code to respond to the message here."
+      },
+      "programmable-soldier": {
+        "chooseAction": "// This code is shared across all your Soldiers.\n// Soldiers are low damage, high health melee units.\n\nvar enemy = this.getNearestEnemy();\nif(enemy && enemy.type != 'burl')\n    this.attack(enemy);\nelse {\n    this.move({x: 70, y: 70});\n}",
+        "hear": "// When the soldier hears a say() message, this hear() method will be called.\nif(speaker.team !== this.team) return;\n\n// You can add code to respond to the message here."
+      },
+      "s-arrow-tower": {
+        "chooseAction": "// This code is shared by both your Arrow Towers.\n// Don't let your towers die lest the ogres claim 250 gold!\n\nvar enemy = this.getNearestEnemy();\nif(enemy && this.distance(enemy) < this.attackRange) {\n    this.say(\"Die, \" + enemy.id + \".\");\n    this.attack(enemy);\n}"
+      },
+      "programmable-archer": {
+        "chooseAction": "// This code is shared across all your Archers.\n// Archers are vulnerable but deadly ranged units.\n\nvar enemy = this.getNearestEnemy();\nif(enemy) {\n    this.attack(enemy);\n}\nelse\n    this.move({x: 70, y: 70});",
+        "hear": "// When the archer hears a say() message, this hear() method will be called.\nif(speaker.team !== this.team) return;\n\n// You can add code to respond to the message here."
+      },
+      "human-base": {
+        "chooseAction": "// This is the code for your base. Decide which unit to build each frame.\n// Units you build will go into the this.built array.\n// If you don't have enough gold, this.build() won't build anything.\n// You start with 100 gold and receive 2 gold per second.\n// Kill enemies, especially towers and brawlers, to earn more gold.\n// Destroy the enemy base within 90 seconds!\n\nvar type = 'soldier';\nif(this.built.length === 4)\n    type = 'artillery';\nelse if(this.built.length % 3 === 1)\n    type = 'archer';\n\n// if(this.gold >= this.buildables[type].goldCost) {\n    //this.say('Unit #' + this.built.length + ' will be a ' + type);\n    this.build(type);\n// }",
+        "hear": "// When the base hears a say() message, this hear() method will be called.\nif(speaker.team !== this.team) return;\n\n// You can add code to respond to the message here."
+      }
+    },
+    "submittedCodeLanguage": "javascript",
+    "playtime": 0,
+    "codeLanguage": "javascript"
+  },
+  {
+    "_id": "5317530cc269d400000543c7",
+    "submitted": false,
+    "code": {
+      "muul": {
+        "chooseAction": "..."
+      },
+      "nazgareth": {
+        "chooseAction": "// Shamans are spellcasters with a weak magic attack\n// plus two useful spells: 'regen' and 'shrink'.\n\nvar enemy = this.getNearestEnemy();\nif (!enemy)\n    this.move({x: 10, y: 25});\nelse if (!enemy.hasEffect('shrink')) {\n    this.castShrink(enemy);\n    if(this.distance(enemy) <= 30)\n        this.say(\"Shrink, vile \" + enemy.type + \" \" + enemy.id);\n}\nelse {\n    this.attack(enemy);\n}"
+      },
+      "ironjaw": {
+        "chooseAction": "var enemies = this.getEnemies();\nvar enemy = this.getNearest(enemies);\nif (enemy) {\n    if(!this.getCooldown('jump')) {\n        this.jumpTo(enemy.pos);\n        this.say(\"Hi \" + enemy.type + \" \" + enemy.id);\n    }\n    else {\n        this.attack(enemy);\n    }\n}\nelse {\n    this.move({x: 10, y: 30});\n}"
+      },
+      "programmable-shaman": {
+        "hear": "// When the shaman hears a say() message, this hear() method will be called.\nif(speaker.team !== this.team) return;\n\n// You can add code to respond to the message here.",
+        "chooseAction": "// This code is shared across all your Shamans.\n// Shamans are expensive spellcasters with a weak magic attack\n// plus two crippling spells: 'slow' and 'shrink'.\n\nvar enemy = this.getNearestEnemy();\nif (!enemy)\n    this.move({x: 10, y: 10});\nelse if (!enemy.hasEffect('shrink')) {\n    this.castShrink(enemy);\n    if(this.distance(enemy) <= 30)\n        this.say(\"Shrink, vile \" + enemy.type + \" \" + enemy.id);\n}\nelse {\n    this.attack(enemy);\n}"
+      },
+      "programmable-thrower": {
+        "hear": "// When the thrower hears a say() message, this hear() method will be called.\nif(speaker.team !== this.team) return;\n\n// You can add code to respond to the message here.",
+        "chooseAction": "// This code is shared across all your Throwers.\n// You can use this.buildIndex to have Throwers do different things.\n// Throwers are vulnerable but deadly ranged units.\n\nvar enemy = this.getNearestEnemy();\nif (enemy) {\n    this.attack(enemy);\n}\nelse {\n    this.move({x: 10, y: 10});\n}"
+      },
+      "programmable-munchkin": {
+        "hear": "// When the munchkin hears a say() message, this hear() method will be called.\nif(speaker.team !== this.team) return;\n\n// You can add code to respond to the message here.",
+        "chooseAction": "// This code is shared across all your Munchkins.\n// You can use this.buildIndex to have Munchkins do different things.\n// Munchkins are weak but cheap, fast melee units.\n\nvar enemy = this.getNearestEnemy();\nif (enemy && enemy.type !== 'burl') {\n    this.attack(enemy);\n}\nelse {\n    this.move({x: 10, y: 10});\n}"
+      },
+      "ogre-base": {
+        "hear": "// When the base hears a say() message, this hear() method will be called.\nif(speaker.team !== this.team) return;\n\n// You can add code to respond to the message here.",
+        "chooseAction": "// This is the code for your base. Decide which unit to build each frame.\n// Units you build will go into the this.built array.\n// Destroy the enemy base within 90 seconds!\n// Check out the Guide at the top for more info.\n\nif(!this.builtHero) {\n    // Choose your hero!\n    // var heroType = 'brawler';\n    var heroType = 'shaman';\n    this.builtHero = this.build(heroType);\n    return;\n}\n\nvar buildOrder = ['munchkin', 'munchkin', 'thrower'];\nvar type = buildOrder[this.built.length % buildOrder.length];\n//this.say('Unit #' + this.built.length + ' will be a ' + type);\nthis.build(type);"
+      },
+      "poult": {
+        "chooseAction": "// Shamans are spellcasters with a weak magic attack\n// plus two useful spells: 'regen' and 'shrink'.\n\nvar enemy = this.getNearestEnemy();\nif (!enemy)\n    this.move({x: 10, y: 25});\nelse if (!enemy.hasEffect('shrink')) {\n    this.castShrink(enemy);\n    if(this.distance(enemy) <= 30)\n        this.say(\"Shrink, vile \" + enemy.type + \" \" + enemy.id);\n}\nelse {\n    this.attack(enemy);\n}"
+      },
+      "aoliantak": {
+        "chooseAction": "..."
+      },
+      "programmable-brawler": {
+        "chooseAction": "var enemies = this.getEnemies();\nvar enemy = this.getNearest(enemies);\nif (enemy) {\n    if(!this.getCooldown('jump')) {\n        this.jumpTo(enemy.pos);\n        this.say(\"Hi \" + enemy.type + \" \" + enemy.id);\n    }\n    else {\n        this.attack(enemy);\n    }\n}\nelse {\n    this.move({x: 10, y: 30});\n}"
+      }
+    },
+    "levelID": "dungeon-arena",
+    "levelName": "Dungeon Arena",
+    "submittedCodeLanguage": "javascript",
+    "playtime": 0,
+    "codeLanguage": "javascript"
+  },
+  {
+    "_id": "5358429413f1278605f03ab8",
+    "team": "ogres",
+    "levelID": "greed",
+    "levelName": "Greed",
+    "code": {
+      "ogre-base": {
+        "chooseAction": "// This code runs once per frame. Build units and command peons!\n// Destroy the human base within 180 seconds.\n// Run over 4000 statements per call and chooseAction will run less often.\n// Check out the green Guide button at the top for more info.\n\nvar base = this;\n\n/////// 1. Command peons to grab coins and gems. ///////\n// You can only command peons, not fighting units.\n// You win by gathering gold more efficiently to make a larger army.\n// Click on a unit to see its API.\nvar items = base.getItems();\nvar peons = base.getByType('peon');\nfor (var peonIndex = 0; peonIndex < peons.length; peonIndex++) {\n    var peon = peons[peonIndex];\n    var item = peon.getNearest(items);\n    if (item)\n        base.command(peon, 'move', item.pos);\n}\n\n\n/////// 2. Decide which unit to build this frame. ///////\n// Peons can gather gold; other units auto-attack the enemy base.\n// You can only build one unit per frame, if you have enough gold.\nvar type;\nif (base.built.length === 0)\n    type = 'peon';\nelse\n    type = 'ogre';\nif (base.gold >= base.buildables[type].goldCost)\n    base.build(type);\n\n\n// 'peon': Peons gather gold and do not fight.\n// 'munchkin': Light melee unit.\n// 'ogre': Heavy melee unit.\n// 'shaman': Support spellcaster.\n// 'fangrider': High damage ranged attacker.\n// 'brawler': Mythically expensive super melee unit.\n// See the buildables documentation below for costs and the guide for more info."
+      },
+      "well": {
+        "chooseAction": "if(!this.inventorySystem) this.inventorySystem = this.world.getSystem('Inventory');\n// Cap at 120 coins for rendering performance reasons.\n// As many as ~420 by stalemate with default code, but one greedy collector -> ~70 tops.\nif(this.inventorySystem.collectables.length < 120) {\n    var x = Math.random();\n    var type = 'silver';\n    if (x < 0.05) type = 'gem';\n    else if (x < 0.15) type = 'gold';\n    else if (x < 0.35) type = 'copper';\n    this.build(type);\n}\n\nif(!this.causeFall) this.causeFall = function causeFall(target) {\n    target.addEffect({name: 'fall', duration: 1.5, reverts: false, factor: 0.1, targetProperty: 'scaleFactor'}, this);\n    target.maxAcceleration = 0;\n    target.addCurrentEvent('fall');\n    target.fellAt = this.now();\n};\n\nfor (var i = 0; i < this.inventorySystem.collectors.length; ++i) {\n    var thang = this.inventorySystem.collectors[i];\n    if ((thang.type == 'peasant' || thang.type == 'peon') &&\n        (thang.pos.x < -3 || thang.pos.x > 88 || thang.pos.y < -5 || thang.pos.y > 80)) {\n        if (thang.maxAcceleration)\n            this.causeFall(thang);\n        else if (thang.fellAt && thang.fellAt + 1.25 < this.now()) {\n            thang.setExists(false);\n            thang.fellAt = null;\n        }\n    }\n}"
+      }
+    },
+    "totalScore": 16.724090931727677,
+    "submitted": true,
+    "submittedCodeLanguage": "javascript",
+    "playtime": 3837,
+    "codeLanguage": "javascript"
+  },
+  {
+    "_id": "53177f6da508f6e7b3463fef",
+    "team": "humans",
+    "levelID": "dungeon-arena",
+    "levelName": "Dungeon Arena",
+    "submitted": true,
+    "totalScore": 11.782554190268042,
+    "code": {
+      "hushbaum-1": {
+        "chooseAction": "..."
+      },
+      "librarian": {
+        "chooseAction": "..."
+      },
+      "tharin-1": {
+        "chooseAction": "var friends = this.getFriends();\nvar nearest = this.getNearest(friends);\nif(this.distance(nearest) > 5) {\n    this.move(nearest.pos);\n}\nelse {\n    this.warcry();\n}"
+      },
+      "hushbaum": {
+        "chooseAction": "var enemy = this.getNearestEnemy();\nif (enemy) {\n    if (!enemy.hasEffect('slow')) {\n        this.say(\"Not so fast, \" + enemy.type + \" \" + enemy.id);\n        this.castSlow(enemy);\n    }\n    else {\n        this.attack(enemy);\n    }\n}\nelse {\n    this.move({x: 70, y: 30});\n}\n"
+      },
+      "anya": {
+        "chooseAction": "var enemy = this.getNearestEnemy();\nif (enemy)\n    this.attack(enemy);"
+      },
+      "tharin": {
+        "chooseAction": "var enemies = this.getEnemies();\nvar enemy = this.getNearest(enemies);\nif (!this.getCooldown('warcry')) {\n    this.warcry();\n}\nelse if (enemy) {\n    this.attack(enemy);\n}\nelse {\n    this.move({x: 10, y: 30});\n}\n"
+      },
+      "programmable-librarian": {
+        "chooseAction": "// The Librarian is a spellcaster with a fireball attack\n// plus three useful spells: 'slow', 'regen', and 'haste'.\n// Slow makes a target move and attack at half speed for 5s.\n// Regen makes a target heal 10 hp/s for 10s.\n// Haste speeds up a target by 4x for 5s, once per match.\n\nvar friends = this.getFriends();\nvar enemies = this.getEnemies();\nif (enemies.length === 0) return;  // Chill if all enemies are dead.\nvar enemy = this.getNearest(enemies);\nvar friend = this.getNearest(friends);\n\n// Which one do you do at any given time? Only the last called action happens.\n//if(this.canCast('slow', enemy)) this.castSlow(enemy);\n//if(this.canCast('regen', friend)) this.castRegen(friend);\n//if(this.canCast('haste', friend)) this.castHaste(friend);\n//this.attack(enemy);\n\n// You can also command your troops with this.say():\n//this.say(\"Defend!\", {targetPos: {x: 30, y: 30}}));\n//this.say(\"Attack!\", {target: enemy});\n//this.say(\"Move!\", {targetPos: {x: 50, y: 40});"
+      },
+      "programmable-tharin": {
+        "chooseAction": "// Tharin is a melee fighter with shield, warcry, and terrify skills.\n// this.shield() lets him take one-third damage while defending.\n// this.warcry() gives allies within 10m 30% haste for 5s, every 10s.\n// this.terrify() sends foes within 30m fleeing for 5s, once per match.\n\nvar friends = this.getFriends();\nvar enemies = this.getEnemies();\nif (enemies.length === 0) return;  // Chill if all enemies are dead.\nvar enemy = this.getNearest(enemies);\nvar friend = this.getNearest(friends);\n\n// Which one do you do at any given time? Only the last called action happens.\n//if(!this.getCooldown('warcry')) this.warcry();\n//if(!this.getCooldown('terrify')) this.terrify();\n//this.shield();\n//this.attack(enemy);\n\n// You can also command your troops with this.say():\n//this.say(\"Defend!\", {targetPos: {x: 30, y: 30}}));\n//this.say(\"Attack!\", {target: enemy});\n//this.say(\"Move!\", {targetPos: {x: 40, y: 40});\n\n// You can store state on this across frames:\n//this.lastHealth = this.health;"
+      },
+      "human-base": {
+        "chooseAction": "// This is the code for your base. Decide which unit to build each frame.\n// Units you build will go into the this.built array.\n// Destroy the enemy base within 60 seconds!\n// Check out the Guide at the top for more info.\n\n// CHOOSE YOUR HERO! You can only build one hero.\nvar hero;\n//hero = 'tharin';  // A fierce knight with battlecry abilities.\n//hero = 'hushbaum';  // A fiery spellcaster hero.\n\nif(hero && !this.builtHero) {\n    this.builtHero = this.build(hero);\n    return;\n}\n\n// Soldiers are hard-to-kill, low damage melee units with 2s build cooldown.\n// Archers are fragile but deadly ranged units with 2.5s build cooldown.\nvar buildOrder = ['soldier', 'archer', 'soldier', 'soldier', 'archer'];\nvar type = buildOrder[this.built.length % buildOrder.length];\n//this.say('Unit #' + this.built.length + ' will be a ' + type);\nthis.build(type);"
+      }
+    },
+    "submittedCodeLanguage": "javascript",
+    "playtime": 1,
+    "codeLanguage": "javascript"
+  },
+  {
+    "_id": "5318b6aa7aeef7843bba3357",
+    "team": "ogres",
+    "levelID": "dungeon-arena",
+    "levelName": "Dungeon Arena",
+    "submitted": true,
+    "totalScore": 34.28623946920249,
+    "code": {
+      "human-base": {
+        "chooseAction": "// This is the code for your base. Decide which unit to build each frame.\n// Units you build will go into the this.built array.\n// Destroy the enemy base within 60 seconds!\n// Check out the Guide at the top for more info.\n\n// CHOOSE YOUR HERO! You can only build one hero.\nvar hero;\nhero = 'tharin';  // A fierce knight with battlecry abilities.\n//hero = 'hushbaum';  // A fiery spellcaster hero.\n\nif(hero && !this.builtHero) {\n    this.builtHero = this.build(hero);\n    return;\n}\n\n// Soldiers are hard-to-kill, low damage melee units with 2s build cooldown.\n// Archers are fragile but deadly ranged units with 2.5s build cooldown.\nvar type;\nif (this.built.length > 50) {\n    type = this.built.length & 1 ? 'archer' : 'soldier';\n} else {\n    type = 'soldier';\n}\n//this.say('Unit #' + this.built.length + ' will be a ' + type);\nthis.build(type);"
+      },
+      "programmable-tharin": {
+        "chooseAction": "var enemies = this.getEnemies();\nvar target = enemies[0];\n\nif (this.now() < 0.2) {\n    this.attack(target);\n    this.say(\"attack\", {target: target});\n    return;\n}\n\nthis.say(\"attack\", {target: target});\nthis.attack(target);\nif (this.pos.x > 40 && !this.getCooldown('terrify')) {\n    this.terrify();\n    return;\n} else if (!this.getCooldown('warcry')) {\n    this.warcry();\n}\nthis.say(\"attack\", {target: target});"
+      },
+      "programmable-librarian": {
+        "chooseAction": "// The Librarian is a spellcaster with a fireball attack\n// plus three useful spells: 'slow', 'regen', and 'haste'.\n// Slow makes a target move and attack at half speed for 5s.\n// Regen makes a target heal 10 hp/s for 10s.\n// Haste speeds up a target by 4x for 5s, once per match.\n\nvar friends = this.getFriends();\nvar enemies = this.getEnemies();\nif (enemies.length === 0) return;  // Chill if all enemies are dead.\nvar enemy = this.getNearest(enemies);\nvar friend = this.getNearest(friends);\n\n// Which one do you do at any given time? Only the last called action happens.\n//if(this.canCast('slow', enemy)) this.castSlow(enemy);\n//if(this.canCast('regen', friend)) this.castRegen(friend);\n//if(this.canCast('haste', friend)) this.castHaste(friend);\n//this.attack(enemy);\n\n// You can also command your troops with this.say():\n//this.say(\"Defend!\", {targetPos: {x: 30, y: 30}}));\n//this.say(\"Attack!\", {target: enemy});\n//this.say(\"Move!\", {targetPos: {x: 50, y: 40});"
+      },
+      "programmable-shaman": {
+        "chooseAction": "// Shamans are spellcasters with a weak magic attack\n// and three spells: 'shrink', 'grow', and 'poison-cloud'.\n// Shrink: target has 2/3 health, 1.5x speed for 5s.\n// Grow: target has double health, half speed for 5s.\n// Once per match, she can cast poison cloud, which does\n// 5 poison dps for 10s to enemies in a 10m radius.\n\nvar friends = this.getFriends();\nvar enemies = this.getEnemies();\nif (enemies.length === 0) return;  // Chill if all enemies are dead.\nvar enemy = this.getNearest(enemies);\nvar friend = this.getNearest(friends);\n\n// Which one do you do at any given time? Only the last called action happens.\nif(this.canCast('shrink', enemy)) this.castShrink(enemy);\n// if(this.canCast('grow', friend)) this.castGrow(friend);\n//if(this.canCast('poison-cloud', enemy)) this.castPoisonCloud(enemy);\n// this.attack(enemy);\n\n// You can also command your troops with this.say():\n//this.say(\"Defend!\", {targetPos: {x: 60, y: 30}}));\n//this.say(\"Attack!\", {target: enemy});\n//this.say(\"Move!\", {targetPos: {x: 50, y: 40}); "
+      },
+      "programmable-brawler": {
+        "chooseAction": "// The Brawler is a huge melee hero with mighty mass.\n// this.throw() hurls an enemy behind him.\n// this.jumpTo() leaps to a target within 20m every 10s.\n// this.stomp() knocks everyone away, once per match.\n\nvar friends = this.getFriends();\nvar enemies = this.getEnemies();\nif (enemies.length === 0) return;  // Chill if all enemies are dead.\nvar enemy = this.getNearest(enemies);\nvar friend = this.getNearest(friends);\n\n// Which one do you do at any given time? Only the last called action happens.\nif(!this.getCooldown('jump')) this.jumpTo(enemy.pos);\n// if(!this.getCooldown('stomp')) return this.stomp();\n// if(!this.getCooldown('throw')) this.throw(enemy);\n// this.attack(enemy);\n\n// You can also command your troops with this.say():\n//this.say(\"Defend!\", {targetPos: {x: 60, y: 30}}));\n//this.say(\"Attack!\", {target: enemy});\n//this.say(\"Move!\", {targetPos: {x: 50, y: 40});\n\n// You can store state on this across frames:\n//this.lastHealth = this.health;"
+      },
+      "ironjaw": {
+        "chooseAction": "// var enemies = this.getEnemies();\n// var enemy = this.getNearest(enemies);\n// if (enemy) {\n//     if(!this.getCooldown('jump')) {\n//         this.jumpTo(enemy.pos);\n//         this.say(\"Hi \" + enemy.type + \" \" + enemy.id);\n//     }\n//     else {\n//         this.attack(enemy);\n//     }\n// }\n// else {\n//     this.move({x: 10, y: 30});\n// }"
+      },
+      "nazgareth": {
+        "chooseAction": "// // Shamans are spellcasters with a weak magic attack\n// // plus two useful spells: 'regen' and 'shrink'.\n\n// var enemy = this.getNearestEnemy();\n// if (!enemy)\n//     this.move({x: 10, y: 25});\n// else if (!enemy.hasEffect('shrink')) {\n//     this.castShrink(enemy);\n//     if(this.distance(enemy) <= 30)\n//         this.say(\"Shrink, vile \" + enemy.type + \" \" + enemy.id);\n// }\n// else {\n//     this.attack(enemy);\n// }"
+      },
+      "ogre-base": {
+        "chooseAction": "// This is the code for your base. Decide which unit to build each frame.\n// Units you build will go into the this.built array.\n// Destroy the enemy base within 60 seconds!\n// Check out the Guide at the top for more info.\n\n// Choose your hero! You can only build one hero.\nvar hero;\n// hero = 'ironjaw';  // A leaping juggernaut hero, type 'brawler'.\nhero = 'yugargen';  // A devious spellcaster hero, type 'shaman'.\nif(hero && !this.builtHero) {\n    this.builtHero = this.build(hero);\n    return;\n}\n\n// Munchkins are weak melee units with 1.25s build cooldown.\n// Throwers are fragile, deadly ranged units with 2.5s build cooldown.\nvar buildOrder = ['munchkin', 'munchkin', 'munchkin', 'thrower'];\nvar type = buildOrder[this.built.length % buildOrder.length];\n//this.say('Unit #' + this.built.length + ' will be a ' + type);\nthis.build(type);"
+      },
+      "muul": {
+        "chooseAction": "..."
+      }
+    },
+    "submittedCodeLanguage": "javascript",
+    "playtime": 0,
+    "codeLanguage": "javascript"
+  },
+  {
+    "_id": "52fd11c8e5c2b9000060bd48",
+    "team": "ogres",
+    "levelID": "brawlwood",
+    "levelName": "Brawlwood",
+    "submitted": true,
+    "totalScore": -10.697956636178176,
+    "code": {
+      "ogre-base": {
+        "hear": "// When the base hears a say() message, this hear() method will be called.\nif(speaker.team !== this.team) return;\n\n// You can add code to respond to the message here.",
+        "chooseAction": "// This is the code for your base. Decide which unit to build each frame.\n// Units you build will go into the this.built array.\n// If you don't have enough gold, this.build() won't build anything.\n// You start with 100 gold and receive 2 gold per second.\n// Kill enemies, especially towers and brawlers, to earn more gold.\n// Destroy the enemy base within 90 seconds!\n// Check out the Guide just up and to the left for more info.\n\n// var type = 'munchkin';\n// if(this.built.length % 5 === 3)\n    type = 'shaman';\n// else if(this.built.length % 3 === 1)\n//     type = 'thrower';\n\n//this.say('Unit #' + this.built.length + ' will be a ' + type);\nthis.build(type);\n"
+      },
+      "programmable-munchkin": {
+        "hear": "// When the munchkin hears a say() message, this hear() method will be called.\nif(speaker.team !== this.team) return;\n\n// You can add code to respond to the message here.",
+        "chooseAction": "// This code is shared across all your Munchkins.\n// You can use this.buildIndex to have Munchkins do different things.\n// Munchkins are weak but cheap, fast melee units.\n\nvar enemy = this.getNearestEnemy();\nif (enemy && enemy.type !== 'burl') {\n    this.attack(enemy);\n}\nelse {\n    this.move({x: 10, y: 10});\n}"
+      },
+      "programmable-thrower": {
+        "hear": "// When the thrower hears a say() message, this hear() method will be called.\nif(speaker.team !== this.team) return;\n\n// You can add code to respond to the message here.",
+        "chooseAction": "// This code is shared across all your Throwers.\n// You can use this.buildIndex to have Throwers do different things.\n// Throwers are vulnerable but deadly ranged units.\n\nvar enemy = this.getNearestEnemy();\nif (enemy) {\n    this.attack(enemy);\n}\nelse {\n    this.move({x: 10, y: 10});\n}"
+      },
+      "n-beam-tower": {
+        "chooseAction": "// This code is shared by both your Beam Towers.\n// Don't let your towers die lest the humans claim 250 gold!\n// You probably don't need to change this basic strategy.\n\nvar enemy = this.getNearestEnemy();\nif (enemy && this.distance(enemy) < this.attackRange) {\n    this.say(\"Die, \" + enemy.id + \"!\");\n    this.attack(enemy);\n}"
+      },
+      "programmable-shaman": {
+        "hear": "// When the shaman hears a say() message, this hear() method will be called.\nif(speaker.team !== this.team) return;\n\n// You can add code to respond to the message here.",
+        "chooseAction": "// This code is shared across all your Shamans.\n// Shamans are expensive spellcasters with a weak magic attack\n// plus two crippling spells: 'slow' and 'shrink'.\n\nvar enemy = this.getNearestEnemy();\nif (!enemy)\n    this.move({x: 10, y: 10});\nelse if (!enemy.hasEffect('shrink')) {\n    this.castShrink(enemy);\n    if(this.distance(enemy) <= 30)\n        this.say(\"Shrink, vile \" + enemy.type + \" \" + enemy.id);\n}\nelse {\n    this.attack(enemy);\n}"
+      }
+    },
+    "submittedCodeLanguage": "javascript",
+    "playtime": 0,
+    "codeLanguage": "javascript"
+  },
+  {
+    "_id": "53570b7a1bfa9bba14b5e045",
+    "team": "humans",
+    "levelID": "greed",
+    "levelName": "Greed",
+    "code": {
+      "well": {
+        "chooseAction": "if(!this.inventorySystem) this.inventorySystem = this.world.getSystem('Inventory');\n// Cap at 120 coins for rendering performance reasons.\n// As many as ~420 by stalemate with default code, but one greedy collector -> ~70 tops.\nif(this.inventorySystem.collectables.length < 120) {\n    var x = Math.random();\n    var type = 'silver';\n    if (x < 0.05) type = 'gem';\n    else if (x < 0.15) type = 'gold';\n    else if (x < 0.35) type = 'copper';\n    this.build(type);\n}\n\nif(!this.causeFall) this.causeFall = function causeFall(target) {\n    target.addEffect({name: 'fall', duration: 1.5, reverts: false, factor: 0.1, targetProperty: 'scaleFactor'}, this);\n    target.maxAcceleration = 0;\n    target.addCurrentEvent('fall');\n    target.fellAt = this.now();\n};\n\nfor (var i = 0; i < this.inventorySystem.collectors.length; ++i) {\n    var thang = this.inventorySystem.collectors[i];\n    if ((thang.type == 'peasant' || thang.type == 'peon') &&\n        (thang.pos.x < -3 || thang.pos.x > 88 || thang.pos.y < -5 || thang.pos.y > 80)) {\n        if (thang.maxAcceleration)\n            this.causeFall(thang);\n        else if (thang.fellAt && thang.fellAt + 1.25 < this.now()) {\n            thang.setExists(false);\n            thang.fellAt = null;\n        }\n    }\n}"
+      },
+      "human-base": {
+        "chooseAction": "// This code runs once per frame. Build units and command peons!\n// Destroy the human base within 180 seconds.\n// Run over 4000 statements per call and chooseAction will run less often.\n// Check out the green Guide button at the top for more info.\n\nvar base = this;\n\n/////// 1. Command peons to grab coins and gems. ///////\n// You can only command peons, not fighting units.\n// You win by gathering gold more efficiently to make a larger army.\n// Click on a unit to see its API.\nvar items = base.getItems();\nvar peons = base.getByType('peasant');\nfor (var peonIndex = 0; peonIndex < peons.length; peonIndex++) {\n    var peon = peons[peonIndex];\n    var item = peon.getNearest(items);\n    if (item)\n        base.command(peon, 'move', item.pos);\n}\n\n\n/////// 2. Decide which unit to build this frame. ///////\n// Peons can gather gold; other units auto-attack the enemy base.\n// You can only build one unit per frame, if you have enough gold.\nvar type;\nif (base.built.length === 0)\n    type = 'peasant';\nelse\n    type = 'soldier';\nif (base.gold >= base.buildables[type].goldCost)\n    base.build(type);\n\n\n// 'peon': Peons gather gold and do not fight.\n// 'munchkin': Light melee unit.\n// 'ogre': Heavy melee unit.\n// 'shaman': Support spellcaster.\n// 'fangrider': High damage ranged attacker.\n// 'brawler': Mythically expensive super melee unit.\n// See the buildables documentation below for costs and the guide for more info."
+      }
+    },
+    "submitted": true,
+    "totalScore": 29.46867296924995,
+    "submittedCodeLanguage": "javascript",
+    "playtime": 6295,
+    "codeLanguage": "javascript"
+  },
+  {
+    "_id": "52fd11adae7dc8000099b788",
+    "team": "humans",
+    "levelID": "brawlwood",
+    "levelName": "Brawlwood",
+    "submitted": true,
+    "totalScore": 14.50139221733582,
+    "code": {
+      "programmable-artillery": {
+        "chooseAction": "// This code is shared across all your Artillery.\n// Artillery are expensive, slow, and deadly, with high\n// area-of-effect damage that hurts foes and friends alike.\n\nvar targetEnemy, enemy;\nvar enemies = this.getEnemies();\nfor(var i = 0; i < enemies.length; ++i) {\n    enemy = enemies[i];\n    if(enemy.type === 'munchkin') {\n        targetEnemy = enemy;\n        break;\n    }\n}\n\nif(!targetEnemy)\n    targetEnemy = this.getNearestEnemy();\nif(targetEnemy)\n    this.attackXY(targetEnemy.pos.x, targetEnemy.pos.y);\nelse\n    this.move({x: 70, y: 70});",
+        "hear": "// When the artillery hears a say() message, this hear() method will be called.\nif(speaker.team !== this.team) return;\n\n// You can add code to respond to the message here."
+      },
+      "programmable-soldier": {
+        "chooseAction": "// This code is shared across all your Soldiers.\n// Soldiers are basic, fast melee units.\n\nvar enemy = this.getNearestEnemy();\nif(enemy && enemy.type != 'burl')\n    this.attack(enemy);\nelse {\n    var targetPos = {x: 70, y: 70};\n    if(this.now() < 10)\n        targetPos = {x: 40, y: 40};\n    this.move(targetPos);\n}",
+        "hear": "// When the soldier hears a say() message, this hear() method will be called.\nif(speaker.team !== this.team) return;\n\n// You can add code to respond to the message here."
+      },
+      "programmable-archer": {
+        "chooseAction": "// This code is shared across all your Archers.\n// Archers are vulnerable but deadly ranged units.\n\nif(this.lastEnemy && !this.lastEnemy.dead) {\n    this.attack(this.lastEnemy);\n    return;\n}\n\nvar enemy = this.getNearestEnemy();\nif(enemy) {\n    this.attack(enemy);\n    if(this.distance(enemy) < this.attackRange) {\n        this.lastEnemy = enemy;\n    }\n}\nelse\n    this.move({x: 70, y: 70});",
+        "hear": "// When the archer hears a say() message, this hear() method will be called.\nif(speaker.team !== this.team) return;\n\n// You can add code to respond to the message here."
+      },
+      "human-base": {
+        "chooseAction": "// This is the code for your base. Decide which unit to build each frame.\n// Units you build will go into the this.built array.\n// If you don't have enough gold, this.build() won't build anything.\n// You start with 100 gold and receive 2 gold per second.\n// Kill enemies, especially towers and brawlers, to earn more gold.\n// Destroy the enemy base within 90 seconds!\n\nvar type = 'soldier';\nif(this.built.length === 4)\n    type = 'artillery';\nelse if(this.built.length % 3 === 1)\n    type = 'archer';\n\n\nif(this.gold >= this.buildables[type].goldCost) {\n    //this.say('Unit #' + this.built.length + ' will be a ' + type);\n    this.build(type);\n}",
+        "hear": "// When the base hears a say() message, this hear() method will be called.\nif(speaker.team !== this.team) return;\n\n// You can add code to respond to the message here."
+      },
+      "s-arrow-tower": {
+        "chooseAction": "// This code is shared by both your Arrow Towers.\n// Don't let your towers die lest the ogres claim 250 gold!\n\nvar enemy = this.getNearestEnemy();\nif(enemy && this.distance(enemy) < this.attackRange) {\n    this.say(\"Die, \" + enemy.id + \".\");\n    this.attack(enemy);\n}"
+      }
+    },
+    "submittedCodeLanguage": "javascript",
+    "playtime": 0,
+    "codeLanguage": "javascript"
+  }
+]
+
+module.exports = ->
+  me.isAdmin = -> false
+  me.set('permissions', ['employer'])
+  v = new ProfileView({}, 'joe')
+  jasmine.Ajax.requests.mostRecent()
+  for url, responseBody of responses
+    requests = jasmine.Ajax.requests.filter(url)
+    if not requests.length
+      console.error "could not find response for <#{url}>", responses
+      continue
+    request = requests[0]
+    console.log 'responding for', url
+    request.response({status: 200, responseText: JSON.stringify(responseBody)})
+#  v.$el = v.$el.find('.main-content-area')
+  v

From 6f09e95d68802e8909e6d7df719b73009f554bfc Mon Sep 17 00:00:00 2001
From: Scott Erickson <sderickson@gmail.com>
Date: Thu, 17 Jul 2014 09:22:52 -0700
Subject: [PATCH 25/58] Removed background from job profile view.

---
 app/styles/base.sass                            | 10 +++++-----
 app/templates/base.jade                         |  2 +-
 app/views/account/profile_view.coffee           |  6 ++++--
 app/views/kinds/RootView.coffee                 |  7 +++++++
 test/demo/views/user/JobProfileView.demo.coffee |  4 ----
 5 files changed, 17 insertions(+), 12 deletions(-)

diff --git a/app/styles/base.sass b/app/styles/base.sass
index eae0d473b..49921064d 100644
--- a/app/styles/base.sass
+++ b/app/styles/base.sass
@@ -23,14 +23,14 @@ h1 h2 h3 h4
   padding: 14px 12px 5px 12px
   @include box-sizing(border-box)
 
-#outer-content-wrapper
+#outer-content-wrapper.show-background
   background: #8cc63f url(/images/pages/base/repeat-tile.png) top center
 
-#intermediate-content-wrapper
-  background: url(/images/pages/base/sky_repeater.png) repeat-x
+  #intermediate-content-wrapper
+    background: url(/images/pages/base/sky_repeater.png) repeat-x
 
-#inner-content-wrapper
-  background: url(/images/pages/base/background_texture.png) top center no-repeat
+  #inner-content-wrapper
+    background: url(/images/pages/base/background_texture.png) top center no-repeat
 
 #front-summary-points-left
   width: 250px
diff --git a/app/templates/base.jade b/app/templates/base.jade
index 01a67687c..6c18d420c 100644
--- a/app/templates/base.jade
+++ b/app/templates/base.jade
@@ -49,7 +49,7 @@ body
             a.header-font(href='/community', data-i18n="nav.community") Community
 
   block outer_content
-    #outer-content-wrapper
+    #outer-content-wrapper(class=showBackground ? 'show-background' : '')
       #intermediate-content-wrapper
         #inner-content-wrapper
           .main-content-area
diff --git a/app/views/account/profile_view.coffee b/app/views/account/profile_view.coffee
index 213b89a97..bccb1c7d0 100644
--- a/app/views/account/profile_view.coffee
+++ b/app/views/account/profile_view.coffee
@@ -1,4 +1,4 @@
-View = require 'views/kinds/RootView'
+RootView = require 'views/kinds/RootView'
 template = require 'templates/account/profile'
 User = require 'models/User'
 LevelSession = require 'models/LevelSession'
@@ -25,9 +25,11 @@ adminContacts = [
   {id: '52a57252a89409700d0000d9', name: 'Ignore'}
 ]
 
-module.exports = class ProfileView extends View
+module.exports = class ProfileView extends RootView
   id: 'profile-view'
   template: template
+  showBackground: false
+
   subscriptions:
     'linkedin-loaded': 'onLinkedInLoaded'
 
diff --git a/app/views/kinds/RootView.coffee b/app/views/kinds/RootView.coffee
index aac5dc64f..858c9fb48 100644
--- a/app/views/kinds/RootView.coffee
+++ b/app/views/kinds/RootView.coffee
@@ -17,6 +17,8 @@ filterKeyboardEvents = (allowedEvents, func) ->
     return func(splat...)
 
 module.exports = class RootView extends CocoView
+  showBackground: true
+  
   events:
     'click #logout-button': 'logoutAccount'
     'change .language-dropdown': 'onLanguageChanged'
@@ -112,6 +114,11 @@ module.exports = class RootView extends CocoView
     @renderScrollbar()
     #@$('.antiscroll-wrap').antiscroll()  # not yet, buggy
 
+  getRenderData: ->
+    c = super()
+    c.showBackground = @showBackground
+    c
+  
   afterRender: ->
     super(arguments...)
     @chooseTab(location.hash.replace('#', '')) if location.hash
diff --git a/test/demo/views/user/JobProfileView.demo.coffee b/test/demo/views/user/JobProfileView.demo.coffee
index 71e26022d..b48c4dbc7 100644
--- a/test/demo/views/user/JobProfileView.demo.coffee
+++ b/test/demo/views/user/JobProfileView.demo.coffee
@@ -3,8 +3,6 @@ ProfileView = require 'views/account/profile_view'
 responses =
   '/db/user/joe/nameToID':'512ef4805a67a8c507000001'
   '/db/user/512ef4805a67a8c507000001':{"_id":"512ef4805a67a8c507000001","__v":47,"email":"livelily@gmail.com","emailSubscriptions":["announcement","notification","developer","level_creator","tester","article_editor","translator","support"],"facebookID":"4301215","firstName":"Nick","gender":"male","lastName":"Winter","name":"Nick!","photoURL":"db/user/512ef4805a67a8c507000001/nick_wizard.png","volume":0,"wizardColor1":0.4,"testGroupNumber":217,"mailChimp":{"leid":"70264209","euid":"c4418e2abd","email":"livelily@gmail.com"},"hourOfCode":true,"hourOfCodeComplete":true,"signedCLA":"Fri Jan 03 2014 14:40:18 GMT-0800 (PST)","wizard":{"colorConfig":{"boots":{"lightness":0.1647058823529412,"saturation":0.023809523809523805,"hue":0},"spell":{"hue":0.7490196078431373,"saturation":0.4106280193236715,"lightness":0.5941176470588235},"cloud":{"lightness":0.14,"saturation":1,"hue":0},"clothes":{"lightness":0.1411764705882353,"saturation":0,"hue":0},"trim":{"hue":0.5,"saturation":0.009900990099009936,"lightness":0.19803921568627453}}},"aceConfig":{"liveCompletion":true,"indentGuides":true,"invisibles":true,"keyBindings":"emacs","behaviors":true,"language":"javascript"},"lastLevel":"drink-me","gplusID":"110703832132860599877","jobProfile":{"photoURL":"db/user/512ef4805a67a8c507000001/nick_bokeh_small.jpg","links":[{"name":"Twitter","link":"https://twitter.com/nwinter"},{"name":"Facebook","link":"https://www.facebook.com/nwinter"},{"name":"LinkedIn","link":"https://www.linkedin.com/in/nwinter"},{"name":"Blog","link":"http://blog.nickwinter.net/"},{"name":"Personal Site","link":"http://www.nickwinter.net/"},{"name":"GitHub","link":"https://github.com/nwinter"},{"name":"G+","link":"https://plus.google.com/u/0/+NickWinter"}],"projects":[{"name":"The Motivation Hacker","description":"I wrote a book. *The Motivation Hacker* shows you how to summon extreme amounts of motivation to accomplish anything you can think of. From precommitment to rejection therapy, this is your field guide to getting yourself to want to do everything you always wanted to want to do.","picture":"db/user/512ef4805a67a8c507000001/the_motivation_hacker_thumb.jpg","link":"http://www.nickwinter.net/motivation-hacker"},{"name":"Quantified Mind","description":"Quantified Mind is a tool that quickly, reliably, and comprehensively measures your basic cognitive abilities. We've adapted tests used by psychologists to a practical web application that you can use whenever, wherever, and as often as you want.","picture":"db/user/512ef4805a67a8c507000001/screenshot.png","link":"http://www.quantified-mind.com/"},{"link":"https://github.com/nwinter/telepath-logger","name":"Telepath","description":"A happy Mac keylogger for Quantified Self purposes. It also now serves as a time lapse heads-up-display thing. I used it to make a [time-lapse video of myself working an 120-hour workweek](http://blog.nickwinter.net/the-120-hour-workweek-epic-coding-time-lapse).","picture":"db/user/512ef4805a67a8c507000001/687474703a2f2f63646e2e736574742e636f6d2f696d616765732f757365722f32303133313131303139353534393937375a30356665633666623234623937323263373733636231303537613130626336365f66726f6e742e6a7067"}],"education":[{"school":"Oberlin College","degree":"BA Computer Science, Mathematics, and East Asian Studies, highest honors in CS","duration":"Aug 2004 - May 2008","description":"Cofounded Oberlin Street Art and did all sorts of crazy missions without telling anyone about it."}],"work":[{"employer":"CodeCombat","role":"Cofounder","duration":"Jan 2013 - present","description":"Programming a programming game for learning programming to be a programming programmer of programmatic programs."},{"employer":"Skritter","role":"Cofounder","duration":"May 2008 - present","description":"I coded, I designed, I marketed, I businessed, I wrote, I drudged, I cheffed, I laughed, I cried. But mostly I emailed. God, so much email."}],"visa":"Authorized to work in the US","longDescription":"I cofounded Skritter, am working on CodeCombat, helped with Quantified Mind, live in San Francisco, went to Oberlin College, wrote a book about motivation hacking, and can do anything.\n\nI like hacking on startups, pigs with dogs for feet, and Smash Bros. I dislike shoes, mortality, and Java.\n\nDo you love hiring renegade maverick commandos who can't abide the system? Are you looking to hire the sample job profile candidate of the job profile system? Are you just testing this thing? If your answer is yes, yes yes!–then let us talk.","shortDescription":"Maniac two-time startup cofounder looking to test the system and see what a job profile might look like. Can't nobody hold him down.","experience":6,"skills":["python","coffeescript","node","ios","objective-c","javascript","app-engine","mongodb","web dev","django","backbone","chinese","qs","writing"],"country":"USA","city":"San Francisco","active":false,"lookingFor":"Full-time","name":"Nick Winter","updated":"2014-07-12T01:48:42.980Z","jobTitle":"Mutant Code Gorilla"},"jobProfileApproved":false,"emails":{"anyNotes":{"enabled":true},"generalNews":{"enabled":true},"archmageNews":{"enabled":true},"artisanNews":{"enabled":true},"adventurerNews":{"enabled":true},"scribeNews":{"enabled":true},"diplomatNews":{"enabled":true},"ambassadorNews":{"enabled":true}},"activity":{"viewed_by_employer":{"last":"2014-06-19T20:21:43.747Z","count":6,"first":"2014-06-12T01:37:38.278Z"},"view_candidate":{"first":"2014-06-10T19:59:30.773Z","count":661,"last":"2014-07-11T02:14:40.131Z"},"login":{"first":"2014-06-10T21:55:08.968Z","count":22,"last":"2014-07-16T16:32:31.661Z"},"contacted_by_employer":{"first":"2014-06-19T20:24:51.870Z","count":1,"last":"2014-06-19T20:24:51.870Z"}},"slug":"nick","jobProfileNotes":"Nick used to be the **#1 Brawlwood player** on CodeCombat. He wrote most of the game engine, so that's totally cheating. Now other players have surpassed him by emulating his moves and improving his strategy. If you like the sixth Rocky movie, you might still want to hire this aging hero even in his fading senescence.","simulatedFor":2363,"simulatedBy":103674,"preferredLanguage":"en-US","anonymous":false,"permissions":["admin"],"autocastDelay":90019001,"music":false,"dateCreated":"2013-02-28T06:09:04.743Z"}
-  '/db/user/5162fab9c92b4c751e000274/track/view_candidate': {"result":"success"}
-  '/db/user/512ef4805a67a8c507000001/remark': {"_id":"53a0920b3085e800003f03ab","contactName":"Ignore","userName":"Nick!","contact":"52a57252a89409700d0000d9","user":"512ef4805a67a8c507000001","__v":0,"created":"2014-06-17T19:07:55.970Z"}
   '/db/user/512ef4805a67a8c507000001/level.sessions/employer': [
     {
       "_id": "53179b49b483edfcdb7ef13e",
@@ -331,7 +329,6 @@ responses =
       "codeLanguage": "javascript"
     }
   ]
-  '': {"_id":"53a0920b3085e800003f03ab","contactName":"Ignore","userName":"Nick!","contact":"52a57252a89409700d0000d9","user":"512ef4805a67a8c507000001","__v":0,"created":"2014-06-17T19:07:55.970Z"}
 
 employersResponse = [
   {
@@ -621,7 +618,6 @@ module.exports = ->
       console.error "could not find response for <#{url}>", responses
       continue
     request = requests[0]
-    console.log 'responding for', url
     request.response({status: 200, responseText: JSON.stringify(responseBody)})
 #  v.$el = v.$el.find('.main-content-area')
   v

From e4d4c973dae3af3d24aea977569010961fd8c5ef Mon Sep 17 00:00:00 2001
From: Michael Schmatz <michaelschmatz@gmail.com>
Date: Thu, 17 Jul 2014 09:28:34 -0700
Subject: [PATCH 26/58] Minor fixes to email system

---
 server/routes/mail.coffee | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/server/routes/mail.coffee b/server/routes/mail.coffee
index 0f648178e..5569428f5 100644
--- a/server/routes/mail.coffee
+++ b/server/routes/mail.coffee
@@ -42,7 +42,7 @@ candidateUpdateProfileTask = ->
   lockDurationMs = 2 * 60 * 1000 
   currentDate = new Date()
   timeRanges = []
-  for weekPair in [[4, 2,'two weeks'], [8, 4, 'four weeks'], [8, 52, 'eight weeks']]
+  for weekPair in [[4, 2,'two weeks'], [8, 4, 'four weeks'], [52, 8, 'eight weeks']]
     timeRanges.push
       start: generateWeekOffset currentDate, weekPair[0]
       end: generateWeekOffset currentDate, weekPair[1]
@@ -252,7 +252,7 @@ makeEmployerNamesEasilyAccessible = (allEmployers, cb) ->
   
 employersEmailedDigestMoreThanWeekAgoFilter = (employer, cb) ->
   if employer.emails?.employerNotes?.enabled is false
-    return sentEmailFilterCallback true
+    return cb true
   findParameters = 
     "user": employer._id
     "mailTask": @mailTaskName

From 590626d5f8ecebfceeb6e14f0ac22211e80a0180 Mon Sep 17 00:00:00 2001
From: Scott Erickson <sderickson@gmail.com>
Date: Thu, 17 Jul 2014 09:30:27 -0700
Subject: [PATCH 27/58] Centered social link icons.

---
 app/styles/account/profile.sass               |   3 +-
 .../views/user/JobProfileView.demo.coffee     | 245 +++++++++++++++++-
 2 files changed, 246 insertions(+), 2 deletions(-)

diff --git a/app/styles/account/profile.sass b/app/styles/account/profile.sass
index 05a06f6ee..a661ea611 100644
--- a/app/styles/account/profile.sass
+++ b/app/styles/account/profile.sass
@@ -127,13 +127,14 @@
               text-align: center
 
           ul.links
+            text-align: center
             li.has-icon
               display: inline-block
               img
                 margin: 0 0 10px 0
             li.has-icon:not(:nth-child(5))
               img
-                margin: 0 10px 10px 0
+                margin: 0 5px 10px 5px
 
           #contact-candidate
             margin-top: 20px
diff --git a/test/demo/views/user/JobProfileView.demo.coffee b/test/demo/views/user/JobProfileView.demo.coffee
index b48c4dbc7..2aabea003 100644
--- a/test/demo/views/user/JobProfileView.demo.coffee
+++ b/test/demo/views/user/JobProfileView.demo.coffee
@@ -2,7 +2,250 @@ ProfileView = require 'views/account/profile_view'
 
 responses =
   '/db/user/joe/nameToID':'512ef4805a67a8c507000001'
-  '/db/user/512ef4805a67a8c507000001':{"_id":"512ef4805a67a8c507000001","__v":47,"email":"livelily@gmail.com","emailSubscriptions":["announcement","notification","developer","level_creator","tester","article_editor","translator","support"],"facebookID":"4301215","firstName":"Nick","gender":"male","lastName":"Winter","name":"Nick!","photoURL":"db/user/512ef4805a67a8c507000001/nick_wizard.png","volume":0,"wizardColor1":0.4,"testGroupNumber":217,"mailChimp":{"leid":"70264209","euid":"c4418e2abd","email":"livelily@gmail.com"},"hourOfCode":true,"hourOfCodeComplete":true,"signedCLA":"Fri Jan 03 2014 14:40:18 GMT-0800 (PST)","wizard":{"colorConfig":{"boots":{"lightness":0.1647058823529412,"saturation":0.023809523809523805,"hue":0},"spell":{"hue":0.7490196078431373,"saturation":0.4106280193236715,"lightness":0.5941176470588235},"cloud":{"lightness":0.14,"saturation":1,"hue":0},"clothes":{"lightness":0.1411764705882353,"saturation":0,"hue":0},"trim":{"hue":0.5,"saturation":0.009900990099009936,"lightness":0.19803921568627453}}},"aceConfig":{"liveCompletion":true,"indentGuides":true,"invisibles":true,"keyBindings":"emacs","behaviors":true,"language":"javascript"},"lastLevel":"drink-me","gplusID":"110703832132860599877","jobProfile":{"photoURL":"db/user/512ef4805a67a8c507000001/nick_bokeh_small.jpg","links":[{"name":"Twitter","link":"https://twitter.com/nwinter"},{"name":"Facebook","link":"https://www.facebook.com/nwinter"},{"name":"LinkedIn","link":"https://www.linkedin.com/in/nwinter"},{"name":"Blog","link":"http://blog.nickwinter.net/"},{"name":"Personal Site","link":"http://www.nickwinter.net/"},{"name":"GitHub","link":"https://github.com/nwinter"},{"name":"G+","link":"https://plus.google.com/u/0/+NickWinter"}],"projects":[{"name":"The Motivation Hacker","description":"I wrote a book. *The Motivation Hacker* shows you how to summon extreme amounts of motivation to accomplish anything you can think of. From precommitment to rejection therapy, this is your field guide to getting yourself to want to do everything you always wanted to want to do.","picture":"db/user/512ef4805a67a8c507000001/the_motivation_hacker_thumb.jpg","link":"http://www.nickwinter.net/motivation-hacker"},{"name":"Quantified Mind","description":"Quantified Mind is a tool that quickly, reliably, and comprehensively measures your basic cognitive abilities. We've adapted tests used by psychologists to a practical web application that you can use whenever, wherever, and as often as you want.","picture":"db/user/512ef4805a67a8c507000001/screenshot.png","link":"http://www.quantified-mind.com/"},{"link":"https://github.com/nwinter/telepath-logger","name":"Telepath","description":"A happy Mac keylogger for Quantified Self purposes. It also now serves as a time lapse heads-up-display thing. I used it to make a [time-lapse video of myself working an 120-hour workweek](http://blog.nickwinter.net/the-120-hour-workweek-epic-coding-time-lapse).","picture":"db/user/512ef4805a67a8c507000001/687474703a2f2f63646e2e736574742e636f6d2f696d616765732f757365722f32303133313131303139353534393937375a30356665633666623234623937323263373733636231303537613130626336365f66726f6e742e6a7067"}],"education":[{"school":"Oberlin College","degree":"BA Computer Science, Mathematics, and East Asian Studies, highest honors in CS","duration":"Aug 2004 - May 2008","description":"Cofounded Oberlin Street Art and did all sorts of crazy missions without telling anyone about it."}],"work":[{"employer":"CodeCombat","role":"Cofounder","duration":"Jan 2013 - present","description":"Programming a programming game for learning programming to be a programming programmer of programmatic programs."},{"employer":"Skritter","role":"Cofounder","duration":"May 2008 - present","description":"I coded, I designed, I marketed, I businessed, I wrote, I drudged, I cheffed, I laughed, I cried. But mostly I emailed. God, so much email."}],"visa":"Authorized to work in the US","longDescription":"I cofounded Skritter, am working on CodeCombat, helped with Quantified Mind, live in San Francisco, went to Oberlin College, wrote a book about motivation hacking, and can do anything.\n\nI like hacking on startups, pigs with dogs for feet, and Smash Bros. I dislike shoes, mortality, and Java.\n\nDo you love hiring renegade maverick commandos who can't abide the system? Are you looking to hire the sample job profile candidate of the job profile system? Are you just testing this thing? If your answer is yes, yes yes!–then let us talk.","shortDescription":"Maniac two-time startup cofounder looking to test the system and see what a job profile might look like. Can't nobody hold him down.","experience":6,"skills":["python","coffeescript","node","ios","objective-c","javascript","app-engine","mongodb","web dev","django","backbone","chinese","qs","writing"],"country":"USA","city":"San Francisco","active":false,"lookingFor":"Full-time","name":"Nick Winter","updated":"2014-07-12T01:48:42.980Z","jobTitle":"Mutant Code Gorilla"},"jobProfileApproved":false,"emails":{"anyNotes":{"enabled":true},"generalNews":{"enabled":true},"archmageNews":{"enabled":true},"artisanNews":{"enabled":true},"adventurerNews":{"enabled":true},"scribeNews":{"enabled":true},"diplomatNews":{"enabled":true},"ambassadorNews":{"enabled":true}},"activity":{"viewed_by_employer":{"last":"2014-06-19T20:21:43.747Z","count":6,"first":"2014-06-12T01:37:38.278Z"},"view_candidate":{"first":"2014-06-10T19:59:30.773Z","count":661,"last":"2014-07-11T02:14:40.131Z"},"login":{"first":"2014-06-10T21:55:08.968Z","count":22,"last":"2014-07-16T16:32:31.661Z"},"contacted_by_employer":{"first":"2014-06-19T20:24:51.870Z","count":1,"last":"2014-06-19T20:24:51.870Z"}},"slug":"nick","jobProfileNotes":"Nick used to be the **#1 Brawlwood player** on CodeCombat. He wrote most of the game engine, so that's totally cheating. Now other players have surpassed him by emulating his moves and improving his strategy. If you like the sixth Rocky movie, you might still want to hire this aging hero even in his fading senescence.","simulatedFor":2363,"simulatedBy":103674,"preferredLanguage":"en-US","anonymous":false,"permissions":["admin"],"autocastDelay":90019001,"music":false,"dateCreated":"2013-02-28T06:09:04.743Z"}
+  
+  
+  '/db/user/512ef4805a67a8c507000001': {
+    "_id": "512ef4805a67a8c507000001",
+    "__v": 47,
+    "email": "livelily@gmail.com",
+    "emailSubscriptions": [
+      "announcement",
+      "notification",
+      "developer",
+      "level_creator",
+      "tester",
+      "article_editor",
+      "translator",
+      "support"
+    ],
+    "facebookID": "4301215",
+    "firstName": "Nick",
+    "gender": "male",
+    "lastName": "Winter",
+    "name": "Nick!",
+    "photoURL": "db/user/512ef4805a67a8c507000001/nick_wizard.png",
+    "volume": 0,
+    "wizardColor1": 0.4,
+    "testGroupNumber": 217,
+    "mailChimp": {
+      "leid": "70264209",
+      "euid": "c4418e2abd",
+      "email": "livelily@gmail.com"
+    },
+    "hourOfCode": true,
+    "hourOfCodeComplete": true,
+    "signedCLA": "Fri Jan 03 2014 14:40:18 GMT-0800 (PST)",
+    "wizard": {
+      "colorConfig": {
+        "boots": {
+          "lightness": 0.1647058823529412,
+          "saturation": 0.023809523809523805,
+          "hue": 0
+        },
+        "spell": {
+          "hue": 0.7490196078431373,
+          "saturation": 0.4106280193236715,
+          "lightness": 0.5941176470588235
+        },
+        "cloud": {
+          "lightness": 0.14,
+          "saturation": 1,
+          "hue": 0
+        },
+        "clothes": {
+          "lightness": 0.1411764705882353,
+          "saturation": 0,
+          "hue": 0
+        },
+        "trim": {
+          "hue": 0.5,
+          "saturation": 0.009900990099009936,
+          "lightness": 0.19803921568627453
+        }
+      }
+    },
+    "aceConfig": {
+      "liveCompletion": true,
+      "indentGuides": true,
+      "invisibles": true,
+      "keyBindings": "emacs",
+      "behaviors": true,
+      "language": "javascript"
+    },
+    "lastLevel": "drink-me",
+    "gplusID": "110703832132860599877",
+    "jobProfile": {
+      "photoURL": "db/user/512ef4805a67a8c507000001/nick_bokeh_small.jpg",
+      "links": [
+#        {
+#          "name": "Twitter",
+#          "link": "https://twitter.com/nwinter"
+#        },
+#        {
+#          "name": "Facebook",
+#          "link": "https://www.facebook.com/nwinter"
+#        },
+        {
+          "name": "LinkedIn",
+          "link": "https://www.linkedin.com/in/nwinter"
+        },
+        {
+          "name": "Blog",
+          "link": "http://blog.nickwinter.net/"
+        },
+        {
+          "name": "Personal Site",
+          "link": "http://www.nickwinter.net/"
+        },
+        {
+          "name": "GitHub",
+          "link": "https://github.com/nwinter"
+        },
+        {
+          "name": "G+",
+          "link": "https://plus.google.com/u/0/+NickWinter"
+        }
+      ],
+      "projects": [
+        {
+          "name": "The Motivation Hacker",
+          "description": "I wrote a book. *The Motivation Hacker* shows you how to summon extreme amounts of motivation to accomplish anything you can think of. From precommitment to rejection therapy, this is your field guide to getting yourself to want to do everything you always wanted to want to do.",
+          "picture": "db/user/512ef4805a67a8c507000001/the_motivation_hacker_thumb.jpg",
+          "link": "http://www.nickwinter.net/motivation-hacker"
+        },
+        {
+          "name": "Quantified Mind",
+          "description": "Quantified Mind is a tool that quickly, reliably, and comprehensively measures your basic cognitive abilities. We've adapted tests used by psychologists to a practical web application that you can use whenever, wherever, and as often as you want.",
+          "picture": "db/user/512ef4805a67a8c507000001/screenshot.png",
+          "link": "http://www.quantified-mind.com/"
+        },
+        {
+          "link": "https://github.com/nwinter/telepath-logger",
+          "name": "Telepath",
+          "description": "A happy Mac keylogger for Quantified Self purposes. It also now serves as a time lapse heads-up-display thing. I used it to make a [time-lapse video of myself working an 120-hour workweek](http://blog.nickwinter.net/the-120-hour-workweek-epic-coding-time-lapse).",
+          "picture": "db/user/512ef4805a67a8c507000001/687474703a2f2f63646e2e736574742e636f6d2f696d616765732f757365722f32303133313131303139353534393937375a30356665633666623234623937323263373733636231303537613130626336365f66726f6e742e6a7067"
+        }
+      ],
+      "education": [
+        {
+          "school": "Oberlin College",
+          "degree": "BA Computer Science, Mathematics, and East Asian Studies, highest honors in CS",
+          "duration": "Aug 2004 - May 2008",
+          "description": "Cofounded Oberlin Street Art and did all sorts of crazy missions without telling anyone about it."
+        }
+      ],
+      "work": [
+        {
+          "employer": "CodeCombat",
+          "role": "Cofounder",
+          "duration": "Jan 2013 - present",
+          "description": "Programming a programming game for learning programming to be a programming programmer of programmatic programs."
+        },
+        {
+          "employer": "Skritter",
+          "role": "Cofounder",
+          "duration": "May 2008 - present",
+          "description": "I coded, I designed, I marketed, I businessed, I wrote, I drudged, I cheffed, I laughed, I cried. But mostly I emailed. God, so much email."
+        }
+      ],
+      "visa": "Authorized to work in the US",
+      "longDescription": "I cofounded Skritter, am working on CodeCombat, helped with Quantified Mind, live in San Francisco, went to Oberlin College, wrote a book about motivation hacking, and can do anything.\n\nI like hacking on startups, pigs with dogs for feet, and Smash Bros. I dislike shoes, mortality, and Java.\n\nDo you love hiring renegade maverick commandos who can't abide the system? Are you looking to hire the sample job profile candidate of the job profile system? Are you just testing this thing? If your answer is yes, yes yes!–then let us talk.",
+      "shortDescription": "Maniac two-time startup cofounder looking to test the system and see what a job profile might look like. Can't nobody hold him down.",
+      "experience": 6,
+      "skills": [
+        "python",
+        "coffeescript",
+        "node",
+        "ios",
+        "objective-c",
+        "javascript",
+        "app-engine",
+        "mongodb",
+        "web dev",
+        "django",
+        "backbone",
+        "chinese",
+        "qs",
+        "writing"
+      ],
+      "country": "USA",
+      "city": "San Francisco",
+      "active": false,
+      "lookingFor": "Full-time",
+      "name": "Nick Winter",
+      "updated": "2014-07-12T01:48:42.980Z",
+      "jobTitle": "Mutant Code Gorilla"
+    },
+    "jobProfileApproved": false,
+    "emails": {
+      "anyNotes": {
+        "enabled": true
+      },
+      "generalNews": {
+        "enabled": true
+      },
+      "archmageNews": {
+        "enabled": true
+      },
+      "artisanNews": {
+        "enabled": true
+      },
+      "adventurerNews": {
+        "enabled": true
+      },
+      "scribeNews": {
+        "enabled": true
+      },
+      "diplomatNews": {
+        "enabled": true
+      },
+      "ambassadorNews": {
+        "enabled": true
+      }
+    },
+    "activity": {
+      "viewed_by_employer": {
+        "last": "2014-06-19T20:21:43.747Z",
+        "count": 6,
+        "first": "2014-06-12T01:37:38.278Z"
+      },
+      "view_candidate": {
+        "first": "2014-06-10T19:59:30.773Z",
+        "count": 661,
+        "last": "2014-07-11T02:14:40.131Z"
+      },
+      "login": {
+        "first": "2014-06-10T21:55:08.968Z",
+        "count": 22,
+        "last": "2014-07-16T16:32:31.661Z"
+      },
+      "contacted_by_employer": {
+        "first": "2014-06-19T20:24:51.870Z",
+        "count": 1,
+        "last": "2014-06-19T20:24:51.870Z"
+      }
+    },
+    "slug": "nick",
+    "jobProfileNotes": "Nick used to be the **#1 Brawlwood player** on CodeCombat. He wrote most of the game engine, so that's totally cheating. Now other players have surpassed him by emulating his moves and improving his strategy. If you like the sixth Rocky movie, you might still want to hire this aging hero even in his fading senescence.",
+    "simulatedFor": 2363,
+    "simulatedBy": 103674,
+    "preferredLanguage": "en-US",
+    "anonymous": false,
+    "permissions": [
+      "admin"
+    ],
+    "autocastDelay": 90019001,
+    "music": false,
+    "dateCreated": "2013-02-28T06:09:04.743Z"
+  },
+
+
+
+
+
+
+
+
   '/db/user/512ef4805a67a8c507000001/level.sessions/employer': [
     {
       "_id": "53179b49b483edfcdb7ef13e",

From 0561235da2b224d5fc510592b34974b89ae51681 Mon Sep 17 00:00:00 2001
From: Michael Schmatz <michaelschmatz@gmail.com>
Date: Thu, 17 Jul 2014 09:50:18 -0700
Subject: [PATCH 28/58] Have no emails send to employers who haven't logged in

---
 server/routes/mail.coffee | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/server/routes/mail.coffee b/server/routes/mail.coffee
index 5569428f5..60b1bbaed 100644
--- a/server/routes/mail.coffee
+++ b/server/routes/mail.coffee
@@ -253,6 +253,8 @@ makeEmployerNamesEasilyAccessible = (allEmployers, cb) ->
 employersEmailedDigestMoreThanWeekAgoFilter = (employer, cb) ->
   if employer.emails?.employerNotes?.enabled is false
     return cb true
+  if not employer.signedEmployerAgreement and not employer.activity?.login?
+    return cb true
   findParameters = 
     "user": employer._id
     "mailTask": @mailTaskName

From a9d664b8ecfa775687be1e1db1957af6cf941e4d Mon Sep 17 00:00:00 2001
From: Michael Schmatz <michaelschmatz@gmail.com>
Date: Thu, 17 Jul 2014 13:16:17 -0700
Subject: [PATCH 29/58] Restored legacy candidates view

---
 app/styles/admin/candidates.sass       |  74 +++++++++
 app/templates/admin.jade               |   2 +
 app/templates/admin/candidates.jade    | 110 +++++++++++++
 app/views/admin/candidates_view.coffee | 207 +++++++++++++++++++++++++
 server/routes/mail.coffee              |   2 +-
 5 files changed, 394 insertions(+), 1 deletion(-)
 create mode 100644 app/styles/admin/candidates.sass
 create mode 100644 app/templates/admin/candidates.jade
 create mode 100644 app/views/admin/candidates_view.coffee

diff --git a/app/styles/admin/candidates.sass b/app/styles/admin/candidates.sass
new file mode 100644
index 000000000..1a34e9f12
--- /dev/null
+++ b/app/styles/admin/candidates.sass
@@ -0,0 +1,74 @@
+#admin-candidates-view
+
+  h1, h2, h3
+    font: Arial
+
+  .see-candidates-header
+    margin: 30px
+    text-align: center
+
+    #see-candidates
+      cursor: pointer
+
+  .employer_icon
+    width: 125px
+    float: left
+    margin: 0px 15px 15px 0px
+
+  .information_row
+    height: 150px
+    padding-right: 15px
+
+  #leftside
+    width: 500px
+    float: left
+
+  #rightside
+    width: 500px
+    float: left
+
+  .tablesorter
+    //img
+    //  display: none
+
+    .tablesorter-header
+      cursor: pointer
+      &:hover
+        color: black
+
+      &:first-child
+        // Make sure that "Developer #56" doesn't wrap onto second row
+        min-width: 110px
+
+    .tablesorter-headerAsc
+      background-color: #cfc
+
+    .tablesorter-headerDesc
+      background-color: #ccf
+
+    tr
+      cursor: pointer
+
+    tr.expired
+      opacity: 0.5
+
+    code
+      background-color: rgb(220, 220, 220)
+      color: #555
+      margin: 2px 0
+      display: inline-block
+      text-transform: lowercase
+
+    td:nth-child(3) select
+      min-width: 100px
+    td:nth-child(6) select
+      min-width: 50px
+    td:nth-child(7) select
+      min-width: 100px
+
+#employers-view, #profile-view.viewed-by-employer
+  #outer-content-wrapper, #intermediate-content-wrapper, #inner-content-wrapper
+    background: #949494
+
+  .main-content-area
+    background-color: #EAEAEA
\ No newline at end of file
diff --git a/app/templates/admin.jade b/app/templates/admin.jade
index 11ee67ee8..5d583f703 100644
--- a/app/templates/admin.jade
+++ b/app/templates/admin.jade
@@ -25,6 +25,8 @@ block content
       a(href="/admin/level_sessions", data-i18n="admin.av_entities_active_instances_url") Active Instances
     li
       a(href="/admin/employer_list", data-i18n="admin.av_entities_employer_list_url") Employer List
+    li
+      a(href="/admin/candidates") Candidate List
         
   h4(data-i18n="admin.av_other_sub_title") Other
 
diff --git a/app/templates/admin/candidates.jade b/app/templates/admin/candidates.jade
new file mode 100644
index 000000000..0a2d85f96
--- /dev/null
+++ b/app/templates/admin/candidates.jade
@@ -0,0 +1,110 @@
+extends /templates/base
+block content
+  if !me.isAdmin()
+    h1 Admins Only
+  if me.isAdmin()
+    h1(data-i18n="employers.want_to_hire_our_players") Hire CodeCombat Players
+    if !isEmployer && !me.isAdmin()
+      div#info_wrapper
+        div#leftside
+          div.information_row
+            img(class="employer_icon" src="/images/pages/employer/employer_icon1.png")
+            h2(data-i18n="employers.what") What is CodeCombat?
+            p(data-i18n="employers.what_blurb") CodeCombat is a multiplayer browser programming game. Players write code to control their forces in battle against other developers. We support JavaScript, Python, Lua, Clojure, CoffeeScript, and Io.
+          div.information_row
+            img(class="employer_icon" src="/images/pages/employer/employer_icon3.png")
+            h2(data-i18n="employers.who") Who Are the Players?
+            p(data-i18n="employers.who_blurb") CodeCombateers are CTOs, VPs of Engineering, and graduates of top 20 engineering schools. No junior developers here. Our players enjoy playing with code and solving problems.
+          div.information_row
+            img(class="employer_icon" src="/images/pages/employer/employer_icon5.png")
+            h2(data-i18n="employers.cost") Who Are the Players?
+            p(data-i18n="employers.cost_blurb") CodeCombateers are CTOs, VPs of Engineering, and graduates of top 20 engineering schools. No junior developers here. Our players enjoy playing with code and solving problems.
+        div#rightside
+          div.information_row
+            img(class="employer_icon" src="/images/pages/employer/employer_icon2.png")
+            h2(data-i18n="employers.how") How Much Do we Charge?
+            p(data-i18n="employers.how_blurb") We charge 15% of first year's salary and offer a 100% money back guarantee for 90 days. We don't charge for candidates who are already actively being interviewed at your company.
+          div.information_row
+            img(class="employer_icon" src="/images/pages/employer/employer_icon4.png")
+            h2(data-i18n="employers.why") Why Hire Through Us?
+            p
+              span(data-i18n="employers.why_blurb_1") We will save you time. Every CodeCombateer we feaure is 
+              strong(data-i18n="employers.why_blurb_2") looking for work
+              span(data-i18n="employers.why_blurb_3") , has 
+              strong(data-i18n="employers.why_blurb_4") demonstrated top notch technical skills
+              span(data-i18n="employers.why_blurb_5") , and has been 
+              strong(data-i18n="employers.why_blurb_6") personally screened by us
+              span(data-i18n="employers.why_blurb_7") . Stop screening and start hiring.
+          div.information_row
+            img(class="employer_icon" src="/images/pages/employer/employer_icon6.png")
+            h2(data-i18n="employers.response") What's the Response Rate?
+            p(data-i18n="employers.response_blurb") Almost every developer you contact on CodeCombat will respond to inquires whether or not they want to interivew. If you would like help finding a candidate for your role, we can make recommendations.
+    if candidates.length
+      ul.nav.nav-pills
+        li.active
+          a(href="#featured-candidates", data-toggle="tab")
+            span(data-i18n="employers.featured_developers") Featured Developers
+            | (#{featuredCandidates.length})
+        if otherCandidates.length
+          li
+            a(href="#other-candidates", data-toggle="tab")
+              span(data-i18n="employers.other_developers") Other Developers
+              | (#{otherCandidates.length})
+        if me.isAdmin() && inactiveCandidates.length
+          li
+            a(href="#inactive-candidates", data-toggle="tab")
+              span(data-i18n="employers.inactive_developers") Inactive Developers
+              | (#{inactiveCandidates.length})
+      div.tab-content
+        for area, tabIndex in [{id: "featured-candidates", candidates: featuredCandidates}, {id: "other-candidates", candidates: otherCandidates}, {id: "inactive-candidates", candidates: inactiveCandidates}]
+          div(class="tab-pane well" + (tabIndex ? "" : " active"), id=area.id)
+            table.table.table-condensed.table-hover.table-responsive.tablesorter
+              thead
+                tr
+                  th(data-i18n="general.name") Name
+                  th(data-i18n="employers.candidate_location") Location
+                  th(data-i18n="employers.candidate_looking_for") Looking For
+                  th(data-i18n="employers.candidate_role") Role
+                  th(data-i18n="employers.candidate_top_skills") Top Skills
+                  th(data-i18n="employers.candidate_years_experience") Yrs Exp
+                  th(data-i18n="employers.candidate_last_updated") Last Updated
+                  if me.isAdmin()
+                    th(data-i18n="employers.candidate_who") Who
+                  if me.isAdmin() && area.id == 'inactive-candidates'
+                    th ✓?
+              tbody
+                for candidate, index in area.candidates
+                  - var profile = candidate.get('jobProfile');
+                  - var authorized = candidate.id;  // If we have the id, then we are authorized.
+                  - var profileAge = (new Date() - new Date(profile.updated)) / 86400 / 1000;
+                  - var expired = profileAge > 2 * 30.4;
+                  tr(data-candidate-id=candidate.id, id=candidate.id, class=expired ? "expired" : "")
+                    td
+                      if authorized
+                        img(src=candidate.getPhotoURL(50), alt=profile.name, title=profile.name, height=50)
+                        if profile.name
+                          p= profile.name
+                        else if me.isAdmin()
+                          p (#{candidate.get('name')})
+                      else
+                        img(src="/images/pages/contribute/archmage.png", alt="", title="Sign up as an employer to see our candidates", width=50)
+                        p Developer ##{index + 1 + (area.id == 'featured-candidates' ? 0 : featuredCandidates.length)}
+                    if profile.country == 'USA'
+                      td= profile.city
+                    else
+                      td= profile.country
+                    td= profile.lookingFor
+                    td= profile.jobTitle
+                    td
+                      each skill in profile.skills
+                        code= skill
+                        span
+                    td= profile.experience
+                    td(data-profile-age=profileAge)= moment(profile.updated).fromNow()
+                    if me.isAdmin()
+                      td= remarks[candidate.id] ? remarks[candidate.id].get('contactName') : ''
+                    if me.isAdmin() && area.id == 'inactive-candidates'
+                      if candidate.get('jobProfileApproved')
+                        td ✓
+                      else
+                        td ✗
\ No newline at end of file
diff --git a/app/views/admin/candidates_view.coffee b/app/views/admin/candidates_view.coffee
new file mode 100644
index 000000000..2946b161d
--- /dev/null
+++ b/app/views/admin/candidates_view.coffee
@@ -0,0 +1,207 @@
+View = require 'views/kinds/RootView'
+template = require 'templates/admin/candidates'
+app = require 'application'
+User = require 'models/User'
+UserRemark = require 'models/UserRemark'
+{me} = require 'lib/auth'
+CocoCollection = require 'collections/CocoCollection'
+EmployerSignupView = require 'views/modal/employer_signup_modal'
+
+class CandidatesCollection extends CocoCollection
+  url: '/db/user/x/candidates'
+  model: User
+
+class UserRemarksCollection extends CocoCollection
+  url: '/db/user.remark?project=contact,contactName,user'
+  model: UserRemark
+
+module.exports = class EmployersView extends View
+  id: "admin-candidates-view"
+  template: template
+
+  events:
+    'click tbody tr': 'onCandidateClicked'
+
+  constructor: (options) ->
+    super options
+    @getCandidates()
+
+  afterRender: ->
+    super()
+    @sortTable() if @candidates.models.length
+
+  afterInsert: ->
+    super()
+    _.delay @checkForEmployerSignupHash, 500
+
+  getRenderData: ->
+    ctx = super()
+    ctx.isEmployer = @isEmployer()
+    ctx.candidates = _.sortBy @candidates.models, (c) -> c.get('jobProfile').updated
+    ctx.activeCandidates = _.filter ctx.candidates, (c) -> c.get('jobProfile').active
+    ctx.inactiveCandidates = _.reject ctx.candidates, (c) -> c.get('jobProfile').active
+    ctx.featuredCandidates = _.filter ctx.activeCandidates, (c) -> c.get('jobProfileApproved')
+    ctx.otherCandidates = _.reject ctx.activeCandidates, (c) -> c.get('jobProfileApproved')
+    ctx.remarks = {}
+    ctx.remarks[remark.get('user')] = remark for remark in @remarks.models
+    ctx.moment = moment
+    ctx._ = _
+    ctx
+
+  isEmployer: ->
+    userPermissions = me.get('permissions') ? []
+    _.contains userPermissions, "employer"
+
+  getCandidates: ->
+    @candidates = new CandidatesCollection()
+    @candidates.fetch()
+    @remarks = new UserRemarksCollection()
+    @remarks.fetch()
+    # Re-render when we have fetched them, but don't wait and show a progress bar while loading.
+    @listenToOnce @candidates, 'all', @renderCandidatesAndSetupScrolling
+    @listenToOnce @remarks, 'all', @renderCandidatesAndSetupScrolling
+
+  renderCandidatesAndSetupScrolling: =>
+    @render()
+    $(".nano").nanoScroller()
+    if window.history?.state?.lastViewedCandidateID
+      $(".nano").nanoScroller({scrollTo:$("#" + window.history.state.lastViewedCandidateID)})
+    else if window.location.hash.length is 25
+      $(".nano").nanoScroller({scrollTo:$(window.location.hash)})
+
+  checkForEmployerSignupHash: =>
+    if window.location.hash is "#employerSignupLoggingIn" and not ("employer" in me.get("permissions"))
+      @openModalView application.router.getView("modal/employer_signup","_modal")
+      window.location.hash = ""
+
+  sortTable: ->
+    # http://mottie.github.io/tablesorter/docs/example-widget-bootstrap-theme.html
+    $.extend $.tablesorter.themes.bootstrap,
+      # these classes are added to the table. To see other table classes available,
+      # look here: http://twitter.github.com/bootstrap/base-css.html#tables
+      table: "table table-bordered"
+      caption: "caption"
+      header: "bootstrap-header" # give the header a gradient background
+      footerRow: ""
+      footerCells: ""
+      icons: "" # add "icon-white" to make them white; this icon class is added to the <i> in the header
+      sortNone: "bootstrap-icon-unsorted"
+      sortAsc: "icon-chevron-up"  # glyphicon glyphicon-chevron-up" # we are still using v2 icons
+      sortDesc: "icon-chevron-down"  # glyphicon-chevron-down" # we are still using v2 icons
+      active: "" # applied when column is sorted
+      hover: "" # use custom css here - bootstrap class may not override it
+      filterRow: "" # filter row class
+      even: "" # odd row zebra striping
+      odd: "" # even row zebra striping
+
+
+    # e = exact text from cell
+    # n = normalized value returned by the column parser
+    # f = search filter input value
+    # i = column index
+    # $r = ???
+    filterSelectExactMatch = (e, n, f, i, $r) -> e is f
+
+    # call the tablesorter plugin and apply the uitheme widget
+    @$el.find(".tablesorter").tablesorter
+      theme: "bootstrap"
+      widthFixed: true
+      headerTemplate: "{content} {icon}"
+      textSorter:
+        6: (a, b, direction, column, table) ->
+          days = []
+          for s in [a, b]
+            n = parseInt s
+            n = 0 unless _.isNumber n
+            n = 1 if /^a/.test s
+            for [duration, factor] in [
+              [/second/i, 1 / (86400 * 1000)]
+              [/minute/i, 1 / 1440]
+              [/hour/i, 1 / 24]
+              [/week/i, 7]
+              [/month/i, 30.42]
+              [/year/i, 365.2425]
+            ]
+              if duration.test s
+                n *= factor
+                break
+            if /^in /i.test s
+              n *= -1
+            days.push n
+          days[0] - days[1]
+      sortList: if @isEmployer() or me.isAdmin() then [[6, 0]] else [[0, 1]]
+    # widget code contained in the jquery.tablesorter.widgets.js file
+    # use the zebra stripe widget if you plan on hiding any rows (filter widget)
+      widgets: ["uitheme", "zebra", "filter"]
+      widgetOptions:
+      # using the default zebra striping class name, so it actually isn't included in the theme variable above
+      # this is ONLY needed for bootstrap theming if you are using the filter widget, because rows are hidden
+        zebra: ["even", "odd"]
+
+      # extra css class applied to the table row containing the filters & the inputs within that row
+        filter_cssFilter: ""
+
+      # If there are child rows in the table (rows with class name from "cssChildRow" option)
+      # and this option is true and a match is found anywhere in the child row, then it will make that row
+      # visible; default is false
+        filter_childRows: false
+
+      # if true, filters are collapsed initially, but can be revealed by hovering over the grey bar immediately
+      # below the header row. Additionally, tabbing through the document will open the filter row when an input gets focus
+        filter_hideFilters: false
+
+      # Set this option to false to make the searches case sensitive
+        filter_ignoreCase: true
+
+      # jQuery selector string of an element used to reset the filters
+        filter_reset: ".reset"
+
+      # Use the $.tablesorter.storage utility to save the most recent filters
+        filter_saveFilters: true
+
+      # Delay in milliseconds before the filter widget starts searching; This option prevents searching for
+      # every character while typing and should make searching large tables faster.
+        filter_searchDelay: 150
+
+      # Set this option to true to use the filter to find text from the start of the column
+      # So typing in "a" will find "albert" but not "frank", both have a's; default is false
+        filter_startsWith: false
+
+        filter_functions:
+          2:
+            "Full-time": filterSelectExactMatch
+            "Part-time": filterSelectExactMatch
+            "Contracting": filterSelectExactMatch
+            "Remote": filterSelectExactMatch
+            "Internship": filterSelectExactMatch
+          5:
+            "0-1": (e, n, f, i, $r) -> n <= 1
+            "2-5": (e, n, f, i, $r) -> 2 <= n <= 5
+            "6+": (e, n, f, i, $r) -> 6 <= n
+          6:
+            "Last day": (e, n, f, i, $r) ->
+              days = parseFloat $($r.find('td')[i]).data('profile-age')
+              days <= 1
+            "Last week": (e, n, f, i, $r) ->
+              days = parseFloat $($r.find('td')[i]).data('profile-age')
+              days <= 7
+            "Last 4 weeks": (e, n, f, i, $r) ->
+              days = parseFloat $($r.find('td')[i]).data('profile-age')
+              days <= 28
+          8:
+            "✓": filterSelectExactMatch
+            "✗": filterSelectExactMatch
+
+  onCandidateClicked: (e) ->
+    id = $(e.target).closest('tr').data('candidate-id')
+    if id
+      if window.history
+        oldState = _.cloneDeep window.history.state ? {}
+        oldState["lastViewedCandidateID"] = id
+        window.history.replaceState(oldState,"")
+      else
+        window.location.hash = id
+      url = "/account/profile/#{id}"
+      window.open url,"_blank"
+    else
+      @openModalView new EmployerSignupView
\ No newline at end of file
diff --git a/server/routes/mail.coffee b/server/routes/mail.coffee
index 60b1bbaed..26a5e8ed0 100644
--- a/server/routes/mail.coffee
+++ b/server/routes/mail.coffee
@@ -327,7 +327,7 @@ employerMatchingCandidateNotificationTask = ->
 ###
 ### End Employer Matching Candidate Notification Email ###
 ### Ladder Update Email ###
-
+### Employer ignore ###
 DEBUGGING = false
 LADDER_PREGAME_INTERVAL = 2 * 3600 * 1000  # Send emails two hours before players last submitted.
 getTimeFromDaysAgo = (now, daysAgo) ->

From 6b028513fdf3c3ba6146485c37dc3995c558240f Mon Sep 17 00:00:00 2001
From: Nick Winter <livelily@gmail.com>
Date: Thu, 17 Jul 2014 15:50:29 -0700
Subject: [PATCH 30/58] Fixed issues with level previews and localStorage model
 loading. Disabled break animations on code error for now. Stopped multiple
 ThangType load on multiple missiles. Stopped trying to connect to Redis on
 local production setup.

---
 app/lib/surface/CocoSprite.coffee  |  4 +-
 app/lib/surface/Surface.coffee     |  5 ++-
 app/views/editor/level/edit.coffee |  2 +-
 app/views/play/level_view.coffee   |  5 ++-
 server/routes/mail.coffee          | 72 +++++++++++++++---------------
 5 files changed, 45 insertions(+), 43 deletions(-)

diff --git a/app/lib/surface/CocoSprite.coffee b/app/lib/surface/CocoSprite.coffee
index 3bc8e7330..b05fe99db 100644
--- a/app/lib/surface/CocoSprite.coffee
+++ b/app/lib/surface/CocoSprite.coffee
@@ -82,7 +82,7 @@ module.exports = CocoSprite = class CocoSprite extends CocoClass
     if @thangType.isFullyLoaded()
       @setupSprite()
     else
-      @thangType.fetch()
+      @thangType.fetch() unless @thangType.loading
       @listenToOnce(@thangType, 'sync', @setupSprite)
 
   setupSprite: ->
@@ -442,7 +442,7 @@ module.exports = CocoSprite = class CocoSprite extends CocoClass
       console.warn 'Cannot show action', action, 'for', @thangType.get('name'), 'because it DNE' unless @warnedFor[action]
       @warnedFor[action] = true
       return if @action is 'idle' then null else 'idle'
-    action = 'break' if @actions.break? and @thang?.erroredOut
+    #action = 'break' if @actions.break? and @thang?.erroredOut  # This makes it looks like it's dead when it's not: bad in Brawlwood.
     action = 'die' if @actions.die? and thang?.health? and thang.health <= 0
     @actions[action]
 
diff --git a/app/lib/surface/Surface.coffee b/app/lib/surface/Surface.coffee
index f435f8110..bd6cf7df1 100644
--- a/app/lib/surface/Surface.coffee
+++ b/app/lib/surface/Surface.coffee
@@ -115,7 +115,8 @@ module.exports = Surface = class Surface extends CocoClass
 
   setWorld: (@world) ->
     @worldLoaded = true
-    @world.getFrame(Math.min(@getCurrentFrame(), @world.totalFrames - 1)).restoreState() unless @options.choosing
+    lastFrame = Math.min(@getCurrentFrame(), @world.totalFrames - 1)
+    @world.getFrame(lastFrame).restoreState() unless @options.choosing
     @spriteBoss.world = @world
 
     @showLevel()
@@ -241,7 +242,7 @@ module.exports = Surface = class Surface extends CocoClass
     @onFrameChanged()
 
   getCurrentFrame: ->
-    return Math.max(0, Math.min(Math.floor(@currentFrame), @world.totalFrames - 1))
+    return Math.max(0, Math.min(Math.floor(@currentFrame), @world.frames.length - 1))
 
   getProgress: -> @currentFrame / @world.totalFrames
 
diff --git a/app/views/editor/level/edit.coffee b/app/views/editor/level/edit.coffee
index 18bc8edf5..7e893d748 100644
--- a/app/views/editor/level/edit.coffee
+++ b/app/views/editor/level/edit.coffee
@@ -40,7 +40,7 @@ module.exports = class EditorLevelView extends View
   constructor: (options, @levelID) ->
     super options
     @supermodel.shouldSaveBackups = (model) ->
-      model.constructor.className in ['Level', 'LevelComponent', 'LevelSystem']
+      model.constructor.className in ['Level', 'LevelComponent', 'LevelSystem', 'ThangType']
     @levelLoader = new LevelLoader supermodel: @supermodel, levelID: @levelID, headless: true, editorMode: true
     @level = @levelLoader.level
     @files = new DocumentFiles(@levelLoader.level)
diff --git a/app/views/play/level_view.coffee b/app/views/play/level_view.coffee
index c15fe7c6e..3527df5e5 100644
--- a/app/views/play/level_view.coffee
+++ b/app/views/play/level_view.coffee
@@ -84,8 +84,9 @@ module.exports = class PlayLevelView extends View
     @saveScreenshot = _.throttle @saveScreenshot, 30000
 
     if @isEditorPreview
-      # wait to see if it's just given to us through setLevel
-      f = => @load() unless @levelLoader
+      @supermodel.shouldSaveBackups = (model) ->  # Make sure to load possibly changed things from localStorage.
+        model.constructor.className in ['Level', 'LevelComponent', 'LevelSystem', 'ThangType']
+      f = => @load() unless @levelLoader  # Wait to see if it's just given to us through setLevel.
       setTimeout f, 100
     else
       @load()
diff --git a/server/routes/mail.coffee b/server/routes/mail.coffee
index 60b1bbaed..887de3cf5 100644
--- a/server/routes/mail.coffee
+++ b/server/routes/mail.coffee
@@ -8,15 +8,15 @@ LevelSession = require '../levels/sessions/LevelSession'
 Level = require '../levels/Level'
 log = require 'winston'
 sendwithus = require '../sendwithus'
-if config.isProduction
+if config.isProduction and config.redis.host isnt 'localhost'
   lockManager = require '../commons/LockManager'
-  
+
 module.exports.setup = (app) ->
   app.all config.mail.mailchimpWebhook, handleMailchimpWebHook
   app.get '/mail/cron/ladder-update', handleLadderUpdate
   if lockManager
     setupScheduledEmails()
-  
+
 setupScheduledEmails = ->
   testForLockManager()
   mailTasks = [
@@ -31,15 +31,15 @@ setupScheduledEmails = ->
   ]
 
   for mailTask in mailTasks
-    setInterval mailTask.taskFunction, mailTask.frequencyMs 
-    
+    setInterval mailTask.taskFunction, mailTask.frequencyMs
+
 testForLockManager = -> unless lockManager then throw "The system isn't configured to do distributed locking!"
-  
+
 ### Candidate Update Reminder Task ###
 
 candidateUpdateProfileTask = ->
   mailTaskName = "candidateUpdateProfileTask"
-  lockDurationMs = 2 * 60 * 1000 
+  lockDurationMs = 2 * 60 * 1000
   currentDate = new Date()
   timeRanges = []
   for weekPair in [[4, 2,'two weeks'], [8, 4, 'four weeks'], [52, 8, 'eight weeks']]
@@ -66,12 +66,12 @@ emailTimeRange = (timeRange, emailTimeRangeCallback) ->
     "mailTaskName": @mailTaskName
   async.waterfall [
     findAllCandidatesWithinTimeRange.bind(waterfallContext)
-    (unfilteredCandidates, cb) -> 
+    (unfilteredCandidates, cb) ->
       async.reject unfilteredCandidates, candidateFilter.bind(waterfallContext), cb.bind(null, null)
     (filteredCandidates, cb) ->
       async.each filteredCandidates, sendReminderEmailToCandidate.bind(waterfallContext), cb
   ], emailTimeRangeCallback
-  
+
 findAllCandidatesWithinTimeRange = (cb) ->
   findParameters =
     "jobProfile.updated":
@@ -80,7 +80,7 @@ findAllCandidatesWithinTimeRange = (cb) ->
     "jobProfileApproved": true
   selection =  "_id email jobProfile.name jobProfile.updated emails" #make sure to check for anyNotes too.
   User.find(findParameters).select(selection).lean().exec cb
-  
+
 candidateFilter = (candidate, sentEmailFilterCallback) ->
   if candidate.emails?.anyNotes?.enabled is false or candidate.emails?.recruitNotes?.enabled is false
     return sentEmailFilterCallback true
@@ -102,7 +102,7 @@ findEmployersSignedUpAfterDate = (dateObject, cb) ->
     employerAt: {$exists: true}
     permissions: "employer"
   User.count countParameters, cb
-  
+
 sendReminderEmailToCandidate = (candidate, sendEmailCallback) ->
   findEmployersSignedUpAfterDate new Date(candidate.jobProfile.updated), (err, employersAfterCount) =>
     if err?
@@ -136,7 +136,7 @@ sendReminderEmailToCandidate = (candidate, sendEmailCallback) ->
 ### Internal Candidate Update Reminder Email ###
 internalCandidateUpdateTask = ->
   mailTaskName = "internalCandidateUpdateTask"
-  lockDurationMs = 2 * 60 * 1000 
+  lockDurationMs = 2 * 60 * 1000
   lockManager.setLock mailTaskName, lockDurationMs, (err) ->
     if err? then return log.error "Error getting a distributed lock for task #{mailTaskName}: #{err}"
     emailInternalCandidateUpdateReminder.call {"mailTaskName":mailTaskName}, (err) ->
@@ -162,31 +162,31 @@ emailInternalCandidateUpdateReminder = (internalCandidateUpdateReminderCallback)
     (filteredCandidates, cb) ->
       async.each filteredCandidates, sendInternalCandidateUpdateReminder.bind(asyncContext), cb
   ], internalCandidateUpdateReminderCallback
-    
+
 findNonApprovedCandidatesWhoUpdatedJobProfileToday = (cb) ->
-  findParameters = 
+  findParameters =
     "jobProfile.updated":
       $lte: @currentTime.toISOString()
       $gt: @beginningOfUTCDay.toISOString()
-    "jobProfileApproved": false 
+    "jobProfileApproved": false
   User.find(findParameters).select("_id jobProfile.name jobProfile.updated").lean().exec cb
-  
+
 candidatesUpdatedTodayFilter = (candidate, cb) ->
   findParameters =
     "user": candidate._id
     "mailTask": @mailTaskName
-    "metadata.beginningOfUTCDay": @beginningOfUTCDay 
+    "metadata.beginningOfUTCDay": @beginningOfUTCDay
   MailSent.find(findParameters).lean().exec (err, sentMail) ->
     if err?
       log.error "Error finding mail sent for task #{@mailTaskName} and user #{candidate._id}!"
       cb true
     else
       cb Boolean(sentMail.length)
-    
+
 sendInternalCandidateUpdateReminder = (candidate, cb) ->
   context =
     email_id: "tem_Ac7nhgKqatTHBCgDgjF5pE"
-    recipient: 
+    recipient:
       address: "team@codecombat.com"
       name: "The CodeCombat Team"
     email_data:
@@ -197,7 +197,7 @@ sendInternalCandidateUpdateReminder = (candidate, cb) ->
     user: candidate._id
     metadata:
       beginningOfUTCDay: @beginningOfUTCDay
-    
+
   MailSent.create newSentMail, (err) ->
     if err? then return cb err
     sendwithus.api.send context, (err, result) ->
@@ -208,7 +208,7 @@ sendInternalCandidateUpdateReminder = (candidate, cb) ->
 ### Employer New Candidates Available Email ###
 employerNewCandidatesAvailableTask = ->
   mailTaskName = "employerNewCandidatesAvailableTask"
-  lockDurationMs = 2 * 60 * 1000 
+  lockDurationMs = 2 * 60 * 1000
   lockManager.setLock mailTaskName, lockDurationMs, (err) ->
     if err? then return log.error "Error getting a distributed lock for task #{mailTaskName}: #{err}"
     emailEmployerNewCandidatesAvailable.call {"mailTaskName":mailTaskName}, (err) ->
@@ -221,10 +221,10 @@ employerNewCandidatesAvailableTask = ->
 
 emailEmployerNewCandidatesAvailable = (emailEmployerNewCandidatesAvailableCallback) ->
   currentTime = new Date()
-  asyncContext = 
+  asyncContext =
     "currentTime": currentTime
     "mailTaskName": @mailTaskName
-    
+
   async.waterfall [
     findAllEmployers
     makeEmployerNamesEasilyAccessible
@@ -233,15 +233,15 @@ emailEmployerNewCandidatesAvailable = (emailEmployerNewCandidatesAvailableCallba
     (employersToEmail, cb) ->
       async.each employersToEmail, sendEmployerNewCandidatesAvailableEmail.bind(asyncContext), cb
   ], emailEmployerNewCandidatesAvailableCallback
-      
+
 findAllEmployers = (cb) ->
-  findParameters = 
+  findParameters =
     "employerAt":
-      $exists: true 
+      $exists: true
     permissions: "employer"
   selection = "_id email employerAt signedEmployerAgreement.data.firstName signedEmployerAgreement.data.lastName activity dateCreated emails"
   User.find(findParameters).select(selection).lean().exec cb
-  
+
 makeEmployerNamesEasilyAccessible = (allEmployers, cb) ->
   for employer, index in allEmployers
     if employer.signedEmployerAgreement?.data?.firstName
@@ -249,17 +249,17 @@ makeEmployerNamesEasilyAccessible = (allEmployers, cb) ->
       delete employer.signedEmployerAgreement
     allEmployers[index] = employer
   cb null, allEmployers
-  
+
 employersEmailedDigestMoreThanWeekAgoFilter = (employer, cb) ->
   if employer.emails?.employerNotes?.enabled is false
     return cb true
   if not employer.signedEmployerAgreement and not employer.activity?.login?
     return cb true
-  findParameters = 
+  findParameters =
     "user": employer._id
     "mailTask": @mailTaskName
     "sent":
-      $gt: new Date(@currentTime.getTime() - 7 * 24 * 60 * 60 * 1000) 
+      $gt: new Date(@currentTime.getTime() - 7 * 24 * 60 * 60 * 1000)
   MailSent.find(findParameters).lean().exec (err, sentMail) ->
     if err?
       log.error "Error finding mail sent for task #{@mailTaskName} and employer #employer._id}!"
@@ -268,17 +268,17 @@ employersEmailedDigestMoreThanWeekAgoFilter = (employer, cb) ->
       cb Boolean(sentMail.length)
 
 sendEmployerNewCandidatesAvailableEmail = (employer, cb) ->
-  lastLoginDate = employer.activity?.login?.last ? employer.dateCreated 
+  lastLoginDate = employer.activity?.login?.last ? employer.dateCreated
   countParameters =
     "jobProfileApproved": true
     $or: [
-        jobProfileApprovedDate: 
+        jobProfileApprovedDate:
           $gt: lastLoginDate.toISOString()
       ,
         jobProfileApprovedDate:
           $exists: false
         "jobProfile.updated":
-          $gt: lastLoginDate.toISOString()   
+          $gt: lastLoginDate.toISOString()
     ]
   User.count countParameters, (err, numberOfCandidatesSinceLogin) =>
     if err? then return cb err
@@ -315,8 +315,8 @@ newRecruitLeaderboardEmailTask = ->
   lockManager.setLock mailTaskName, lockDurationMs, (err, lockResult) ->
 ###
 ### End New Recruit Leaderboard Email ###
-  
-### Employer Matching Candidate Notification Email ### 
+
+### Employer Matching Candidate Notification Email ###
 ###
 employerMatchingCandidateNotificationTask = ->
   # tem_mYsepTfWQ265noKfZJcbBH
@@ -344,7 +344,7 @@ isRequestFromDesignatedCronHandler = (req, res) ->
   return true
 
 
-  
+
 handleLadderUpdate = (req, res) ->
   log.info('Going to see about sending ladder update emails.')
   requestIsFromDesignatedCronHandler = isRequestFromDesignatedCronHandler req, res

From 4818a81854eb38a9bf1e119a0a8c604b0edf024c Mon Sep 17 00:00:00 2001
From: Scott Erickson <sderickson@gmail.com>
Date: Thu, 17 Jul 2014 16:22:06 -0700
Subject: [PATCH 31/58] Added setProjection so CocoModels can more easily get
 subsets of data.

---
 app/models/CocoModel.coffee           | 15 +++++++++++----
 test/app/models/CocoModel.spec.coffee |  8 ++++++++
 2 files changed, 19 insertions(+), 4 deletions(-)

diff --git a/app/models/CocoModel.coffee b/app/models/CocoModel.coffee
index 045843306..5da19cab3 100644
--- a/app/models/CocoModel.coffee
+++ b/app/models/CocoModel.coffee
@@ -13,8 +13,10 @@ class CocoModel extends Backbone.Model
 
   getMe: -> @me or @me = require('lib/auth').me
 
-  initialize: ->
-    super()
+  initialize: (attributes, options) ->
+    super(arguments...)
+    options ?= {}
+    @setProjection options.project
     if not @constructor.className
       console.error("#{@} needs a className set.")
     @addSchemaDefaults()
@@ -22,6 +24,8 @@ class CocoModel extends Backbone.Model
     @on 'error', @onError, @
     @on 'add', @onLoaded, @
     @saveBackup = _.debounce(@saveBackup, 500)
+    
+  setProjection: (@project) ->
 
   type: ->
     @constructor.className
@@ -116,8 +120,11 @@ class CocoModel extends Backbone.Model
     console.debug 'Patching', @get('name') or @, keys
     @save(attrs, options)
 
-  fetch: ->
-    @jqxhr = super(arguments...)
+  fetch: (options) ->
+    options ?= {}
+    options.data ?= {}
+    options.data.project = @project.join(',') if @project
+    @jqxhr = super(options)
     @loading = true
     @jqxhr
 
diff --git a/test/app/models/CocoModel.spec.coffee b/test/app/models/CocoModel.spec.coffee
index 67e019c9a..7f2529466 100644
--- a/test/app/models/CocoModel.spec.coffee
+++ b/test/app/models/CocoModel.spec.coffee
@@ -14,6 +14,14 @@ class BlandClass extends CocoModel
   urlRoot: '/db/bland'
 
 describe 'CocoModel', ->
+  describe 'setProjection', ->
+    it 'takes an array of properties to project and adds them as a query parameter', ->
+      b = new BlandClass({})
+      b.setProjection ['number', 'object']
+      b.fetch()
+      request = jasmine.Ajax.requests.mostRecent()
+      expect(decodeURIComponent(request.url).indexOf('project=number,object')).toBeGreaterThan(-1)
+  
   describe 'save', ->
 
     it 'saves to db/<urlRoot>', ->

From 1b999a2efea3642d93c65ef9c6a5a8d3e751d49e Mon Sep 17 00:00:00 2001
From: Scott Erickson <sderickson@gmail.com>
Date: Thu, 17 Jul 2014 16:28:52 -0700
Subject: [PATCH 32/58] Extended getLatestVersion for Handler to also be able
 to accept project parameters.

---
 server/commons/Handler.coffee | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/server/commons/Handler.coffee b/server/commons/Handler.coffee
index a796b705e..9dfca705b 100644
--- a/server/commons/Handler.coffee
+++ b/server/commons/Handler.coffee
@@ -232,7 +232,11 @@ module.exports = class Handler
       query['version.minor'] = minorVersion unless _.isNaN(minorVersion)
     sort = { 'version.major': -1, 'version.minor': -1 }
     args = [query]
-    args.push PROJECT if req.query.project
+    if req.query.project
+      projection = {}
+      fields = if req.query.project is 'true' then _.keys(PROJECT) else req.query.project.split(',')
+      projection[field] = 1 for field in fields
+      args.push projection
     @modelClass.findOne(args...).sort(sort).exec (err, doc) =>
       return @sendNotFoundError(res) unless doc?
       return @sendUnauthorizedError(res) unless @hasAccessToDocument(req, doc)

From 51e63ddbc3ec06f2e021f385a3757b71a6ed4f2e Mon Sep 17 00:00:00 2001
From: Scott Erickson <sderickson@gmail.com>
Date: Thu, 17 Jul 2014 16:29:26 -0700
Subject: [PATCH 33/58] Fixed some DemoView issues, mainly clicking links from
 one demo to another.

---
 app/views/DemoView.coffee | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/app/views/DemoView.coffee b/app/views/DemoView.coffee
index a3b65c781..d18190162 100644
--- a/app/views/DemoView.coffee
+++ b/app/views/DemoView.coffee
@@ -35,6 +35,7 @@ module.exports = DemoView = class DemoView extends CocoView
     @loadDemoingLibs() unless DemoView.loaded
 
   loadDemoingLibs: ->
+    DemoView.loaded = true
     @queue = new createjs.LoadQueue()
     @queue.on('complete', @scriptsLoaded, @)
     window.jasmine = {} # so that mock-ajax properly loads. It expects jasmine to be loaded
@@ -81,8 +82,14 @@ module.exports = DemoView = class DemoView extends CocoView
     view = demoFunc()
     return unless view
     @$el.find('#demo-area').empty().append(view.$el)
+    view.afterInsert()
     # TODO, maybe handle root views differently than modal views differently than everything else?
 
   getAllDemoFiles: ->
     allFiles = window.require.list()
     (f for f in allFiles when f.indexOf('.demo') > -1)
+
+  destroy: ->
+    # hack to get jasmine tests to properly run again on clicking links, and make sure if you
+    # leave this page (say, back to the main site) that test stuff doesn't follow you.
+    document.location.reload()

From 45a8278e7ebbc8c8bb3dd1f6a68b1df0a462c8ac Mon Sep 17 00:00:00 2001
From: Scott Erickson <sderickson@gmail.com>
Date: Thu, 17 Jul 2014 16:30:56 -0700
Subject: [PATCH 34/58] Work on the job profile view, initial work on the code
 modal.

---
 app/schemas/models/level.coffee               |   1 +
 app/schemas/models/level_session.coffee       |   2 +-
 .../common/level_session_code_view.sass       |  19 +
 .../account/job_profile_code_modal.jade       |  13 +
 app/templates/account/profile.jade            |  15 +-
 app/templates/common/level_session_code.jade  |  13 +
 app/views/account/JobProfileCodeModal.coffee  |  19 +
 app/views/account/profile_view.coffee         |   8 +
 app/views/common/LevelSessionCodeView.coffee  |  46 ++
 server/users/user_handler.coffee              |   2 +-
 .../common/LevelSessionCodeView.demo.coffee   |  65 ++
 .../views/user/JobProfileView.demo.coffee     | 558 +++++++-----------
 12 files changed, 422 insertions(+), 339 deletions(-)
 create mode 100644 app/styles/common/level_session_code_view.sass
 create mode 100644 app/templates/account/job_profile_code_modal.jade
 create mode 100644 app/templates/common/level_session_code.jade
 create mode 100644 app/views/account/JobProfileCodeModal.coffee
 create mode 100644 app/views/common/LevelSessionCodeView.coffee
 create mode 100644 test/demo/views/common/LevelSessionCodeView.demo.coffee

diff --git a/app/schemas/models/level.coffee b/app/schemas/models/level.coffee
index eba42f599..31ce3f3f9 100644
--- a/app/schemas/models/level.coffee
+++ b/app/schemas/models/level.coffee
@@ -230,6 +230,7 @@ _.extend LevelSchema.properties,
     title: 'Next Level',
     description: 'Reference to the next level players will play after beating this one.'
   }
+  employerDescription: { type:'string' }
   scripts: c.array {title: 'Scripts', description: 'An array of scripts that trigger based on what the player does and affect things outside of the core level simulation.', 'default': []}, ScriptSchema
   thangs: c.array {title: 'Thangs', description: 'An array of Thangs that make up the level.', 'default': []}, LevelThangSchema
   systems: c.array {title: 'Systems', description: 'Levels are configured by changing the Systems attached to them.', uniqueItems: true, default: []}, LevelSystemSchema  # TODO: uniqueness should be based on 'original', not whole thing
diff --git a/app/schemas/models/level_session.coffee b/app/schemas/models/level_session.coffee
index f4f629914..92ff0f5ba 100644
--- a/app/schemas/models/level_session.coffee
+++ b/app/schemas/models/level_session.coffee
@@ -13,7 +13,7 @@ LevelSessionPlayerSchema = c.object
   changes:
     type: 'Number'
 
-LevelSessionLevelSchema = c.object {required: ['original', 'majorVersion']},
+LevelSessionLevelSchema = c.object {required: ['original', 'majorVersion'], links: [{rel: 'db', href: '/db/level/{(original)}/version/{(majorVersion)}'}]},
   original: c.objectId({})
   majorVersion:
     type: 'integer'
diff --git a/app/styles/common/level_session_code_view.sass b/app/styles/common/level_session_code_view.sass
new file mode 100644
index 000000000..2e5ae518b
--- /dev/null
+++ b/app/styles/common/level_session_code_view.sass
@@ -0,0 +1,19 @@
+.level-session-code-view
+  #level-icon
+    width: 100px
+    margin-right: 10px
+    display: inline-block
+    float: left
+   
+  #level-meta-data
+    margin-left: 120px
+    
+  #session-code
+    clear: both
+    
+    h3
+      font-family: Arial
+      
+    .code
+      height: 600px
+      border: 2px solid black
\ No newline at end of file
diff --git a/app/templates/account/job_profile_code_modal.jade b/app/templates/account/job_profile_code_modal.jade
new file mode 100644
index 000000000..6fb40e492
--- /dev/null
+++ b/app/templates/account/job_profile_code_modal.jade
@@ -0,0 +1,13 @@
+extends /templates/modal/modal_base
+
+block modal-header-content
+  .modal-header
+    h3 Applicant Code
+
+block modal-body-content
+  .modal-body
+    .level-session-code-view
+
+block modal-footer
+  .modal-footer
+    button(data-dismiss="modal", data-i18n="modal.close").btn Close
diff --git a/app/templates/account/profile.jade b/app/templates/account/profile.jade
index 11c0d6956..3f71b8b34 100644
--- a/app/templates/account/profile.jade
+++ b/app/templates/account/profile.jade
@@ -181,13 +181,14 @@ block content
               ul.sessions
                 each session in sessions
                   li
-                    - var sessionLink = "/play/level/" + session.levelID + "?team=" + (session.team || 'humans') + (myProfile ? '' : "&session=" + session._id);
-                    a(href=sessionLink)
-                      span= session.levelName
-                      if session.team
-                        span  #{session.team}
-                    if session.codeLanguage != 'javascript'
-                      span  - #{{coffeescript: 'CoffeeScript', python: 'Python', lua: 'Lua', io: 'Io', clojure: 'Clojure'}[session.codeLanguage]}
+                    span.session-link(data-session-id=session._id)= session.levelName
+                    //- var sessionLink = "/play/level/" + session.levelID + "?team=" + (session.team || 'humans') + (myProfile ? '' : "&session=" + session._id);
+                    //a(href=sessionLink)
+                    //  span= session.levelName
+                    //  if session.team
+                    //    span  #{session.team}
+                    //if session.codeLanguage != 'javascript'
+                    //  span  - #{{coffeescript: 'CoffeeScript', python: 'Python', lua: 'Lua', io: 'Io', clojure: 'Clojure'}[session.codeLanguage]}
 
         .middle-column.full-height-column
           .sub-column
diff --git a/app/templates/common/level_session_code.jade b/app/templates/common/level_session_code.jade
new file mode 100644
index 000000000..eb6f6a867
--- /dev/null
+++ b/app/templates/common/level_session_code.jade
@@ -0,0 +1,13 @@
+div#session-info
+  img(src='/file/'+levelIcon alt='levelIcon')#level-icon
+  div#level-meta-data
+    strong= levelName
+    p!= levelDescription
+  
+div#session-code
+  for spell in levelSpells
+    .panel.panel-success
+      .panel-heading
+        h3= spell.name
+      .panel-body
+        .code= spell.code
\ No newline at end of file
diff --git a/app/views/account/JobProfileCodeModal.coffee b/app/views/account/JobProfileCodeModal.coffee
new file mode 100644
index 000000000..d8545bd43
--- /dev/null
+++ b/app/views/account/JobProfileCodeModal.coffee
@@ -0,0 +1,19 @@
+ModalView = require 'views/kinds/ModalView'
+template = require 'templates/account/job_profile_code_modal'
+LevelSessionCodeView = require 'views/common/LevelSessionCodeView'
+console.log 'template', template
+
+module.exports = class JobProfileCodeModal extends ModalView
+  id: 'job_profile_code_modal'
+  template: template
+  
+  constructor: (options) ->
+    super(arguments...)
+    @session = options.session
+
+  afterRender: ->
+    super()
+    return unless @session.loaded
+    codeView = new LevelSessionCodeView({session:@session})
+    @insertSubView(codeView)
+    
\ No newline at end of file
diff --git a/app/views/account/profile_view.coffee b/app/views/account/profile_view.coffee
index bccb1c7d0..3d3b0b823 100644
--- a/app/views/account/profile_view.coffee
+++ b/app/views/account/profile_view.coffee
@@ -9,6 +9,7 @@ JobProfileView = require 'views/account/job_profile_view'
 UserRemark = require 'models/UserRemark'
 forms = require 'lib/forms'
 ModelModal = require 'views/modal/model_modal'
+JobProfileCodeModal = require './JobProfileCodeModal'
 
 class LevelSessionsCollection extends CocoCollection
   url: -> "/db/user/#{@userID}/level.sessions/employer"
@@ -51,6 +52,7 @@ module.exports = class ProfileView extends RootView
     'keyup .editable-profile .editable-array input': 'onEditArray'
     'click .editable-profile a': 'onClickLinkWhileEditing'
     'change #admin-contact': 'onAdminContactChanged'
+    'click .session-link': 'onSessionLinkPressed'
 
   constructor: (options, @userID) ->
     @userID ?= me.id
@@ -586,3 +588,9 @@ module.exports = class ProfileView extends RootView
       {name: t('account_profile.next_photo'), weight: 2, container: '#profile-photo-container', fn: modified 'photoURL'}
       {name: t('account_profile.next_active'), weight: 1, fn: modified 'active'}
     ]
+
+  onSessionLinkPressed: (e) ->
+    sessionID = $(e.target).data('session-id')
+    session = _.find @sessions.models, (session) -> session.id is sessionID
+    modal = new JobProfileCodeModal({session:session})
+    @openModalView modal
\ No newline at end of file
diff --git a/app/views/common/LevelSessionCodeView.coffee b/app/views/common/LevelSessionCodeView.coffee
new file mode 100644
index 000000000..9a38166fb
--- /dev/null
+++ b/app/views/common/LevelSessionCodeView.coffee
@@ -0,0 +1,46 @@
+CocoView = require 'views/kinds/CocoView'
+template = require 'templates/common/level_session_code'
+
+Level = require 'models/Level'
+LevelSession = require 'models/LevelSession'
+
+module.exports = class LevelSessionCodeView extends CocoView
+  className: 'level-session-code-view'
+  template: template
+  modalWidthPercent: 80
+  plain: true
+
+  constructor: (options) ->
+    super(options)
+    @session = options.session
+    @level = LevelSession.getReferencedModel(@session.get('level'), LevelSession.schema.properties.level)
+    @level.setProjection ['employerDescription', 'name', 'icon']
+    @supermodel.loadModel @level, 'level'
+
+  getRenderData: ->
+    c = super()
+    c.levelIcon = @level.get('icon')
+    c.levelName = @level.get('name')
+    c.levelDescription = marked(@level.get('employerDescription') or '')
+    c.levelSpells = @organizeCode()
+    c
+    
+  afterRender: ->
+    super()
+    @$el.find('.code').each (index, codeEl) ->
+      editor = ace.edit codeEl
+      editor.setReadOnly true
+      aceSession = editor.getSession()
+      aceSession.setMode 'ace/mode/javascript'
+    
+  organizeCode: ->
+    team = @session.get('team') or 'humans'
+    teamSpells = @session.get('teamSpells')[team] or []
+    filteredSpells = []
+    for spell in teamSpells
+      code = @session.getSourceFor(spell)
+      filteredSpells.push {
+        code: code
+        name: spell.split('/')[1]
+      }
+    filteredSpells 
\ No newline at end of file
diff --git a/server/users/user_handler.coffee b/server/users/user_handler.coffee
index 275807ad7..fbd13ec19 100644
--- a/server/users/user_handler.coffee
+++ b/server/users/user_handler.coffee
@@ -233,7 +233,7 @@ UserHandler = class UserHandler extends Handler
   getLevelSessionsForEmployer: (req, res, userID) ->
     return @sendUnauthorizedError(res) unless req.user._id+'' is userID or req.user.isAdmin() or ('employer' in req.user.get('permissions'))
     query = creator: userID, levelID: {$in: ['gridmancer', 'greed', 'dungeon-arena', 'brawlwood', 'gold-rush']}
-    projection = 'levelName levelID team playtime codeLanguage submitted code totalScore'
+    projection = 'levelName levelID team playtime codeLanguage submitted code totalScore teamSpells level'
     LevelSession.find(query).select(projection).exec (err, documents) =>
       return @sendDatabaseError(res, err) if err
       documents = (LevelSessionHandler.formatEntity(req, doc) for doc in documents)
diff --git a/test/demo/views/common/LevelSessionCodeView.demo.coffee b/test/demo/views/common/LevelSessionCodeView.demo.coffee
new file mode 100644
index 000000000..938bec582
--- /dev/null
+++ b/test/demo/views/common/LevelSessionCodeView.demo.coffee
@@ -0,0 +1,65 @@
+LevelSessionCodeView = require 'views/common/LevelSessionCodeView'
+LevelSession = require 'models/LevelSession'
+
+levelSessionData = {
+  "_id": "5334901f0a0f9b286f57382c",
+  "level": {
+    "original": "533353722a61b7ca6832840c",
+    "majorVersion": 0
+  },
+  "team": "humans",
+  "code": {
+    "coin-generator-9000": {
+      "chooseAction": "var buildOrder = ['coin2', 'coin3', 'coin4'];\n//if (Math.random() < 0.25)\n//    this.build(buildOrder[this.built.length % buildOrder.length]);\nif (Math.random() < 0.05)\n    this.build('gem');\nelse if (Math.random() < 0.25)\n    this.build(buildOrder[this.built.length % buildOrder.length])\nelse if (Math.random() < 0.5)\n    this.build('coin');\n\n\n\nvar human = this.getThangByID(\"Tharin\");\nvar ogre = this.getThangByID(\"Mak Fod\");\n\n//this.say(human.gold);\n\n//this.say(\"Humans: \" + human.gold + \", \" + \"Ogres: \" + ogre.gold);\n\nif(ogre.gold >= 150) {\n    this.say(\"Ogres win!\");\n    this.setGoalState(\"goldOgres\", \"success\");\n}\n\nelse if(human.gold >= 150) {\n    this.say(\"Humans win!\");\n    this.setGoalState(\"goldHumans\", \"success\");\n}"
+    },
+    "programmable-coin": {
+      "chooseAction": "//this.say(\"Say, who's in charge around here?\");  // Should fill in some default source\n\n//var time = this.now();\n//if(Math.round(time) % 20 === 0) {\nif (typeof this.teleportOnce === 'undefined') {\n    this.teleportRandom();\n    this.teleportOnce = true;\n}\n//}"
+    },
+    "tharin": {
+      "chooseAction": "var t = this;\nvar e = t.getNearestEnemy();\nvar vec = new Vector(0, 0);\n\nfunction item_worth(item) {\n    return item.bountyGold/Math.pow(item.distance(e) - t.distance(item), 1.5);\n}\n\nvar items = this.getItems();\nfor (var i = 0; i < items.length; i++) {\n    var item = items[i];\n    var direction = Vector.normalize(Vector.subtract(item.pos, this.pos));\n    var weighted_dir = Vector.multiply(direction, 1000 * item_worth(item));\n    vec = Vector.add(vec, weighted_dir);\n}\n\nvar action = \"move\";\nif (typeof this.used_terrify == \"undefined\") {\n    var enemy = this.getNearestEnemy();\n    \n    if (enemy.gold >= 140 || this.distance(enemy) <= 15) {\n        action = \"terrify\";\n    }\n}\n\nif (action == \"move\") {\n    var best_item = null;\n    var best_item_value = 0;\n    for (var i = 0; i < items.length; i++) {\n        var item = items[i];\n        var direction = Vector.subtract(item.pos, this.pos);\n        \n        var angle = Math.acos(vec.dot(direction) / (vec.magnitude() * direction.magnitude()))\n        if (angle < Math.PI / 16 || angle > Math.PI * (31/16)) {\n            if (item_worth(item) > best_item_value) {\n                best_item_value = item_worth(item);\n                best_item = item;\n            }\n        }\n    }\n    \n    if (best_item_value > 0.05) {\n        this.move(best_item.pos);\n    } else {\n        this.say(\"Move to \" + Vector.add(this.pos, vec).x + \" \" + Vector.add(this.pos, vec).y);\n        this.move(Vector.add(this.pos, vec));\n    }\n} else if (action == \"terrify\") {\n    //this.terrify();\n    this.used_terrify = true;\n}\n/*\n\n// This code runs once per frame. Choose where to move to grab gold!\n// First player to 150 gold wins.\n\n// This is an example of grabbing the 0th coin from the items array.\nvar items = this.getItems();\nif (items[0]) {\n    this.move(items[0].pos);\n} else {\n    this.moveXY(18, 36);\n}\n\n\n// You can surely pick a better coin using the methods below.\n// Click on a coin to see its API.\n*/\n"
+    },
+    "wizard-purple": {
+      "chooseAction": "//this.say(\"Say, who's in charge around here?\");  // Should fill in some default source\n\n//var time = this.now();\n\n//if(Math.round(time) % 20 == 0) {\n    this.build('coin');\n//    console.log(\"build coin\");\n//}"
+    }
+  },
+  "teamSpells": {
+    "common": [
+      "coin-generator-9000/chooseAction"
+    ],
+    "humans": [
+      "tharin/chooseAction"
+    ],
+    "ogres": [
+      "mak-fod/chooseAction"
+    ]
+  },
+  "levelID": "gold-rush",
+  "levelName": "Gold Rush",
+  "totalScore": 39.23691444835561,
+  "submitted": true,
+  "submittedCodeLanguage": "javascript",
+  "playtime": 1158,
+  "codeLanguage": "javascript"
+}
+
+levelData = {
+  "_id": "53c71962587cd615bf404919",
+  "name": "Dungeon Arena",
+  "icon": "db/level/53173f76c269d400000543c2/11_dungeon.png",
+  "description": "This level is indescribably flarmy!",
+  "employerDescription": "A DotA-like level where players:\n* Take control of a hero with special abilities\n* Choose which sorts of troops to build.\n* Have limited control over their troops."
+  "version": {
+    "minor": 0,
+    "major": 0,
+    "isLatestMajor": true,
+    "isLatestMinor": true
+  }
+}
+
+module.exports = ->
+  session = new LevelSession(levelSessionData)
+  v = new LevelSessionCodeView({session:session})
+  request = jasmine.Ajax.requests.mostRecent()
+  request.response({status: 200, responseText: JSON.stringify(levelData)})
+  console.log 'okay should be fine'
+  v
diff --git a/test/demo/views/user/JobProfileView.demo.coffee b/test/demo/views/user/JobProfileView.demo.coffee
index 2aabea003..b3a8e1b03 100644
--- a/test/demo/views/user/JobProfileView.demo.coffee
+++ b/test/demo/views/user/JobProfileView.demo.coffee
@@ -3,7 +3,6 @@ ProfileView = require 'views/account/profile_view'
 responses =
   '/db/user/joe/nameToID':'512ef4805a67a8c507000001'
   
-  
   '/db/user/512ef4805a67a8c507000001': {
     "_id": "512ef4805a67a8c507000001",
     "__v": 47,
@@ -239,16 +238,13 @@ responses =
     "dateCreated": "2013-02-28T06:09:04.743Z"
   },
 
-
-
-
-
-
-
-
   '/db/user/512ef4805a67a8c507000001/level.sessions/employer': [
     {
       "_id": "53179b49b483edfcdb7ef13e",
+      "level": {
+        "original": "53173f76c269d400000543c2",
+        "majorVersion": 0
+      },
       "code": {
         "human-base": {
           "chooseAction": "// This is the code for your base. Decide which unit to build each frame.\n// Units you build will go into the this.built array.\n// Destroy the enemy base within 60 seconds!\n// Check out the Guide at the top for more info.\n\n// CHOOSE YOUR HERO! You can only build one hero.\nvar hero;\n//hero = 'tharin';  // A fierce knight with battlecry abilities.\n//hero = 'hushbaum';  // A fiery spellcaster hero.\n\nif(hero && !this.builtHero) {\n    this.builtHero = this.build(hero);\n    return;\n}\n\n// Soldiers are hard-to-kill, low damage melee units with 2s build cooldown.\n// Archers are fragile but deadly ranged units with 2.5s build cooldown.\nvar buildOrder = ['soldier', 'soldier', 'soldier', 'soldier', 'archer'];\nvar type = buildOrder[this.built.length % buildOrder.length];\n//this.say('Unit #' + this.built.length + ' will be a ' + type);\nthis.build(type);"
@@ -270,6 +266,18 @@ responses =
         }
       },
       "submitted": false,
+      "teamSpells": {
+        "ogres": [
+          "programmable-brawler/chooseAction",
+          "programmable-shaman/chooseAction",
+          "ogre-base/chooseAction"
+        ],
+        "humans": [
+          "programmable-librarian/chooseAction",
+          "programmable-tharin/chooseAction",
+          "human-base/chooseAction"
+        ]
+      },
       "levelID": "dungeon-arena",
       "levelName": "Dungeon Arena",
       "submittedCodeLanguage": "javascript",
@@ -278,6 +286,10 @@ responses =
     },
     {
       "_id": "53336ee91506ed33756f73e5",
+      "level": {
+        "original": "533353722a61b7ca6832840c",
+        "majorVersion": 0
+      },
       "code": {
         "tharin": {
           "chooseAction": "this.say(\"Say, who's in charge around here?\");  // Should fill in some default source"
@@ -289,6 +301,13 @@ responses =
           "chooseAction": "//this.say(\"Say, who's in charge around here?\");  // Should fill in some default source\n\n//var time = this.now();\n\n//if(Math.round(time) % 20 == 0) {\n    this.build('coin');\n//    console.log(\"build coin\");\n//}"
         }
       },
+      "teamSpells": {
+        "humans": [
+          "programmable-coin/chooseAction",
+          "tharin/chooseAction",
+          "wizard-purple/chooseAction"
+        ]
+      },
       "levelID": "gold-rush",
       "levelName": "Resource gathering multiplayer",
       "submittedCodeLanguage": "javascript",
@@ -297,6 +316,10 @@ responses =
     },
     {
       "_id": "52ae32cbef42c52f1300000d",
+      "level": {
+        "original": "52ae2460ef42c52f13000008",
+        "majorVersion": 0
+      },
       "levelID": "gridmancer",
       "levelName": "Gridmancer",
       "code": {
@@ -307,6 +330,11 @@ responses =
           "plan": "var grid = this.getNavGrid().grid;\nvar tileSize = 4;\nvar canOverlap = false;\nvar i, rect;\nthis.doWait = function() {\n    this.wait(1);\n    this.say(\"hi\");\n    this.wait(1);\n    this.say(\"there\");\n    this.wait(1);\n};\nthis.doWait();\nfor (var y = 0; y + tileSize < grid.length; y += tileSize) {\n    for (var x = 0; x + tileSize < grid[0].length;) {\n        // check if wall\n        var occupied = grid[y][x].length > 0;\n        // check if already covered by another rect\n        if (!occupied) {\n            for (i = 0; i < this.spawnedRectangles.length; ++i) {\n                rect = this.spawnedRectangles[i];\n                if (rect.pos.x - rect.width / 2 <= x && x < rect.pos.x + rect.width / 2 && rect.pos.y - rect.height / 2 < y && rect.pos.y + rect.height / 2 > y)\n                    occupied = true;\n            }\n        }\n        if (!occupied) {\n            var x2 = x,\n                y2 = y;\n            // expand to the right until we find a wall\n            while (x2 < grid[0].length - 1 && grid[y][x2 + tileSize].length === 0)\n                x2 += tileSize;\n            // expand current horizontal rectangle vertically until wall\n            var ok = true;\n            while (y2 + tileSize < grid.length && ok) {\n                var yt = y2 + tileSize;\n                // check each cell\n                for (var xt = x; xt <= x2; xt += tileSize) {\n                    if (grid[yt][xt].length > 0) {\n                        ok = false;\n                    }\n                }\n                if (!canOverlap) {\n                    // check if tile to the left is non-wall\n                    if (x > 0 && grid[yt][x - tileSize].length === 0) {\n                        // check if already has a rect\n                        var covered = false;\n                        for (i = 0; i < this.spawnedRectangles.length; ++i) {\n                            rect = this.spawnedRectangles[i];\n                            if (rect.pos.x - rect.width / 2 <= x - tileSize &&\n                                x - tileSize < rect.pos.x + rect.width / 2 &&\n                                rect.pos.y - rect.height / 2 < yt &&\n                                rect.pos.y + rect.height / 2 > yt)\n                                covered = true;\n                        }\n                        // if no wall and no rect leave open to avoid future overlap\n                        if (!covered)\n                            ok = false;\n                    }\n                }\n                // advance\n                if (ok)\n                    y2 += tileSize;\n            }\n            // done\n            this.addRect(x + tileSize / 2 + (x2 - x) / 2, y + tileSize / 2 + (y2 - y) / 2,\n                tileSize + (x2 - x), tileSize + (y2 - y));\n            x = x2 + tileSize;\n            this.wait();\n        } else {\n            x += tileSize;\n        }\n    }\n}\n\n/*\nvar tileSize = 4;\n\nvar grid;\nvar occupied, occupiedArray;\nvar numTilesX, numTilesY;\nvar x, y, y2, x2, x3, y3, lastX, lastY;\nvar width, height;\n\ngrid = this.getNavGrid().grid;\noccupiedArray = [];\n\nfor(y = 0; y + tileSize < grid.length; y += tileSize) \n{\n    occupiedArray[y] = [];\n    for(x = 0; x + tileSize < grid[y].length; x += tileSize) \n    {\n        occupiedArray[y][x] = (grid[y][x].length > 0);\n    }\n}\n\nfor(y = 0; y + tileSize < grid.length; y += tileSize) \n{\n    for(x = 0; x + tileSize < grid[y].length; x += tileSize) \n    {\n        if(!occupiedArray[y][x])\n        {\n            //Check width of rectangle\n            lastX = x;\n            y2 = y;\n            numTilesX = 0;\n            var okay = true;\n            for(x2 = x; okay &&x2 + tileSize < grid[y].length; x2 += tileSize)\n            {\n                if(occupiedArray[y2][x2])\n                {\n                    okay = false;\n                    //x2 = grid[y].length;\n                }\n                else\n                {\n                    lastX = x2;\n                    numTilesX++;\n                }\n            }\n\n            // Check height of rectangle\n            lastY = y;\n            x2 = x;\n            numTilesY = 0;\n            okay = true;\n            for(y2 = y; okay && y2 + tileSize < grid.length; y2 += tileSize)\n            {\n                var okay2 = true;\n                for(x3 = x; okay2 && x3 <= lastX; x3 += tileSize)\n                {\n                    occupied = occupiedArray[y2][x3];\n                    if(occupied)\n                    {\n                        okay2 = false;\n                        //x3 = grid[y].length;\n                    }\n                }\n                if(occupied)\n                {\n                    okay = false;\n                    //y2 = grid.length;\n                }\n                else\n                {\n                    lastY = y2;\n                    numTilesY++;\n                }\n            }\n\n            for(y3 = y; y3 <= lastY; y3 += tileSize)            \n            {\n                for(x3 = x; x3 <= lastX; x3 += tileSize)\n                {\n                    occupiedArray[y3][x3] = true;\n                }\n            }\n  \n            width = numTilesX * tileSize;\n            height = numTilesY * tileSize;\n            this.addRect( x  + (width / 2), y + (height / 2), width, height);\n            \n            this.wait();  // Hover over the timeline to help debug!\n        }       \n    }\n}\n*/\n\n\n/*\nvar todoGrid = this.getNavGrid().grid;\nvar tileSize = 4;\nvar yGridSize = todoGrid.length;\nvar xGridSize = todoGrid[0].length;\nvar x, y;\n//store all tiles which actually need to be filled\nfor(y = 0; y + tileSize < yGridSize; y += tileSize) {\n    for(x = 0; x + tileSize < xGridSize; x += tileSize) {\n        todoGrid[y][x] = todoGrid[y][x].length === 0;\n    }\n}\n\n//determine how many tiles to fill\nvar todoAnz = 0;\nfor(y = 0; y + tileSize < yGridSize; y += tileSize) {\n    for(x = 0; x + tileSize < xGridSize; x += tileSize) {\n        if(todoGrid[y][x]) {\n            todoAnz++;\n        }\n    }\n}\n\n//fill all tiles from biggest to smallest rectangle possible\nwhile(todoAnz > 0) {\n    var biggestLeftX, biggestLeftY, biggestRightX, biggestRightY, tmpX, tmpY;\n    var bigRect = 0;\n    for(y = 0; y + tileSize < yGridSize; y += tileSize) {\n        for(x = 0; x + tileSize < xGridSize; x += tileSize) {\n            if(todoGrid[y][x]) {\n            var width = 1, height = 1;\n            while(todoGrid[y][x + width * tileSize] && x + width * tileSize + tileSize < xGridSize) {\n                width++;\n            }\n            var higher = true;\n            while(higher) {\n                for(tmpX = x; tmpX < x + tileSize * width; tmpX += tileSize)\n                    if(!todoGrid[y + height * tileSize][tmpX] || y + height * tileSize + tileSize >= yGridSize) higher = false;\n                if(higher) height++;\n            }\n            if(width * height > bigRect) {\n                bigRect = width * height;\n                biggestLeftX = x;\n                biggestLeftY = y;\n                biggestRightX = x + width * tileSize;\n                biggestRightY = y + height * tileSize;\n            }\n        }\n    }\n}\nfor(tmpY = biggestLeftY; tmpY < biggestRightY; tmpY += tileSize)\n    for(tmpX = biggestLeftX; tmpX < biggestRightX; tmpX += tileSize)\n        todoGrid[tmpY][tmpX] = false;\n    this.addRect( (biggestLeftX + biggestRightX) / 2,\n                  (biggestLeftY + biggestRightY) / 2,\n                  biggestRightX - biggestLeftX,\n                  biggestRightY - biggestLeftY );\n    this.wait(0.2);\n    todoAnz -= bigRect;\n    // this.say(\"Found a \"+bigRect+\" tile Rectangle, \"+todoAnz+\" tile(s) left\");\n}\n// André\n*/\n\n/*\nvar grid = this.getNavGrid().grid;\nvar tileSize = 4;\nfor(var y = 0; y + tileSize < grid.length; y += tileSize) {\n    for(var x = 0; x + tileSize < grid[0].length; ) {\n\n        var occupied = grid[y][x].length > 0;\n\n        if (!occupied) {\n            for (var i = 0; i < this.spawnedRectangles.length; ++i) {\n                var rect = this.spawnedRectangles[i];\n                if (rect.pos.x - rect.width / 2 <= x && x <= rect.pos.x + rect.width / 2 \n                    && rect.pos.y - rect.height / 2 < y && rect.pos.y + rect.height / 2 > y)\n                    occupied = true;\n            }\n        }\n\n        if(!occupied) {\n            var x2 = x, y2 = y;\n            while (x2 < grid[0].length-1 && grid[y][x2+tileSize].length===0)\n                x2 += tileSize;\n\n            var ok = true;\n            while (y2 + tileSize < grid.length && ok) {\n                var yt = y2 + tileSize; \n                for (var xt = x; xt <= x2; xt += tileSize) {\n                    if (grid[yt][xt].length > 0) {\n                        ok = false;\n                    }\n                }\n                if (x > 0 && grid[yt][x - tileSize].length === 0)\n                    ok = false;\n                if (x2 < grid[0].length-tileSize && grid[yt][x2+tileSize].length === 0)\n                    ok = false;\n                if (ok)\n                    y2 += tileSize; \n            }\n\n\n            this.addRect(x + tileSize / 2 + (x2-x)/2, y + tileSize / 2 + (y2-y)/2, tileSize + (x2-x), tileSize + (y2-y));\n            x = x2 + tileSize;\n            this.wait();\n        } else {\n            x += tileSize;\n        }\n    }\n}\n*/\n\n/*\nvar grid = this.getNavGrid().grid;\nvar tileSize = 4;\nvar isCounting;\nvar adyacentX;\nvar startPos;\n\nfor(var y = 0; y + tileSize < grid.length; y += tileSize) {\n    isCounting = 0;\n    adyacentX = 0;\n    for(var x = 0; x + tileSize < grid[0].length; x += tileSize) {\n        var occupied = grid[y][x].length > 0;\n        if(!occupied) {\n            if(isCounting === 0)\n                startPos = x;\n            isCounting = 1;\n            adyacentX++;\n     // this.say(\"Pos(\"+x+\",\"+y+\") is occupied\");\n     // this.addRect(x + tileSize / 2, y + tileSize / 2, tileSize, tileSize);\n    // this.wait(); // Hover over the timeline to help debug!\n        }\n        else {\n       // this.say(\"Pos(\"+x+\",\"+y+\") is not occupied\");\n            isCounting = 0;\n            if(adyacentX > 0){\n      // this.say(\"writing \" + adyacentX + \"width rectangle= \" + tileSize*adyacentX);\n                this.addRect((startPos + x)/2,y+tileSize / 2,tileSize*adyacentX,tileSize);\n                }\n            adyacentX = 0;\n        }\n    }\n\n}\n\nthis.say(\"Finish!\");\n*/\n\n/*\nfunction largestRectangle(grid, bottomY, leftX, width, height) {\n    var coveredRows = [];\n    var shortestCoveredRow = width - leftX;\n    var done = false;\n    for(var y = bottomY; !done && y < height; ++y) {\n        var coveredRow = 0, done2 = false;\n        for(var x = leftX; !done2 && x < leftX + shortestCoveredRow; ++x) {\n            if(!grid[y][x].length)\n                ++coveredRow;\n            else\n                done2 = true;\n        }\n        if(!coveredRow)\n            done = true;\n        else {\n            coveredRows.push(coveredRow);\n            shortestCoveredRow = Math.min(shortestCoveredRow, coveredRow);\n        }\n    }\n    var maxArea = 0, maxAreaRows = 0, maxAreaRowLength = 0, shortestRow = 0;\n    for(var rowIndex = 0; rowIndex < coveredRows.length; ++rowIndex) {\n        var rowLength = coveredRows[rowIndex];\n        if(!shortestRow)\n            shortestRow = rowLength;\n        area = rowLength * (rowIndex + 1);\n        if(area > maxArea) {\n            maxAreaRows = rowIndex +1;\n            maxAreaRowLength = shortestRow;\n            maxArea = area;\n        }\n        shortestRow = Math.min(rowLength, shortestRow);\n    }\n    return {x: leftX + maxAreaRowLength / 2, y: bottomY + maxAreaRows / 2, width: maxAreaRowLength, height: maxAreaRows};\n}\n\nvar grid = this.getNavGrid().grid;\nvar tileSize = 4;\nfor(var y = 0; y < grid.length - tileSize / 2; y += tileSize) {\n    for(var x = 0; x < grid[0].length - tileSize / 2; x += tileSize) {\n        var occupied = grid[y][x].length > 0;\n        if(!occupied) {\n            var rect = largestRectangle(grid, y, x, grid[0].length, grid.length);\n            this.addRect(rect.x, rect.y, rect.width, rect.height);\n            //this.say(\"Placed rect \" + rect.x + \", \" + rect.y + \", \" + rect.width + \", \" + rect.height + \" for \" + grid[0].length + \",  \" + grid.length + \", \" + x + \", \" + y);\n            this.wait(0.1);\n            for(var y2 = rect.y - rect.height / 2; y2 < rect.y + rect.height / 2; ++y2) {\n                for(var x2 = rect.x - rect.width / 2; x2 < rect.x + rect.width / 2; ++x2) {\n                    grid[y2][x2] = [rect];\n                }\n            }\n        }\n    }\n}\n*/"
         }
       },
+      "teamSpells": {
+        "humans": [
+          "thoktar"
+        ]
+      },
       "submitted": false,
       "submittedCodeLanguage": "javascript",
       "playtime": 302,
@@ -314,6 +342,10 @@ responses =
     },
     {
       "_id": "5334901f0a0f9b286f57382c",
+      "level": {
+        "original": "533353722a61b7ca6832840c",
+        "majorVersion": 0
+      },
       "team": "humans",
       "code": {
         "coin-generator-9000": {
@@ -329,9 +361,20 @@ responses =
           "chooseAction": "//this.say(\"Say, who's in charge around here?\");  // Should fill in some default source\n\n//var time = this.now();\n\n//if(Math.round(time) % 20 == 0) {\n    this.build('coin');\n//    console.log(\"build coin\");\n//}"
         }
       },
+      "teamSpells": {
+        "common": [
+          "coin-generator-9000/chooseAction"
+        ],
+        "humans": [
+          "tharin/chooseAction"
+        ],
+        "ogres": [
+          "mak-fod/chooseAction"
+        ]
+      },
       "levelID": "gold-rush",
       "levelName": "Gold Rush",
-      "totalScore": 39.33094538664242,
+      "totalScore": 39.23691444835561,
       "submitted": true,
       "submittedCodeLanguage": "javascript",
       "playtime": 1158,
@@ -339,6 +382,10 @@ responses =
     },
     {
       "_id": "52dea9b77e486eeb97000001",
+      "level": {
+        "original": "52d97ecd32362bc86e004e87",
+        "majorVersion": 0
+      },
       "levelID": "brawlwood",
       "levelName": "Brawlwood",
       "code": {
@@ -391,7 +438,31 @@ responses =
           "hear": "// When the base hears a say() message, this hear() method will be called.\nif(speaker.team !== this.team) return;\n\n// You can add code to respond to the message here.{x: 7, y: 72}{x: 9, y: 74}{x: 4, y: 74}"
         }
       },
-      "totalScore": 24.004311721082228,
+      "totalScore": 24.138610165979667,
+      "teamSpells": {
+        "humans": [
+          "programmable-artillery/chooseAction",
+          "programmable-artillery/hear",
+          "programmable-soldier/chooseAction",
+          "programmable-soldier/hear",
+          "s-arrow-tower/chooseAction",
+          "programmable-archer/chooseAction",
+          "programmable-archer/hear",
+          "human-base/chooseAction",
+          "human-base/hear"
+        ],
+        "ogres": [
+          "programmable-shaman/chooseAction",
+          "programmable-shaman/hear",
+          "n-beam-tower/chooseAction",
+          "programmable-thrower/chooseAction",
+          "programmable-thrower/hear",
+          "programmable-munchkin/chooseAction",
+          "programmable-munchkin/hear",
+          "ogre-base/chooseAction",
+          "ogre-base/hear"
+        ]
+      },
       "team": "humans",
       "submitted": true,
       "submittedCodeLanguage": "javascript",
@@ -400,6 +471,10 @@ responses =
     },
     {
       "_id": "535701331bfa9bba14b5e03d",
+      "level": {
+        "original": "53558b5a9914f5a90d7ccddb",
+        "majorVersion": 0
+      },
       "team": "ogres",
       "levelID": "greed",
       "levelName": "Greed",
@@ -411,10 +486,21 @@ responses =
           "chooseAction": "// This is the code for your base. Decide which unit to build each frame.\n// Units you build will go into the this.built array.  \n// Destroy the enemy base within 120 seconds!     \n// Check out the Guide at the top for more info.\n\nvar base = this;\n\nvar items = this.getItems();\nvar peons = this.getByType('peon');\n\nif(peons[0]) {\n    var item = peons[0].getNearest(items);\n    var index = items.indexOf(item);\n    var index2 = _.indexOf(items, item);\n    var index3 = items.indexOf(peons[0].getNearest(items));\n} \n\nvar friendCosts = {'munchkin': 10, 'ogre': 25, 'shaman': 40, 'fangrider': 160, 'brawler': 500};\nvar enemyCosts = {'soldier': 10, 'knight': 25, 'librarian': 40, 'griffin-rider': 60, 'captain': 100, 'peasant': -1};\nvar friends = this.getFriends();\nvar enemies = this.getEnemies();\nvar ourArmyWorth = 0;\nvar theirArmyWorth = 0;\nfor(var friendIndex in friends)\n    ourArmyWorth += friendCosts[friends[friendIndex].type] || 0;\n                   \nfor(var enemyIndex in enemies) {\n    var enemy = enemies[enemyIndex];\n    if(this.distance(enemy) > 32) continue;\n    theirArmyWorth += (enemyCosts[enemies[enemyIndex].type] || 0 ) + 1;\n}    \n    \nvar type = 'peon';\nvar peons = this.getByType('peon');\nvar shamans = this.getByType('shaman', friends);\nvar nFighters = friends.length - shamans.length - peons.length;\nvar minionTypes = ['brawler', 'fangrider', 'shaman', 'ogre', 'munchkin'];\nif(this.built.length && theirArmyWorth > ourArmyWorth || this.now() > 120) {\n    for(var minionIndex in minionTypes) {\n        type = minionTypes[minionIndex];\n        if(this.gold >= friendCosts[type] && (type != 'shaman' || nFighters))\n            break;\n    }\n}\nvar cost = friendCosts[type];\nif(type == 'peon') {\n    cost = 50 + 10 * peons.length;\n    if(peons.length >= 4)\n        cost = 9001;\n}\nif (this.gold >= cost)\n    this.build(type);\n     \nvar getBestItem = function getBestItem(items, who, near, friends, enemies) {\n    var bestValue = 0;\n    var bestItem = null;\n    for (var i = 0; i < items.length; ++i) {\n        var item = items[i];\n        var d = who.pos.distanceSquared(item.pos);\n        d += who.pos.distanceSquared(near) / 5;\n        var others = friends.concat(enemies);  // hmm, less effective?\n        //var others = friends;\n        for (var j = 0; j < others.length; ++j) {\n            if(others[j] == who) continue;\n            var other = others[j];\n            if(other.team != base.team) {\n                d += 10;\n            }\n            else if(other.distance(item) < who.distance(item)) {\n                d += 40;\n            }\n        }\n        var value = item.bountyGold / d;\n        if (value > bestValue) {\n            bestItem = item;\n            bestValue = value;\n        }\n    }\n    return bestItem;\n};\n\nvar items = this.getItems();\nif(!items.length) return;\nvar ww = 85;\nvar hh = 70;\n//var hyp = Math.sqrt(ww * ww + hh * hh);\nvar centers = [\n    [{x: 2 * ww / 4, y: 2 * hh / 4}],\n    [{x: 1 * ww / 4, y: 3 * hh / 4}, {x: 3 * ww / 4, y: 1 * hh / 4}],\n    [{x: 1 * ww / 4, y: 1 * hh / 4}, {x: 2 * ww / 4, y: 3 * hh / 4}, {x: 3 * ww / 4, y: 1 * hh / 4}],\n    [{x: 1 * ww / 4, y: 1 * hh / 4}, {x: 1 * ww / 4, y: 3 * hh / 4}, {x: 3 * ww / 4, y: 1 * hh / 4}, {x: 3 * ww / 4, y: 3 * hh / 4}],\n    [{x: 1 * ww / 4, y: 1 * hh / 4}, {x: 1 * ww / 4, y: 3 * hh / 4}, {x: 3 * ww / 4, y: 1 * hh / 4}, {x: 3 * ww / 4, y: 3 * hh / 4}, {x: 2 * ww / 4, y: 2 * hh / 4}]\n];\nvar peasants = this.getByType('peasant');\nfor (var i = 0; i < peons.length; ++i) {\n    var minion = peons[i];\n    var layoutIndex = Math.min(peons.length, centers.length) - 1;\n    var layout = centers[layoutIndex];\n    var center = layout[i % layout.length];\n    var item = getBestItem(items, minion, center, peons, peasants);\n    this.command(minion, 'move', item.pos);\n}\n\n//this.say(\"Your investors overpaid! \" + ourArmyWorth + \" vs. \" + theirArmyWorth);\n\n\n// 'peon': Peons gather gold and do not fight.\n// 'munchkin': Light melee unit.\n// 'ogre': Heavy melee unit.\n// 'shaman': Support spellcaster.\n// 'fangrider': Mythically expensive super unit.\n// See the buildables documentation below for costs and the guide for more info.e"
         },
         "human-base": {
-          "chooseAction": ".......;"
+          "chooseAction": "var __interceptThis=(function(){var G=this;return function($this,sandbox){if($this==G){return sandbox;}return $this;};})();\nreturn (function (__global) {\n    var tmp0, tmp1;\n    tmp1 = function () {\n        'use strict'; _aether.logCallStart(_aether._userInfo); var alliedTypes, enemyTypes, tmp, maxkey, filterType, filterNotType, lerp, clamp, remove, removeIndex, valueFighter, valuateFighters, computeMinDistances, computeEnemyMult, computeAttractionSquared, computeSpringAssignments, items, friends, enemies, enemyBase, enemyGold, peasants, peons, assignments, i, as, createRegressionFunc, estimateVariance, estimateHighLow, militaryFriends, friendlySoldiers, militaryEnemies, nearestEnemy, PREDICTOR_HISTORY_LENGTH, PREDICTOR_SAMPLE_INTERVAL, PREDICTOR_LOOKAHEAD_TIME, enemyTotalWorth, ourMilitaryStrength, enemyMilitaryStrength, ourStrength, enemyStrength, enemyStrengthForecast, highLowE, futureEnemyBonus, doNothingState, collectState, pokeState, stockpileState, decideMilitaryToBuild, attackState, defendState, states, type, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8, tmp9, tmp10, tmp11, tmp12, tmp13, tmp14, tmp15, tmp16, tmp17, tmp18, tmp19, tmp20, tmp21, tmp22, tmp23, tmp24, tmp25, tmp26, tmp27, tmp28, tmp29, tmp30, tmp31, tmp32, tmp33, tmp34, tmp35, tmp36, tmp37, tmp38, tmp39, tmp40, tmp41, tmp42, tmp43, tmp44, tmp45, tmp46, tmp47, tmp48, tmp49, tmp50, tmp51, tmp52, tmp53, tmp54, tmp55, tmp56, tmp57, tmp58, tmp59, tmp60, tmp61, tmp64, tmp65, tmp66, tmp67, tmp68, tmp69, tmp70, tmp71, tmp72, tmp73, tmp74, tmp75, tmp76, tmp77, tmp78, tmp79, tmp80, tmp81, tmp82, tmp83, tmp84, tmp85, tmp86, tmp87, tmp88, tmp89, tmp90, tmp91, tmp92, tmp93, tmp94, tmp95, tmp96, tmp97, tmp98, tmp99, tmp100, tmp101, tmp102, tmp103, tmp104, tmp105, tmp106, tmp107, tmp108, tmp109, tmp110, tmp111, tmp112, tmp113, tmp114, tmp115, tmp116, tmp117, tmp118, tmp119, tmp120, tmp121, tmp122, tmp123, tmp124, tmp125, tmp126, tmp127, tmp128, tmp129, tmp130, tmp131, tmp132, tmp133, tmp134, tmp135, tmp136, tmp137, tmp138, tmp139, tmp140, tmp141, tmp142, tmp143, tmp144, tmp145, tmp146, tmp147, tmp148, tmp149, tmp150, tmp151, tmp152, tmp153, tmp154, tmp155, tmp156, tmp157, tmp158, tmp159, tmp160, tmp161, tmp162, tmp163, tmp164, tmp165, tmp166, tmp167, tmp168, tmp169, tmp170, tmp171, tmp172, tmp173, tmp174, tmp175, tmp176, tmp177, tmp178, tmp179, tmp180, tmp181, tmp182, tmp183, tmp184, tmp185, tmp186, tmp187, tmp190, tmp191, tmp192, tmp229, tmp230, tmp231, tmp248, tmp249, tmp250, tmp263, tmp264, tmp265, tmp290, tmp291, tmp292, tmp318, tmp319, tmp320, tmp321, tmp322, tmp323, tmp324, tmp325, tmp326, tmp347, tmp348, tmp349, tmp350, tmp351, tmp352, tmp353, tmp354, tmp355, tmp356, tmp357, tmp358, tmp359, tmp360, tmp361, tmp362, tmp363, tmp364, tmp365, tmp366, tmp367, tmp368, tmp369, tmp370;  for(var __argIndexer = 0; __argIndexer < arguments.length; ++__argIndexer) arguments[__argIndexer] = _aether.createAPIClone(_aether, arguments[__argIndexer]);\n        _aether.logStatementStart([{ofs: 749, row: 30, col: 0}, {ofs: 1054, row: 43, col: 1}]); maxkey = function (f, arr) {\n            var winner, winScore, i, elem, score, tmp371, tmp372, tmp373, tmp374, tmp375, tmp376, tmp377, tmp378, tmp379, tmp380, tmp381, tmp382, tmp385, tmp386, tmp387, tmp388, tmp389, tmp390, tmp391, tmp392; f = _aether.createAPIClone(_aether, f); arr = _aether.createAPIClone(_aether, arr); for(var __argIndexer = 0; __argIndexer < arguments.length; ++__argIndexer) arguments[__argIndexer] = _aether.createAPIClone(_aether, arguments[__argIndexer]);\n            _aether.logStatementStart([{ofs: 779, row: 31, col: 4}, {ofs: 797, row: 31, col: 22}]); winner = null;  _aether.logStatement([{ofs: 779, row: 31, col: 4}, {ofs: 797, row: 31, col: 22}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 818, row: 32, col: 20}, {ofs: 823, row: 32, col: 25}]); tmp371 = 10000;  _aether.logStatement([{ofs: 818, row: 32, col: 20}, {ofs: 823, row: 32, col: 25}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 802, row: 32, col: 4}, {ofs: 824, row: 32, col: 26}]); winScore = -tmp371;  _aether.logStatement([{ofs: 802, row: 32, col: 4}, {ofs: 824, row: 32, col: 26}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 834, row: 33, col: 9}, {ofs: 843, row: 33, col: 18}]); i = 0;  _aether.logStatement([{ofs: 834, row: 33, col: 9}, {ofs: 843, row: 33, col: 18}], _aether._userInfo, false);\n            tmp373 = i;\n            tmp375 = arr;\n            tmp376 = 'length';\n            _aether.logStatementStart([{ofs: 849, row: 33, col: 24}, {ofs: 859, row: 33, col: 34}]); tmp374 = tmp375[tmp376];  _aether.logStatement([{ofs: 849, row: 33, col: 24}, {ofs: 859, row: 33, col: 34}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 845, row: 33, col: 20}, {ofs: 859, row: 33, col: 34}]); tmp372 = tmp373 < tmp374;  _aether.logStatement([{ofs: 845, row: 33, col: 20}, {ofs: 859, row: 33, col: 34}], _aether._userInfo, false);\n            tmp383: {\n                while (tmp372) {\n                    tmp384: {\n                        tmp385 = arr;\n                        tmp386 = i;\n                        _aether.logStatementStart([{ofs: 876, row: 34, col: 8}, {ofs: 894, row: 34, col: 26}]); elem = tmp385[tmp386];  _aether.logStatement([{ofs: 876, row: 34, col: 8}, {ofs: 894, row: 34, col: 26}], _aether._userInfo, false);\n                        tmp387 = f;\n                        tmp388 = elem;\n                        _aether.logStatementStart([{ofs: 903, row: 35, col: 8}, {ofs: 923, row: 35, col: 28}]); score = _aether.createAPIClone(_aether, tmp387(_aether.restoreAPIClone(_aether, tmp388)));  _aether.logStatement([{ofs: 903, row: 35, col: 8}, {ofs: 923, row: 35, col: 28}], _aether._userInfo, false);\n                        tmp390 = score;\n                        tmp391 = winScore;\n                        _aether.logStatementStart([{ofs: 936, row: 36, col: 12}, {ofs: 952, row: 36, col: 28}]); tmp389 = tmp390 > tmp391;  _aether.logStatement([{ofs: 936, row: 36, col: 12}, {ofs: 952, row: 36, col: 28}], _aether._userInfo, false);\n                        if (tmp389) {\n                            winner = elem;\n                            winScore = score;\n                        } else {\n                            ;\n                        }\n                    }\n                    tmp381 = i;\n                    tmp382 = 1;\n                    i = tmp381 + tmp382;\n                    tmp377 = i;\n                    tmp379 = arr;\n                    tmp380 = 'length';\n                    _aether.logStatementStart([{ofs: 849, row: 33, col: 24}, {ofs: 859, row: 33, col: 34}]); tmp378 = tmp379[tmp380];  _aether.logStatement([{ofs: 849, row: 33, col: 24}, {ofs: 859, row: 33, col: 34}], _aether._userInfo, false);\n                    _aether.logStatementStart([{ofs: 845, row: 33, col: 20}, {ofs: 859, row: 33, col: 34}]); tmp372 = tmp377 < tmp378;  _aether.logStatement([{ofs: 845, row: 33, col: 20}, {ofs: 859, row: 33, col: 34}], _aether._userInfo, false);\n                }\n            }\n            tmp392 = winner;\n            return _aether.restoreAPIClone(_aether, tmp392);\n        };  _aether.logStatement([{ofs: 749, row: 30, col: 0}, {ofs: 1054, row: 43, col: 1}], _aether._userInfo, false);\n        _aether.logStatementStart([{ofs: 1122, row: 46, col: 0}, {ofs: 1225, row: 48, col: 1}]); filterType = function (type, arr) {\n            var tmp393, tmp394, tmp395, tmp396, tmp397; type = _aether.createAPIClone(_aether, type); arr = _aether.createAPIClone(_aether, arr); for(var __argIndexer = 0; __argIndexer < arguments.length; ++__argIndexer) arguments[__argIndexer] = _aether.createAPIClone(_aether, arguments[__argIndexer]);\n            tmp394 = arr;\n            tmp395 = 'filter';\n            _aether.logStatementStart([{ofs: 1177, row: 47, col: 22}, {ofs: 1216, row: 47, col: 61}]); tmp396 = function (x) {\n                var tmp398, tmp399, tmp400, tmp401, tmp402; x = _aether.createAPIClone(_aether, x); for(var __argIndexer = 0; __argIndexer < arguments.length; ++__argIndexer) arguments[__argIndexer] = _aether.createAPIClone(_aether, arguments[__argIndexer]);\n                tmp401 = x;\n                tmp402 = 'type';\n                _aether.logStatementStart([{ofs: 1198, row: 47, col: 43}, {ofs: 1204, row: 47, col: 49}]); tmp399 = tmp401[tmp402];  _aether.logStatement([{ofs: 1198, row: 47, col: 43}, {ofs: 1204, row: 47, col: 49}], _aether._userInfo, false);\n                tmp400 = type;\n                _aether.logStatementStart([{ofs: 1198, row: 47, col: 43}, {ofs: 1213, row: 47, col: 58}]); tmp398 = tmp399 === tmp400;  _aether.logStatement([{ofs: 1198, row: 47, col: 43}, {ofs: 1213, row: 47, col: 58}], _aether._userInfo, false);\n                return _aether.restoreAPIClone(_aether, tmp398);\n            };  _aether.logStatement([{ofs: 1177, row: 47, col: 22}, {ofs: 1216, row: 47, col: 61}], _aether._userInfo, false);\n            tmp397 = arr;\n            _aether.logStatementStart([{ofs: 1166, row: 47, col: 11}, {ofs: 1222, row: 47, col: 67}]); tmp393 = _aether.createAPIClone(_aether, tmp394[tmp395](_aether.restoreAPIClone(_aether, tmp396), _aether.restoreAPIClone(_aether, tmp397)));  _aether.logStatement([{ofs: 1166, row: 47, col: 11}, {ofs: 1222, row: 47, col: 67}], _aether._userInfo, false);\n            return _aether.restoreAPIClone(_aether, tmp393);\n        };  _aether.logStatement([{ofs: 1122, row: 46, col: 0}, {ofs: 1225, row: 48, col: 1}], _aether._userInfo, false);\n        _aether.logStatementStart([{ofs: 1291, row: 51, col: 0}, {ofs: 1397, row: 53, col: 1}]); filterNotType = function (type, arr) {\n            var tmp403, tmp404, tmp405, tmp406, tmp407; type = _aether.createAPIClone(_aether, type); arr = _aether.createAPIClone(_aether, arr); for(var __argIndexer = 0; __argIndexer < arguments.length; ++__argIndexer) arguments[__argIndexer] = _aether.createAPIClone(_aether, arguments[__argIndexer]);\n            tmp404 = arr;\n            tmp405 = 'filter';\n            _aether.logStatementStart([{ofs: 1349, row: 52, col: 22}, {ofs: 1388, row: 52, col: 61}]); tmp406 = function (x) {\n                var tmp408, tmp409, tmp410, tmp411, tmp412; x = _aether.createAPIClone(_aether, x); for(var __argIndexer = 0; __argIndexer < arguments.length; ++__argIndexer) arguments[__argIndexer] = _aether.createAPIClone(_aether, arguments[__argIndexer]);\n                tmp411 = x;\n                tmp412 = 'type';\n                _aether.logStatementStart([{ofs: 1370, row: 52, col: 43}, {ofs: 1376, row: 52, col: 49}]); tmp409 = tmp411[tmp412];  _aether.logStatement([{ofs: 1370, row: 52, col: 43}, {ofs: 1376, row: 52, col: 49}], _aether._userInfo, false);\n                tmp410 = type;\n                _aether.logStatementStart([{ofs: 1370, row: 52, col: 43}, {ofs: 1385, row: 52, col: 58}]); tmp408 = tmp409 !== tmp410;  _aether.logStatement([{ofs: 1370, row: 52, col: 43}, {ofs: 1385, row: 52, col: 58}], _aether._userInfo, false);\n                return _aether.restoreAPIClone(_aether, tmp408);\n            };  _aether.logStatement([{ofs: 1349, row: 52, col: 22}, {ofs: 1388, row: 52, col: 61}], _aether._userInfo, false);\n            tmp407 = arr;\n            _aether.logStatementStart([{ofs: 1338, row: 52, col: 11}, {ofs: 1394, row: 52, col: 67}]); tmp403 = _aether.createAPIClone(_aether, tmp404[tmp405](_aether.restoreAPIClone(_aether, tmp406), _aether.restoreAPIClone(_aether, tmp407)));  _aether.logStatement([{ofs: 1338, row: 52, col: 11}, {ofs: 1394, row: 52, col: 67}], _aether._userInfo, false);\n            return _aether.restoreAPIClone(_aether, tmp403);\n        };  _aether.logStatement([{ofs: 1291, row: 51, col: 0}, {ofs: 1397, row: 53, col: 1}], _aether._userInfo, false);\n        _aether.logStatementStart([{ofs: 1532, row: 57, col: 0}, {ofs: 1610, row: 59, col: 1}]); lerp = function (start, end, frac) {\n            var tmp413, tmp414, tmp415, tmp416, tmp417, tmp418, tmp419; start = _aether.createAPIClone(_aether, start); end = _aether.createAPIClone(_aether, end); frac = _aether.createAPIClone(_aether, frac); for(var __argIndexer = 0; __argIndexer < arguments.length; ++__argIndexer) arguments[__argIndexer] = _aether.createAPIClone(_aether, arguments[__argIndexer]);\n            tmp414 = start;\n            tmp418 = end;\n            tmp419 = start;\n            _aether.logStatementStart([{ofs: 1587, row: 58, col: 21}, {ofs: 1598, row: 58, col: 32}]); tmp416 = tmp418 - tmp419;  _aether.logStatement([{ofs: 1587, row: 58, col: 21}, {ofs: 1598, row: 58, col: 32}], _aether._userInfo, false);\n            tmp417 = frac;\n            _aether.logStatementStart([{ofs: 1586, row: 58, col: 20}, {ofs: 1606, row: 58, col: 40}]); tmp415 = tmp416 * tmp417;  _aether.logStatement([{ofs: 1586, row: 58, col: 20}, {ofs: 1606, row: 58, col: 40}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 1577, row: 58, col: 11}, {ofs: 1607, row: 58, col: 41}]); tmp413 = tmp414 + tmp415;  _aether.logStatement([{ofs: 1577, row: 58, col: 11}, {ofs: 1607, row: 58, col: 41}], _aether._userInfo, false);\n            return _aether.restoreAPIClone(_aether, tmp413);\n        };  _aether.logStatement([{ofs: 1532, row: 57, col: 0}, {ofs: 1610, row: 59, col: 1}], _aether._userInfo, false);\n        _aether.logStatementStart([{ofs: 1612, row: 61, col: 0}, {ofs: 1693, row: 63, col: 1}]); clamp = function (val, low, high) {\n            var tmp420, tmp421, tmp422, tmp423, tmp424, tmp425, tmp426, tmp427, tmp428, tmp429, tmp430; val = _aether.createAPIClone(_aether, val); low = _aether.createAPIClone(_aether, low); high = _aether.createAPIClone(_aether, high); for(var __argIndexer = 0; __argIndexer < arguments.length; ++__argIndexer) arguments[__argIndexer] = _aether.createAPIClone(_aether, arguments[__argIndexer]);\n            tmp423 = 'Math';\n            tmp421 = __global[tmp423];\n            tmp422 = 'max';\n            tmp428 = 'Math';\n            tmp426 = __global[tmp428];\n            tmp427 = 'min';\n            tmp429 = val;\n            tmp430 = high;\n            _aether.logStatementStart([{ofs: 1665, row: 62, col: 20}, {ofs: 1684, row: 62, col: 39}]); tmp424 = _aether.createAPIClone(_aether, tmp426[tmp427](_aether.restoreAPIClone(_aether, tmp429), _aether.restoreAPIClone(_aether, tmp430)));  _aether.logStatement([{ofs: 1665, row: 62, col: 20}, {ofs: 1684, row: 62, col: 39}], _aether._userInfo, false);\n            tmp425 = low;\n            _aether.logStatementStart([{ofs: 1656, row: 62, col: 11}, {ofs: 1690, row: 62, col: 45}]); tmp420 = _aether.createAPIClone(_aether, tmp421[tmp422](_aether.restoreAPIClone(_aether, tmp424), _aether.restoreAPIClone(_aether, tmp425)));  _aether.logStatement([{ofs: 1656, row: 62, col: 11}, {ofs: 1690, row: 62, col: 45}], _aether._userInfo, false);\n            return _aether.restoreAPIClone(_aether, tmp420);\n        };  _aether.logStatement([{ofs: 1612, row: 61, col: 0}, {ofs: 1693, row: 63, col: 1}], _aether._userInfo, false);\n        _aether.logStatementStart([{ofs: 1751, row: 66, col: 0}, {ofs: 1829, row: 68, col: 1}]); remove = function (elem, arr) {\n            var tmp431, tmp432, tmp433, tmp434, tmp435, tmp436, tmp437, tmp438, tmp439, tmp440; elem = _aether.createAPIClone(_aether, elem); arr = _aether.createAPIClone(_aether, arr); for(var __argIndexer = 0; __argIndexer < arguments.length; ++__argIndexer) arguments[__argIndexer] = _aether.createAPIClone(_aether, arguments[__argIndexer]);\n            tmp434 = arr;\n            tmp435 = 'splice';\n            tmp438 = arr;\n            tmp439 = 'indexOf';\n            tmp440 = elem;\n            _aether.logStatementStart([{ofs: 1802, row: 67, col: 22}, {ofs: 1819, row: 67, col: 39}]); tmp436 = _aether.createAPIClone(_aether, tmp438[tmp439](_aether.restoreAPIClone(_aether, tmp440)));  _aether.logStatement([{ofs: 1802, row: 67, col: 22}, {ofs: 1819, row: 67, col: 39}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 1821, row: 67, col: 41}, {ofs: 1822, row: 67, col: 42}]); tmp437 = 1;  _aether.logStatement([{ofs: 1821, row: 67, col: 41}, {ofs: 1822, row: 67, col: 42}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 1791, row: 67, col: 11}, {ofs: 1823, row: 67, col: 43}]); tmp432 = _aether.createAPIClone(_aether, tmp434[tmp435](_aether.restoreAPIClone(_aether, tmp436), _aether.restoreAPIClone(_aether, tmp437)));  _aether.logStatement([{ofs: 1791, row: 67, col: 11}, {ofs: 1823, row: 67, col: 43}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 1824, row: 67, col: 44}, {ofs: 1825, row: 67, col: 45}]); tmp433 = 0;  _aether.logStatement([{ofs: 1824, row: 67, col: 44}, {ofs: 1825, row: 67, col: 45}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 1791, row: 67, col: 11}, {ofs: 1826, row: 67, col: 46}]); tmp431 = tmp432[tmp433];  _aether.logStatement([{ofs: 1791, row: 67, col: 11}, {ofs: 1826, row: 67, col: 46}], _aether._userInfo, false);\n            return _aether.restoreAPIClone(_aether, tmp431);\n        };  _aether.logStatement([{ofs: 1751, row: 66, col: 0}, {ofs: 1829, row: 68, col: 1}], _aether._userInfo, false);\n        _aether.logStatementStart([{ofs: 1900, row: 71, col: 0}, {ofs: 1964, row: 73, col: 1}]); removeIndex = function (i, arr) {\n            var tmp441, tmp442, tmp443, tmp444, tmp445, tmp446, tmp447; i = _aether.createAPIClone(_aether, i); arr = _aether.createAPIClone(_aether, arr); for(var __argIndexer = 0; __argIndexer < arguments.length; ++__argIndexer) arguments[__argIndexer] = _aether.createAPIClone(_aether, arguments[__argIndexer]);\n            tmp444 = arr;\n            tmp445 = 'splice';\n            tmp446 = i;\n            _aether.logStatementStart([{ofs: 1956, row: 72, col: 25}, {ofs: 1957, row: 72, col: 26}]); tmp447 = 1;  _aether.logStatement([{ofs: 1956, row: 72, col: 25}, {ofs: 1957, row: 72, col: 26}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 1942, row: 72, col: 11}, {ofs: 1958, row: 72, col: 27}]); tmp442 = _aether.createAPIClone(_aether, tmp444[tmp445](_aether.restoreAPIClone(_aether, tmp446), _aether.restoreAPIClone(_aether, tmp447)));  _aether.logStatement([{ofs: 1942, row: 72, col: 11}, {ofs: 1958, row: 72, col: 27}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 1959, row: 72, col: 28}, {ofs: 1960, row: 72, col: 29}]); tmp443 = 0;  _aether.logStatement([{ofs: 1959, row: 72, col: 28}, {ofs: 1960, row: 72, col: 29}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 1942, row: 72, col: 11}, {ofs: 1961, row: 72, col: 30}]); tmp441 = tmp442[tmp443];  _aether.logStatement([{ofs: 1942, row: 72, col: 11}, {ofs: 1961, row: 72, col: 30}], _aether._userInfo, false);\n            return _aether.restoreAPIClone(_aether, tmp441);\n        };  _aether.logStatement([{ofs: 1900, row: 71, col: 0}, {ofs: 1964, row: 73, col: 1}], _aether._userInfo, false);\n        _aether.logStatementStart([{ofs: 2109, row: 78, col: 0}, {ofs: 2639, row: 101, col: 1}]); valueFighter = function (type) {\n            var tmp448, tmp450, tmp451, tmp452, tmp453, tmp454, tmp455, tmp456, tmp457, tmp458, tmp459, tmp460, tmp461, tmp462, tmp463, tmp464, tmp465, tmp466, tmp467, tmp468, tmp469, tmp470, tmp471, tmp472, tmp473, tmp474, tmp475, tmp476, tmp477, tmp478, tmp479, tmp480, tmp481, tmp482, tmp483, tmp484, tmp485, tmp486, tmp487, tmp488; type = _aether.createAPIClone(_aether, type); for(var __argIndexer = 0; __argIndexer < arguments.length; ++__argIndexer) arguments[__argIndexer] = _aether.createAPIClone(_aether, arguments[__argIndexer]);\n            tmp448 = type;\n            tmp449: {\n                _aether.logStatementStart([{ofs: 2172, row: 80, col: 13}, {ofs: 2182, row: 80, col: 23}]); tmp486 = 'munchkin';  _aether.logStatement([{ofs: 2172, row: 80, col: 13}, {ofs: 2182, row: 80, col: 23}], _aether._userInfo, false);\n                _aether.logStatementStart([{ofs: 2143, row: 79, col: 4}, {ofs: 2637, row: 100, col: 5}]); tmp487 = tmp448 === tmp486;  _aether.logStatement([{ofs: 2143, row: 79, col: 4}, {ofs: 2637, row: 100, col: 5}], _aether._userInfo, false);\n                if (tmp487) {\n                    _aether.logStatementStart([{ofs: 2227, row: 82, col: 19}, {ofs: 2229, row: 82, col: 21}]); tmp488 = 10;  _aether.logStatement([{ofs: 2227, row: 82, col: 19}, {ofs: 2229, row: 82, col: 21}], _aether._userInfo, false);\n                    return _aether.restoreAPIClone(_aether, tmp488);\n                } else {\n                    _aether.logStatementStart([{ofs: 2197, row: 81, col: 13}, {ofs: 2206, row: 81, col: 22}]); tmp483 = 'soldier';  _aether.logStatement([{ofs: 2197, row: 81, col: 13}, {ofs: 2206, row: 81, col: 22}], _aether._userInfo, false);\n                    _aether.logStatementStart([{ofs: 2143, row: 79, col: 4}, {ofs: 2637, row: 100, col: 5}]); tmp484 = tmp448 === tmp483;  _aether.logStatement([{ofs: 2143, row: 79, col: 4}, {ofs: 2637, row: 100, col: 5}], _aether._userInfo, false);\n                    if (tmp484) {\n                        _aether.logStatementStart([{ofs: 2227, row: 82, col: 19}, {ofs: 2229, row: 82, col: 21}]); tmp485 = 10;  _aether.logStatement([{ofs: 2227, row: 82, col: 19}, {ofs: 2229, row: 82, col: 21}], _aether._userInfo, false);\n                        return _aether.restoreAPIClone(_aether, tmp485);\n                    } else {\n                        _aether.logStatementStart([{ofs: 2244, row: 83, col: 13}, {ofs: 2252, row: 83, col: 21}]); tmp480 = 'knight';  _aether.logStatement([{ofs: 2244, row: 83, col: 13}, {ofs: 2252, row: 83, col: 21}], _aether._userInfo, false);\n                        _aether.logStatementStart([{ofs: 2143, row: 79, col: 4}, {ofs: 2637, row: 100, col: 5}]); tmp481 = tmp448 === tmp480;  _aether.logStatement([{ofs: 2143, row: 79, col: 4}, {ofs: 2637, row: 100, col: 5}], _aether._userInfo, false);\n                        if (tmp481) {\n                            _aether.logStatementStart([{ofs: 2294, row: 85, col: 19}, {ofs: 2296, row: 85, col: 21}]); tmp482 = 25;  _aether.logStatement([{ofs: 2294, row: 85, col: 19}, {ofs: 2296, row: 85, col: 21}], _aether._userInfo, false);\n                            return _aether.restoreAPIClone(_aether, tmp482);\n                        } else {\n                            _aether.logStatementStart([{ofs: 2267, row: 84, col: 13}, {ofs: 2273, row: 84, col: 19}]); tmp477 = 'ogre';  _aether.logStatement([{ofs: 2267, row: 84, col: 13}, {ofs: 2273, row: 84, col: 19}], _aether._userInfo, false);\n                            _aether.logStatementStart([{ofs: 2143, row: 79, col: 4}, {ofs: 2637, row: 100, col: 5}]); tmp478 = tmp448 === tmp477;  _aether.logStatement([{ofs: 2143, row: 79, col: 4}, {ofs: 2637, row: 100, col: 5}], _aether._userInfo, false);\n                            if (tmp478) {\n                                _aether.logStatementStart([{ofs: 2294, row: 85, col: 19}, {ofs: 2296, row: 85, col: 21}]); tmp479 = 25;  _aether.logStatement([{ofs: 2294, row: 85, col: 19}, {ofs: 2296, row: 85, col: 21}], _aether._userInfo, false);\n                                return _aether.restoreAPIClone(_aether, tmp479);\n                            } else {\n                                _aether.logStatementStart([{ofs: 2311, row: 86, col: 13}, {ofs: 2322, row: 86, col: 24}]); tmp474 = 'librarian';  _aether.logStatement([{ofs: 2311, row: 86, col: 13}, {ofs: 2322, row: 86, col: 24}], _aether._userInfo, false);\n                                _aether.logStatementStart([{ofs: 2143, row: 79, col: 4}, {ofs: 2637, row: 100, col: 5}]); tmp475 = tmp448 === tmp474;  _aether.logStatement([{ofs: 2143, row: 79, col: 4}, {ofs: 2637, row: 100, col: 5}], _aether._userInfo, false);\n                                if (tmp475) {\n                                    _aether.logStatementStart([{ofs: 2366, row: 88, col: 19}, {ofs: 2368, row: 88, col: 21}]); tmp476 = 40;  _aether.logStatement([{ofs: 2366, row: 88, col: 19}, {ofs: 2368, row: 88, col: 21}], _aether._userInfo, false);\n                                    return _aether.restoreAPIClone(_aether, tmp476);\n                                } else {\n                                    _aether.logStatementStart([{ofs: 2337, row: 87, col: 13}, {ofs: 2345, row: 87, col: 21}]); tmp471 = 'shaman';  _aether.logStatement([{ofs: 2337, row: 87, col: 13}, {ofs: 2345, row: 87, col: 21}], _aether._userInfo, false);\n                                    _aether.logStatementStart([{ofs: 2143, row: 79, col: 4}, {ofs: 2637, row: 100, col: 5}]); tmp472 = tmp448 === tmp471;  _aether.logStatement([{ofs: 2143, row: 79, col: 4}, {ofs: 2637, row: 100, col: 5}], _aether._userInfo, false);\n                                    if (tmp472) {\n                                        _aether.logStatementStart([{ofs: 2366, row: 88, col: 19}, {ofs: 2368, row: 88, col: 21}]); tmp473 = 40;  _aether.logStatement([{ofs: 2366, row: 88, col: 19}, {ofs: 2368, row: 88, col: 21}], _aether._userInfo, false);\n                                        return _aether.restoreAPIClone(_aether, tmp473);\n                                    } else {\n                                        _aether.logStatementStart([{ofs: 2383, row: 89, col: 13}, {ofs: 2398, row: 89, col: 28}]); tmp468 = 'griffin-rider';  _aether.logStatement([{ofs: 2383, row: 89, col: 13}, {ofs: 2398, row: 89, col: 28}], _aether._userInfo, false);\n                                        _aether.logStatementStart([{ofs: 2143, row: 79, col: 4}, {ofs: 2637, row: 100, col: 5}]); tmp469 = tmp448 === tmp468;  _aether.logStatement([{ofs: 2143, row: 79, col: 4}, {ofs: 2637, row: 100, col: 5}], _aether._userInfo, false);\n                                        if (tmp469) {\n                                            _aether.logStatementStart([{ofs: 2445, row: 91, col: 19}, {ofs: 2447, row: 91, col: 21}]); tmp470 = 60;  _aether.logStatement([{ofs: 2445, row: 91, col: 19}, {ofs: 2447, row: 91, col: 21}], _aether._userInfo, false);\n                                            return _aether.restoreAPIClone(_aether, tmp470);\n                                        } else {\n                                            _aether.logStatementStart([{ofs: 2413, row: 90, col: 13}, {ofs: 2424, row: 90, col: 24}]); tmp465 = 'fangrider';  _aether.logStatement([{ofs: 2413, row: 90, col: 13}, {ofs: 2424, row: 90, col: 24}], _aether._userInfo, false);\n                                            _aether.logStatementStart([{ofs: 2143, row: 79, col: 4}, {ofs: 2637, row: 100, col: 5}]); tmp466 = tmp448 === tmp465;  _aether.logStatement([{ofs: 2143, row: 79, col: 4}, {ofs: 2637, row: 100, col: 5}], _aether._userInfo, false);\n                                            if (tmp466) {\n                                                _aether.logStatementStart([{ofs: 2445, row: 91, col: 19}, {ofs: 2447, row: 91, col: 21}]); tmp467 = 60;  _aether.logStatement([{ofs: 2445, row: 91, col: 19}, {ofs: 2447, row: 91, col: 21}], _aether._userInfo, false);\n                                                return _aether.restoreAPIClone(_aether, tmp467);\n                                            } else {\n                                                _aether.logStatementStart([{ofs: 2462, row: 92, col: 13}, {ofs: 2471, row: 92, col: 22}]); tmp462 = 'captain';  _aether.logStatement([{ofs: 2462, row: 92, col: 13}, {ofs: 2471, row: 92, col: 22}], _aether._userInfo, false);\n                                                _aether.logStatementStart([{ofs: 2143, row: 79, col: 4}, {ofs: 2637, row: 100, col: 5}]); tmp463 = tmp448 === tmp462;  _aether.logStatement([{ofs: 2143, row: 79, col: 4}, {ofs: 2637, row: 100, col: 5}], _aether._userInfo, false);\n                                                if (tmp463) {\n                                                    _aether.logStatementStart([{ofs: 2516, row: 94, col: 19}, {ofs: 2519, row: 94, col: 22}]); tmp464 = 100;  _aether.logStatement([{ofs: 2516, row: 94, col: 19}, {ofs: 2519, row: 94, col: 22}], _aether._userInfo, false);\n                                                    return _aether.restoreAPIClone(_aether, tmp464);\n                                                } else {\n                                                    _aether.logStatementStart([{ofs: 2486, row: 93, col: 13}, {ofs: 2495, row: 93, col: 22}]); tmp459 = 'brawler';  _aether.logStatement([{ofs: 2486, row: 93, col: 13}, {ofs: 2495, row: 93, col: 22}], _aether._userInfo, false);\n                                                    _aether.logStatementStart([{ofs: 2143, row: 79, col: 4}, {ofs: 2637, row: 100, col: 5}]); tmp460 = tmp448 === tmp459;  _aether.logStatement([{ofs: 2143, row: 79, col: 4}, {ofs: 2637, row: 100, col: 5}], _aether._userInfo, false);\n                                                    if (tmp460) {\n                                                        _aether.logStatementStart([{ofs: 2516, row: 94, col: 19}, {ofs: 2519, row: 94, col: 22}]); tmp461 = 100;  _aether.logStatement([{ofs: 2516, row: 94, col: 19}, {ofs: 2519, row: 94, col: 22}], _aether._userInfo, false);\n                                                        return _aether.restoreAPIClone(_aether, tmp461);\n                                                    } else {\n                                                        _aether.logStatementStart([{ofs: 2534, row: 95, col: 13}, {ofs: 2540, row: 95, col: 19}]); tmp456 = 'base';  _aether.logStatement([{ofs: 2534, row: 95, col: 13}, {ofs: 2540, row: 95, col: 19}], _aether._userInfo, false);\n                                                        _aether.logStatementStart([{ofs: 2143, row: 79, col: 4}, {ofs: 2637, row: 100, col: 5}]); tmp457 = tmp448 === tmp456;  _aether.logStatement([{ofs: 2143, row: 79, col: 4}, {ofs: 2637, row: 100, col: 5}], _aether._userInfo, false);\n                                                        if (tmp457) {\n                                                            _aether.logStatementStart([{ofs: 2561, row: 96, col: 19}, {ofs: 2562, row: 96, col: 20}]); tmp458 = 0;  _aether.logStatement([{ofs: 2561, row: 96, col: 19}, {ofs: 2562, row: 96, col: 20}], _aether._userInfo, false);\n                                                            return _aether.restoreAPIClone(_aether, tmp458);\n                                                        } else {\n                                                            _aether.logStatementStart([{ofs: 2577, row: 97, col: 13}, {ofs: 2586, row: 97, col: 22}]); tmp453 = 'peasant';  _aether.logStatement([{ofs: 2577, row: 97, col: 13}, {ofs: 2586, row: 97, col: 22}], _aether._userInfo, false);\n                                                            _aether.logStatementStart([{ofs: 2143, row: 79, col: 4}, {ofs: 2637, row: 100, col: 5}]); tmp454 = tmp448 === tmp453;  _aether.logStatement([{ofs: 2143, row: 79, col: 4}, {ofs: 2637, row: 100, col: 5}], _aether._userInfo, false);\n                                                            if (tmp454) {\n                                                                _aether.logStatementStart([{ofs: 2628, row: 99, col: 19}, {ofs: 2630, row: 99, col: 21}]); tmp455 = 50;  _aether.logStatement([{ofs: 2628, row: 99, col: 19}, {ofs: 2630, row: 99, col: 21}], _aether._userInfo, false);\n                                                                return _aether.restoreAPIClone(_aether, tmp455);\n                                                            } else {\n                                                                _aether.logStatementStart([{ofs: 2601, row: 98, col: 13}, {ofs: 2607, row: 98, col: 19}]); tmp450 = 'peon';  _aether.logStatement([{ofs: 2601, row: 98, col: 13}, {ofs: 2607, row: 98, col: 19}], _aether._userInfo, false);\n                                                                _aether.logStatementStart([{ofs: 2143, row: 79, col: 4}, {ofs: 2637, row: 100, col: 5}]); tmp451 = tmp448 === tmp450;  _aether.logStatement([{ofs: 2143, row: 79, col: 4}, {ofs: 2637, row: 100, col: 5}], _aether._userInfo, false);\n                                                                if (tmp451) {\n                                                                    _aether.logStatementStart([{ofs: 2628, row: 99, col: 19}, {ofs: 2630, row: 99, col: 21}]); tmp452 = 50;  _aether.logStatement([{ofs: 2628, row: 99, col: 19}, {ofs: 2630, row: 99, col: 21}], _aether._userInfo, false);\n                                                                    return _aether.restoreAPIClone(_aether, tmp452);\n                                                                } else {\n                                                                    ;\n                                                                }\n                                                            }\n                                                        }\n                                                    }\n                                                }\n                                            }\n                                        }\n                                    }\n                                }\n                            }\n                        }\n                    }\n                }\n            }\n            return;\n        };  _aether.logStatement([{ofs: 2109, row: 78, col: 0}, {ofs: 2639, row: 101, col: 1}], _aether._userInfo, false);\n        _aether.logStatementStart([{ofs: 2715, row: 104, col: 0}, {ofs: 2909, row: 111, col: 1}]); valuateFighters = function (fighters) {\n            var score, i, len, tmp489, tmp490, tmp491, tmp492, tmp493, tmp494, tmp495, tmp496, tmp497, tmp500, tmp501, tmp502, tmp503, tmp504, tmp505, tmp506, tmp507, tmp508, tmp509; fighters = _aether.createAPIClone(_aether, fighters); for(var __argIndexer = 0; __argIndexer < arguments.length; ++__argIndexer) arguments[__argIndexer] = _aether.createAPIClone(_aether, arguments[__argIndexer]);\n            _aether.logStatementStart([{ofs: 2756, row: 105, col: 4}, {ofs: 2770, row: 105, col: 18}]); score = 0;  _aether.logStatement([{ofs: 2756, row: 105, col: 4}, {ofs: 2770, row: 105, col: 18}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 2780, row: 106, col: 9}, {ofs: 2812, row: 106, col: 41}]); i = 0;  _aether.logStatement([{ofs: 2780, row: 106, col: 9}, {ofs: 2812, row: 106, col: 41}], _aether._userInfo, false);\n            tmp489 = fighters;\n            tmp490 = 'length';\n            _aether.logStatementStart([{ofs: 2780, row: 106, col: 9}, {ofs: 2812, row: 106, col: 41}]); len = tmp489[tmp490];  _aether.logStatement([{ofs: 2780, row: 106, col: 9}, {ofs: 2812, row: 106, col: 41}], _aether._userInfo, false);\n            tmp492 = i;\n            tmp493 = len;\n            _aether.logStatementStart([{ofs: 2814, row: 106, col: 43}, {ofs: 2821, row: 106, col: 50}]); tmp491 = tmp492 < tmp493;  _aether.logStatement([{ofs: 2814, row: 106, col: 43}, {ofs: 2821, row: 106, col: 50}], _aether._userInfo, false);\n            tmp498: {\n                while (tmp491) {\n                    tmp499: {\n                        tmp501 = valueFighter;\n                        tmp505 = fighters;\n                        tmp506 = i;\n                        _aether.logStatementStart([{ofs: 2860, row: 107, col: 30}, {ofs: 2871, row: 107, col: 41}]); tmp503 = tmp505[tmp506];  _aether.logStatement([{ofs: 2860, row: 107, col: 30}, {ofs: 2871, row: 107, col: 41}], _aether._userInfo, false);\n                        tmp504 = 'type';\n                        _aether.logStatementStart([{ofs: 2860, row: 107, col: 30}, {ofs: 2876, row: 107, col: 46}]); tmp502 = tmp503[tmp504];  _aether.logStatement([{ofs: 2860, row: 107, col: 30}, {ofs: 2876, row: 107, col: 46}], _aether._userInfo, false);\n                        _aether.logStatementStart([{ofs: 2838, row: 107, col: 8}, {ofs: 2878, row: 107, col: 48}]); tmp500 = _aether.createAPIClone(_aether, tmp501(_aether.restoreAPIClone(_aether, tmp502)));  _aether.logStatement([{ofs: 2838, row: 107, col: 8}, {ofs: 2878, row: 107, col: 48}], _aether._userInfo, false);\n                        tmp507 = score;\n                        tmp508 = tmp500;\n                        score = tmp507 + tmp508;\n                    }\n                    tmp496 = i;\n                    tmp497 = 1;\n                    i = tmp496 + tmp497;\n                    tmp494 = i;\n                    tmp495 = len;\n                    _aether.logStatementStart([{ofs: 2814, row: 106, col: 43}, {ofs: 2821, row: 106, col: 50}]); tmp491 = tmp494 < tmp495;  _aether.logStatement([{ofs: 2814, row: 106, col: 43}, {ofs: 2821, row: 106, col: 50}], _aether._userInfo, false);\n                }\n            }\n            tmp509 = score;\n            return _aether.restoreAPIClone(_aether, tmp509);\n        };  _aether.logStatement([{ofs: 2715, row: 104, col: 0}, {ofs: 2909, row: 111, col: 1}], _aether._userInfo, false);\n        _aether.logStatementStart([{ofs: 2993, row: 115, col: 0}, {ofs: 3452, row: 132, col: 1}]); computeMinDistances = function (peasants, coins) {\n            var dict, i, len, coin, winScore, j, pLen, dist, tmp510, tmp511, tmp512, tmp513, tmp514, tmp515, tmp516, tmp517, tmp518, tmp521, tmp522, tmp523, tmp524, tmp525, tmp526, tmp527, tmp528, tmp529, tmp530, tmp531, tmp534, tmp535, tmp536, tmp537, tmp538, tmp539, tmp540, tmp541, tmp542, tmp543, tmp544, tmp545, tmp546, tmp547, tmp548, tmp549, tmp550, tmp551; peasants = _aether.createAPIClone(_aether, peasants); coins = _aether.createAPIClone(_aether, coins); for(var __argIndexer = 0; __argIndexer < arguments.length; ++__argIndexer) arguments[__argIndexer] = _aether.createAPIClone(_aether, arguments[__argIndexer]);\n            _aether.logStatementStart([{ofs: 3045, row: 116, col: 4}, {ofs: 3059, row: 116, col: 18}]); dict = {};  _aether.logStatement([{ofs: 3045, row: 116, col: 4}, {ofs: 3059, row: 116, col: 18}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 3070, row: 118, col: 9}, {ofs: 3099, row: 118, col: 38}]); i = 0;  _aether.logStatement([{ofs: 3070, row: 118, col: 9}, {ofs: 3099, row: 118, col: 38}], _aether._userInfo, false);\n            tmp510 = coins;\n            tmp511 = 'length';\n            _aether.logStatementStart([{ofs: 3070, row: 118, col: 9}, {ofs: 3099, row: 118, col: 38}]); len = tmp510[tmp511];  _aether.logStatement([{ofs: 3070, row: 118, col: 9}, {ofs: 3099, row: 118, col: 38}], _aether._userInfo, false);\n            tmp513 = i;\n            tmp514 = len;\n            _aether.logStatementStart([{ofs: 3101, row: 118, col: 40}, {ofs: 3108, row: 118, col: 47}]); tmp512 = tmp513 < tmp514;  _aether.logStatement([{ofs: 3101, row: 118, col: 40}, {ofs: 3108, row: 118, col: 47}], _aether._userInfo, false);\n            tmp519: {\n                while (tmp512) {\n                    tmp520: {\n                        tmp521 = coins;\n                        tmp522 = i;\n                        _aether.logStatementStart([{ofs: 3125, row: 119, col: 8}, {ofs: 3145, row: 119, col: 28}]); coin = tmp521[tmp522];  _aether.logStatement([{ofs: 3125, row: 119, col: 8}, {ofs: 3145, row: 119, col: 28}], _aether._userInfo, false);\n                        _aether.logStatementStart([{ofs: 3154, row: 120, col: 8}, {ofs: 3175, row: 120, col: 29}]); winScore = 10000;  _aether.logStatement([{ofs: 3154, row: 120, col: 8}, {ofs: 3175, row: 120, col: 29}], _aether._userInfo, false);\n                        _aether.logStatementStart([{ofs: 3189, row: 121, col: 13}, {ofs: 3222, row: 121, col: 46}]); j = 0;  _aether.logStatement([{ofs: 3189, row: 121, col: 13}, {ofs: 3222, row: 121, col: 46}], _aether._userInfo, false);\n                        tmp523 = peasants;\n                        tmp524 = 'length';\n                        _aether.logStatementStart([{ofs: 3189, row: 121, col: 13}, {ofs: 3222, row: 121, col: 46}]); pLen = tmp523[tmp524];  _aether.logStatement([{ofs: 3189, row: 121, col: 13}, {ofs: 3222, row: 121, col: 46}], _aether._userInfo, false);\n                        tmp526 = j;\n                        tmp527 = pLen;\n                        _aether.logStatementStart([{ofs: 3224, row: 121, col: 48}, {ofs: 3232, row: 121, col: 56}]); tmp525 = tmp526 < tmp527;  _aether.logStatement([{ofs: 3224, row: 121, col: 48}, {ofs: 3232, row: 121, col: 56}], _aether._userInfo, false);\n                        tmp532: {\n                            while (tmp525) {\n                                tmp533: {\n                                    tmp536 = coin;\n                                    tmp537 = 'pos';\n                                    _aether.logStatementStart([{ofs: 3264, row: 122, col: 23}, {ofs: 3272, row: 122, col: 31}]); tmp534 = tmp536[tmp537];  _aether.logStatement([{ofs: 3264, row: 122, col: 23}, {ofs: 3272, row: 122, col: 31}], _aether._userInfo, false);\n                                    tmp535 = 'distance';\n                                    tmp541 = peasants;\n                                    tmp542 = j;\n                                    _aether.logStatementStart([{ofs: 3282, row: 122, col: 41}, {ofs: 3293, row: 122, col: 52}]); tmp539 = tmp541[tmp542];  _aether.logStatement([{ofs: 3282, row: 122, col: 41}, {ofs: 3293, row: 122, col: 52}], _aether._userInfo, false);\n                                    tmp540 = 'pos';\n                                    _aether.logStatementStart([{ofs: 3282, row: 122, col: 41}, {ofs: 3297, row: 122, col: 56}]); tmp538 = tmp539[tmp540];  _aether.logStatement([{ofs: 3282, row: 122, col: 41}, {ofs: 3297, row: 122, col: 56}], _aether._userInfo, false);\n                                    _aether.logStatementStart([{ofs: 3253, row: 122, col: 12}, {ofs: 3299, row: 122, col: 58}]); dist = _aether.createAPIClone(_aether, tmp534[tmp535](_aether.restoreAPIClone(_aether, tmp538)));  _aether.logStatement([{ofs: 3253, row: 122, col: 12}, {ofs: 3299, row: 122, col: 58}], _aether._userInfo, false);\n                                    tmp544 = dist;\n                                    tmp545 = winScore;\n                                    _aether.logStatementStart([{ofs: 3316, row: 123, col: 16}, {ofs: 3331, row: 123, col: 31}]); tmp543 = tmp544 < tmp545;  _aether.logStatement([{ofs: 3316, row: 123, col: 16}, {ofs: 3331, row: 123, col: 31}], _aether._userInfo, false);\n                                    if (tmp543) {\n                                        winScore = dist;\n                                    } else {\n                                        ;\n                                    }\n                                }\n                                tmp530 = j;\n                                tmp531 = 1;\n                                j = tmp530 + tmp531;\n                                tmp528 = j;\n                                tmp529 = pLen;\n                                _aether.logStatementStart([{ofs: 3224, row: 121, col: 48}, {ofs: 3232, row: 121, col: 56}]); tmp525 = tmp528 < tmp529;  _aether.logStatement([{ofs: 3224, row: 121, col: 48}, {ofs: 3232, row: 121, col: 56}], _aether._userInfo, false);\n                            }\n                        }\n                        tmp546 = dict;\n                        tmp548 = coin;\n                        tmp549 = 'id';\n                        _aether.logStatementStart([{ofs: 3406, row: 128, col: 13}, {ofs: 3413, row: 128, col: 20}]); tmp547 = tmp548[tmp549];  _aether.logStatement([{ofs: 3406, row: 128, col: 13}, {ofs: 3413, row: 128, col: 20}], _aether._userInfo, false);\n                        tmp550 = winScore;\n                        _aether.logStatementStart([{ofs: 3401, row: 128, col: 8}, {ofs: 3425, row: 128, col: 32}]); tmp546[tmp547] = tmp550;  _aether.logStatement([{ofs: 3401, row: 128, col: 8}, {ofs: 3425, row: 128, col: 32}], _aether._userInfo, false);\n                    }\n                    tmp517 = i;\n                    tmp518 = 1;\n                    i = tmp517 + tmp518;\n                    tmp515 = i;\n                    tmp516 = len;\n                    _aether.logStatementStart([{ofs: 3101, row: 118, col: 40}, {ofs: 3108, row: 118, col: 47}]); tmp512 = tmp515 < tmp516;  _aether.logStatement([{ofs: 3101, row: 118, col: 40}, {ofs: 3108, row: 118, col: 47}], _aether._userInfo, false);\n                }\n            }\n            tmp551 = dict;\n            return _aether.restoreAPIClone(_aether, tmp551);\n        };  _aether.logStatement([{ofs: 2993, row: 115, col: 0}, {ofs: 3452, row: 132, col: 1}], _aether._userInfo, false);\n        _aether.logStatementStart([{ofs: 3454, row: 134, col: 0}, {ofs: 3675, row: 141, col: 1}]); computeEnemyMult = function (ourDistance, enemyDistance) {\n            var enemyDistFrac, tmp552, tmp553, tmp554, tmp555, tmp556, tmp557, tmp558, tmp559, tmp560; ourDistance = _aether.createAPIClone(_aether, ourDistance); enemyDistance = _aether.createAPIClone(_aether, enemyDistance); for(var __argIndexer = 0; __argIndexer < arguments.length; ++__argIndexer) arguments[__argIndexer] = _aether.createAPIClone(_aether, arguments[__argIndexer]);\n            tmp554 = ourDistance;\n            tmp555 = enemyDistance;\n            _aether.logStatementStart([{ofs: 3535, row: 135, col: 25}, {ofs: 3562, row: 135, col: 52}]); tmp552 = tmp554 + tmp555;  _aether.logStatement([{ofs: 3535, row: 135, col: 25}, {ofs: 3562, row: 135, col: 52}], _aether._userInfo, false);\n            tmp553 = enemyDistance;\n            _aether.logStatementStart([{ofs: 3514, row: 135, col: 4}, {ofs: 3580, row: 135, col: 70}]); enemyDistFrac = tmp552 / tmp553;  _aether.logStatement([{ofs: 3514, row: 135, col: 4}, {ofs: 3580, row: 135, col: 70}], _aether._userInfo, false);\n            tmp557 = enemyDistFrac;\n            _aether.logStatementStart([{ofs: 3605, row: 136, col: 24}, {ofs: 3617, row: 136, col: 36}]); tmp558 = 2.2222222222;  _aether.logStatement([{ofs: 3605, row: 136, col: 24}, {ofs: 3617, row: 136, col: 36}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 3589, row: 136, col: 8}, {ofs: 3617, row: 136, col: 36}]); tmp556 = tmp557 > tmp558;  _aether.logStatement([{ofs: 3589, row: 136, col: 8}, {ofs: 3617, row: 136, col: 36}], _aether._userInfo, false);\n            if (tmp556) {\n                _aether.logStatementStart([{ofs: 3636, row: 137, col: 15}, {ofs: 3639, row: 137, col: 18}]); tmp559 = 0.5;  _aether.logStatement([{ofs: 3636, row: 137, col: 15}, {ofs: 3639, row: 137, col: 18}], _aether._userInfo, false);\n                return _aether.restoreAPIClone(_aether, tmp559);\n            } else {\n                ;\n            }\n            tmp560 = enemyDistFrac;\n            return _aether.restoreAPIClone(_aether, tmp560);\n        };  _aether.logStatement([{ofs: 3454, row: 134, col: 0}, {ofs: 3675, row: 141, col: 1}], _aether._userInfo, false);\n        _aether.logStatementStart([{ofs: 3677, row: 143, col: 0}, {ofs: 3988, row: 148, col: 1}]); computeAttractionSquared = function (itemPos, attractorPos, attractorMass) {\n            var distance, strength, direction, tmp561, tmp562, tmp563, tmp564, tmp565, tmp566, tmp567, tmp568, tmp569, tmp570, tmp571, tmp572, tmp573, tmp574, tmp575, tmp576, tmp577, tmp578, tmp579, tmp580, tmp581, tmp582; itemPos = _aether.createAPIClone(_aether, itemPos); attractorPos = _aether.createAPIClone(_aether, attractorPos); attractorMass = _aether.createAPIClone(_aether, attractorMass); for(var __argIndexer = 0; __argIndexer < arguments.length; ++__argIndexer) arguments[__argIndexer] = _aether.createAPIClone(_aether, arguments[__argIndexer]);\n            tmp561 = itemPos;\n            tmp562 = 'distance';\n            tmp563 = attractorPos;\n            _aether.logStatementStart([{ofs: 3755, row: 144, col: 4}, {ofs: 3801, row: 144, col: 50}]); distance = _aether.createAPIClone(_aether, tmp561[tmp562](_aether.restoreAPIClone(_aether, tmp563)));  _aether.logStatement([{ofs: 3755, row: 144, col: 4}, {ofs: 3801, row: 144, col: 50}], _aether._userInfo, false);\n            tmp564 = attractorMass;\n            tmp566 = distance;\n            tmp567 = distance;\n            _aether.logStatementStart([{ofs: 3838, row: 145, col: 36}, {ofs: 3857, row: 145, col: 55}]); tmp565 = tmp566 * tmp567;  _aether.logStatement([{ofs: 3838, row: 145, col: 36}, {ofs: 3857, row: 145, col: 55}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 3806, row: 145, col: 4}, {ofs: 3859, row: 145, col: 57}]); strength = tmp564 / tmp565;  _aether.logStatement([{ofs: 3806, row: 145, col: 4}, {ofs: 3859, row: 145, col: 57}], _aether._userInfo, false);\n            tmp570 = 'Vector';\n            tmp568 = __global[tmp570];\n            tmp569 = 'normalize';\n            tmp574 = 'Vector';\n            tmp572 = __global[tmp574];\n            tmp573 = 'subtract';\n            tmp575 = attractorPos;\n            tmp576 = itemPos;\n            _aether.logStatementStart([{ofs: 3897, row: 146, col: 37}, {ofs: 3935, row: 146, col: 75}]); tmp571 = _aether.createAPIClone(_aether, tmp572[tmp573](_aether.restoreAPIClone(_aether, tmp575), _aether.restoreAPIClone(_aether, tmp576)));  _aether.logStatement([{ofs: 3897, row: 146, col: 37}, {ofs: 3935, row: 146, col: 75}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 3864, row: 146, col: 4}, {ofs: 3937, row: 146, col: 77}]); direction = _aether.createAPIClone(_aether, tmp568[tmp569](_aether.restoreAPIClone(_aether, tmp571)));  _aether.logStatement([{ofs: 3864, row: 146, col: 4}, {ofs: 3937, row: 146, col: 77}], _aether._userInfo, false);\n            tmp580 = 'Vector';\n            tmp578 = __global[tmp580];\n            tmp579 = 'multiply';\n            tmp581 = direction;\n            tmp582 = strength;\n            _aether.logStatementStart([{ofs: 3949, row: 147, col: 11}, {ofs: 3985, row: 147, col: 47}]); tmp577 = _aether.createAPIClone(_aether, tmp578[tmp579](_aether.restoreAPIClone(_aether, tmp581), _aether.restoreAPIClone(_aether, tmp582)));  _aether.logStatement([{ofs: 3949, row: 147, col: 11}, {ofs: 3985, row: 147, col: 47}], _aether._userInfo, false);\n            return _aether.restoreAPIClone(_aether, tmp577);\n        };  _aether.logStatement([{ofs: 3677, row: 143, col: 0}, {ofs: 3988, row: 148, col: 1}], _aether._userInfo, false);\n        _aether.logStatementStart([{ofs: 3990, row: 150, col: 0}, {ofs: 6161, row: 202, col: 1}]); computeSpringAssignments = function (friends, enemies, coins, computeAttraction) {\n            var WALL_ATTRACTION, FRIEND_ATTRACTION, DIRECTION_CASTAHEAD, ARENA_WIDTH, ARENA_HEIGHT, limits, assignments, i, fLen, friend, friendPos, force, j, cLen, coin, coinPos, dist, enemyDist, strength, direction, k, newPos, tmp583, tmp584, tmp585, tmp586, tmp587, tmp588, tmp589, tmp590, tmp591, tmp592, tmp593, tmp594, tmp595, tmp596, tmp599, tmp600, tmp601, tmp602, tmp603, tmp604, tmp605, tmp606, tmp607, tmp608, tmp609, tmp610, tmp611, tmp612, tmp613, tmp614, tmp615, tmp618, tmp619, tmp620, tmp621, tmp622, tmp623, tmp624, tmp625, tmp626, tmp627, tmp628, tmp629, tmp630, tmp631, tmp632, tmp633, tmp634, tmp635, tmp636, tmp637, tmp638, tmp639, tmp640, tmp641, tmp642, tmp643, tmp644, tmp645, tmp646, tmp647, tmp648, tmp649, tmp650, tmp651, tmp652, tmp653, tmp654, tmp655, tmp656, tmp657, tmp658, tmp659, tmp660, tmp661, tmp662, tmp663, tmp664, tmp665, tmp668, tmp669, tmp670, tmp671, tmp672, tmp673, tmp674, tmp675, tmp676, tmp677, tmp678, tmp679, tmp680, tmp681, tmp682, tmp683, tmp684, tmp685, tmp686, tmp687, tmp688, tmp689, tmp690, tmp691, tmp692, tmp693, tmp694, tmp695, tmp696, tmp697, tmp698, tmp699, tmp700, tmp701, tmp702, tmp703, tmp704, tmp705, tmp706, tmp707, tmp708, tmp709, tmp710, tmp711, tmp712, tmp713, tmp714, tmp715, tmp716, tmp717, tmp718, tmp719, tmp720, tmp721, tmp722, tmp723, tmp724, tmp725, tmp726, tmp727, tmp728, tmp729, tmp730, tmp731, tmp732, tmp733, tmp734, tmp735, tmp736, tmp737, tmp738, tmp739, tmp740, tmp741, tmp742, tmp743, tmp744, tmp745, tmp746, tmp747, tmp748, tmp749, tmp750, tmp751, tmp752, tmp753, tmp754, tmp755, tmp756, tmp757, tmp758, tmp759, tmp760, tmp761, tmp762, tmp763, tmp764, tmp765, tmp766, tmp767, tmp768, tmp769, tmp770, tmp771, tmp772, tmp773, tmp774, tmp775, tmp776, tmp777, tmp778, tmp779, tmp780, tmp781, tmp782, tmp783, tmp784, tmp785, tmp786, tmp787, tmp788, tmp789, tmp790, tmp791, tmp792, tmp793, tmp794, tmp795, tmp796, tmp797, tmp798; friends = _aether.createAPIClone(_aether, friends); enemies = _aether.createAPIClone(_aether, enemies); coins = _aether.createAPIClone(_aether, coins); computeAttraction = _aether.createAPIClone(_aether, computeAttraction); for(var __argIndexer = 0; __argIndexer < arguments.length; ++__argIndexer) arguments[__argIndexer] = _aether.createAPIClone(_aether, arguments[__argIndexer]);\n            _aether.logStatementStart([{ofs: 4097, row: 151, col: 27}, {ofs: 4098, row: 151, col: 28}]); tmp583 = 1;  _aether.logStatement([{ofs: 4097, row: 151, col: 27}, {ofs: 4098, row: 151, col: 28}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 4074, row: 151, col: 4}, {ofs: 4099, row: 151, col: 29}]); WALL_ATTRACTION = -tmp583;  _aether.logStatement([{ofs: 4074, row: 151, col: 4}, {ofs: 4099, row: 151, col: 29}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 4129, row: 152, col: 29}, {ofs: 4130, row: 152, col: 30}]); tmp584 = 5;  _aether.logStatement([{ofs: 4129, row: 152, col: 29}, {ofs: 4130, row: 152, col: 30}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 4104, row: 152, col: 4}, {ofs: 4131, row: 152, col: 31}]); FRIEND_ATTRACTION = -tmp584;  _aether.logStatement([{ofs: 4104, row: 152, col: 4}, {ofs: 4131, row: 152, col: 31}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 4137, row: 154, col: 4}, {ofs: 4165, row: 154, col: 32}]); DIRECTION_CASTAHEAD = 6;  _aether.logStatement([{ofs: 4137, row: 154, col: 4}, {ofs: 4165, row: 154, col: 32}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 4175, row: 156, col: 4}, {ofs: 4196, row: 156, col: 25}]); ARENA_WIDTH = 85;  _aether.logStatement([{ofs: 4175, row: 156, col: 4}, {ofs: 4196, row: 156, col: 25}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 4201, row: 157, col: 4}, {ofs: 4223, row: 157, col: 26}]); ARENA_HEIGHT = 70;  _aether.logStatement([{ofs: 4201, row: 157, col: 4}, {ofs: 4223, row: 157, col: 26}], _aether._userInfo, false);\n            tmp585 = computeMinDistances;\n            tmp586 = enemies;\n            tmp587 = coins;\n            _aether.logStatementStart([{ofs: 4233, row: 159, col: 4}, {ofs: 4282, row: 159, col: 53}]); limits = _aether.createAPIClone(_aether, tmp585(_aether.restoreAPIClone(_aether, tmp586), _aether.restoreAPIClone(_aether, tmp587)));  _aether.logStatement([{ofs: 4233, row: 159, col: 4}, {ofs: 4282, row: 159, col: 53}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 4292, row: 161, col: 4}, {ofs: 4313, row: 161, col: 25}]); assignments = [];  _aether.logStatement([{ofs: 4292, row: 161, col: 4}, {ofs: 4313, row: 161, col: 25}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 4328, row: 163, col: 9}, {ofs: 4360, row: 163, col: 41}]); i = 0;  _aether.logStatement([{ofs: 4328, row: 163, col: 9}, {ofs: 4360, row: 163, col: 41}], _aether._userInfo, false);\n            tmp588 = friends;\n            tmp589 = 'length';\n            _aether.logStatementStart([{ofs: 4328, row: 163, col: 9}, {ofs: 4360, row: 163, col: 41}]); fLen = tmp588[tmp589];  _aether.logStatement([{ofs: 4328, row: 163, col: 9}, {ofs: 4360, row: 163, col: 41}], _aether._userInfo, false);\n            tmp591 = i;\n            tmp592 = fLen;\n            _aether.logStatementStart([{ofs: 4362, row: 163, col: 43}, {ofs: 4370, row: 163, col: 51}]); tmp590 = tmp591 < tmp592;  _aether.logStatement([{ofs: 4362, row: 163, col: 43}, {ofs: 4370, row: 163, col: 51}], _aether._userInfo, false);\n            tmp597: {\n                while (tmp590) {\n                    tmp598: {\n                        tmp599 = friends;\n                        tmp600 = i;\n                        _aether.logStatementStart([{ofs: 4387, row: 164, col: 8}, {ofs: 4411, row: 164, col: 32}]); friend = tmp599[tmp600];  _aether.logStatement([{ofs: 4387, row: 164, col: 8}, {ofs: 4411, row: 164, col: 32}], _aether._userInfo, false);\n                        tmp601 = friend;\n                        tmp602 = 'pos';\n                        _aether.logStatementStart([{ofs: 4420, row: 165, col: 8}, {ofs: 4447, row: 165, col: 35}]); friendPos = tmp601[tmp602];  _aether.logStatement([{ofs: 4420, row: 165, col: 8}, {ofs: 4447, row: 165, col: 35}], _aether._userInfo, false);\n                        tmp604 = 'Vector';\n                        tmp603 = __global[tmp604];\n                        _aether.logStatementStart([{ofs: 4488, row: 167, col: 31}, {ofs: 4489, row: 167, col: 32}]); tmp605 = 0;  _aether.logStatement([{ofs: 4488, row: 167, col: 31}, {ofs: 4489, row: 167, col: 32}], _aether._userInfo, false);\n                        _aether.logStatementStart([{ofs: 4491, row: 167, col: 34}, {ofs: 4492, row: 167, col: 35}]); tmp606 = 0;  _aether.logStatement([{ofs: 4491, row: 167, col: 34}, {ofs: 4492, row: 167, col: 35}], _aether._userInfo, false);\n                        _aether.logStatementStart([{ofs: 4465, row: 167, col: 8}, {ofs: 4494, row: 167, col: 37}]); force = new tmp603(tmp605, tmp606);  _aether.logStatement([{ofs: 4465, row: 167, col: 8}, {ofs: 4494, row: 167, col: 37}], _aether._userInfo, false);\n                        _aether.logStatementStart([{ofs: 4517, row: 169, col: 13}, {ofs: 4547, row: 169, col: 43}]); j = 0;  _aether.logStatement([{ofs: 4517, row: 169, col: 13}, {ofs: 4547, row: 169, col: 43}], _aether._userInfo, false);\n                        tmp607 = coins;\n                        tmp608 = 'length';\n                        _aether.logStatementStart([{ofs: 4517, row: 169, col: 13}, {ofs: 4547, row: 169, col: 43}]); cLen = tmp607[tmp608];  _aether.logStatement([{ofs: 4517, row: 169, col: 13}, {ofs: 4547, row: 169, col: 43}], _aether._userInfo, false);\n                        tmp610 = j;\n                        tmp611 = cLen;\n                        _aether.logStatementStart([{ofs: 4549, row: 169, col: 45}, {ofs: 4557, row: 169, col: 53}]); tmp609 = tmp610 < tmp611;  _aether.logStatement([{ofs: 4549, row: 169, col: 45}, {ofs: 4557, row: 169, col: 53}], _aether._userInfo, false);\n                        tmp616: {\n                            while (tmp609) {\n                                tmp617: {\n                                    tmp618 = coins;\n                                    tmp619 = j;\n                                    _aether.logStatementStart([{ofs: 4578, row: 170, col: 12}, {ofs: 4598, row: 170, col: 32}]); coin = tmp618[tmp619];  _aether.logStatement([{ofs: 4578, row: 170, col: 12}, {ofs: 4598, row: 170, col: 32}], _aether._userInfo, false);\n                                    tmp620 = coin;\n                                    tmp621 = 'pos';\n                                    _aether.logStatementStart([{ofs: 4611, row: 171, col: 12}, {ofs: 4634, row: 171, col: 35}]); coinPos = tmp620[tmp621];  _aether.logStatement([{ofs: 4611, row: 171, col: 12}, {ofs: 4634, row: 171, col: 35}], _aether._userInfo, false);\n                                    tmp622 = friendPos;\n                                    tmp623 = 'distance';\n                                    tmp624 = coinPos;\n                                    _aether.logStatementStart([{ofs: 4647, row: 172, col: 12}, {ofs: 4686, row: 172, col: 51}]); dist = _aether.createAPIClone(_aether, tmp622[tmp623](_aether.restoreAPIClone(_aether, tmp624)));  _aether.logStatement([{ofs: 4647, row: 172, col: 12}, {ofs: 4686, row: 172, col: 51}], _aether._userInfo, false);\n                                    tmp625 = limits;\n                                    tmp627 = coin;\n                                    tmp628 = 'id';\n                                    _aether.logStatementStart([{ofs: 4722, row: 173, col: 35}, {ofs: 4729, row: 173, col: 42}]); tmp626 = tmp627[tmp628];  _aether.logStatement([{ofs: 4722, row: 173, col: 35}, {ofs: 4729, row: 173, col: 42}], _aether._userInfo, false);\n                                    _aether.logStatementStart([{ofs: 4699, row: 173, col: 12}, {ofs: 4731, row: 173, col: 44}]); enemyDist = tmp625[tmp626];  _aether.logStatement([{ofs: 4699, row: 173, col: 12}, {ofs: 4731, row: 173, col: 44}], _aether._userInfo, false);\n                                    tmp633 = coin;\n                                    tmp634 = 'bountyGold';\n                                    _aether.logStatementStart([{ofs: 4760, row: 174, col: 28}, {ofs: 4775, row: 174, col: 43}]); tmp631 = tmp633[tmp634];  _aether.logStatement([{ofs: 4760, row: 174, col: 28}, {ofs: 4775, row: 174, col: 43}], _aether._userInfo, false);\n                                    tmp635 = computeEnemyMult;\n                                    tmp636 = dist;\n                                    tmp637 = enemyDist;\n                                    _aether.logStatementStart([{ofs: 4778, row: 174, col: 46}, {ofs: 4811, row: 174, col: 79}]); tmp632 = _aether.createAPIClone(_aether, tmp635(_aether.restoreAPIClone(_aether, tmp636), _aether.restoreAPIClone(_aether, tmp637)));  _aether.logStatement([{ofs: 4778, row: 174, col: 46}, {ofs: 4811, row: 174, col: 79}], _aether._userInfo, false);\n                                    _aether.logStatementStart([{ofs: 4760, row: 174, col: 28}, {ofs: 4811, row: 174, col: 79}]); tmp629 = tmp631 * tmp632;  _aether.logStatement([{ofs: 4760, row: 174, col: 28}, {ofs: 4811, row: 174, col: 79}], _aether._userInfo, false);\n                                    tmp638 = dist;\n                                    tmp639 = dist;\n                                    _aether.logStatementStart([{ofs: 4816, row: 174, col: 84}, {ofs: 4827, row: 174, col: 95}]); tmp630 = tmp638 * tmp639;  _aether.logStatement([{ofs: 4816, row: 174, col: 84}, {ofs: 4827, row: 174, col: 95}], _aether._userInfo, false);\n                                    _aether.logStatementStart([{ofs: 4744, row: 174, col: 12}, {ofs: 4829, row: 174, col: 97}]); strength = tmp629 / tmp630;  _aether.logStatement([{ofs: 4744, row: 174, col: 12}, {ofs: 4829, row: 174, col: 97}], _aether._userInfo, false);\n                                    tmp642 = 'Vector';\n                                    tmp640 = __global[tmp642];\n                                    tmp641 = 'normalize';\n                                    tmp646 = 'Vector';\n                                    tmp644 = __global[tmp646];\n                                    tmp645 = 'subtract';\n                                    tmp647 = coinPos;\n                                    tmp648 = friendPos;\n                                    _aether.logStatementStart([{ofs: 4875, row: 175, col: 45}, {ofs: 4910, row: 175, col: 80}]); tmp643 = _aether.createAPIClone(_aether, tmp644[tmp645](_aether.restoreAPIClone(_aether, tmp647), _aether.restoreAPIClone(_aether, tmp648)));  _aether.logStatement([{ofs: 4875, row: 175, col: 45}, {ofs: 4910, row: 175, col: 80}], _aether._userInfo, false);\n                                    _aether.logStatementStart([{ofs: 4842, row: 175, col: 12}, {ofs: 4912, row: 175, col: 82}]); direction = _aether.createAPIClone(_aether, tmp640[tmp641](_aether.restoreAPIClone(_aether, tmp643)));  _aether.logStatement([{ofs: 4842, row: 175, col: 12}, {ofs: 4912, row: 175, col: 82}], _aether._userInfo, false);\n                                    tmp651 = 'Vector';\n                                    tmp649 = __global[tmp651];\n                                    tmp650 = 'add';\n                                    tmp652 = force;\n                                    tmp656 = 'Vector';\n                                    tmp654 = __global[tmp656];\n                                    tmp655 = 'multiply';\n                                    tmp657 = direction;\n                                    tmp658 = strength;\n                                    _aether.logStatementStart([{ofs: 4951, row: 176, col: 38}, {ofs: 4987, row: 176, col: 74}]); tmp653 = _aether.createAPIClone(_aether, tmp654[tmp655](_aether.restoreAPIClone(_aether, tmp657), _aether.restoreAPIClone(_aether, tmp658)));  _aether.logStatement([{ofs: 4951, row: 176, col: 38}, {ofs: 4987, row: 176, col: 74}], _aether._userInfo, false);\n                                    _aether.logStatementStart([{ofs: 4925, row: 176, col: 12}, {ofs: 4989, row: 176, col: 76}]); force = _aether.createAPIClone(_aether, tmp649[tmp650](_aether.restoreAPIClone(_aether, tmp652), _aether.restoreAPIClone(_aether, tmp653)));  _aether.logStatement([{ofs: 4925, row: 176, col: 12}, {ofs: 4989, row: 176, col: 76}], _aether._userInfo, false);\n                                }\n                                tmp614 = j;\n                                tmp615 = 1;\n                                j = tmp614 + tmp615;\n                                tmp612 = j;\n                                tmp613 = cLen;\n                                _aether.logStatementStart([{ofs: 4549, row: 169, col: 45}, {ofs: 4557, row: 169, col: 53}]); tmp609 = tmp612 < tmp613;  _aether.logStatement([{ofs: 4549, row: 169, col: 45}, {ofs: 4557, row: 169, col: 53}], _aether._userInfo, false);\n                            }\n                        }\n                        _aether.logStatementStart([{ofs: 5022, row: 179, col: 13}, {ofs: 5031, row: 179, col: 22}]); k = 0;  _aether.logStatement([{ofs: 5022, row: 179, col: 13}, {ofs: 5031, row: 179, col: 22}], _aether._userInfo, false);\n                        tmp660 = k;\n                        tmp661 = fLen;\n                        _aether.logStatementStart([{ofs: 5033, row: 179, col: 24}, {ofs: 5041, row: 179, col: 32}]); tmp659 = tmp660 < tmp661;  _aether.logStatement([{ofs: 5033, row: 179, col: 24}, {ofs: 5041, row: 179, col: 32}], _aether._userInfo, false);\n                        tmp666: {\n                            while (tmp659) {\n                                tmp667: {\n                                    tmp669 = k;\n                                    tmp670 = i;\n                                    _aether.logStatementStart([{ofs: 5066, row: 180, col: 16}, {ofs: 5073, row: 180, col: 23}]); tmp668 = tmp669 === tmp670;  _aether.logStatement([{ofs: 5066, row: 180, col: 16}, {ofs: 5073, row: 180, col: 23}], _aether._userInfo, false);\n                                    if (tmp668) {\n                                        break tmp667;\n                                    } else {\n                                        ;\n                                    }\n                                    tmp673 = 'Vector';\n                                    tmp671 = __global[tmp673];\n                                    tmp672 = 'add';\n                                    tmp674 = force;\n                                    tmp676 = computeAttraction;\n                                    tmp677 = friendPos;\n                                    tmp682 = friends;\n                                    tmp683 = k;\n                                    _aether.logStatementStart([{ofs: 5197, row: 184, col: 67}, {ofs: 5207, row: 184, col: 77}]); tmp680 = tmp682[tmp683];  _aether.logStatement([{ofs: 5197, row: 184, col: 67}, {ofs: 5207, row: 184, col: 77}], _aether._userInfo, false);\n                                    tmp681 = 'pos';\n                                    _aether.logStatementStart([{ofs: 5197, row: 184, col: 67}, {ofs: 5211, row: 184, col: 81}]); tmp678 = tmp680[tmp681];  _aether.logStatement([{ofs: 5197, row: 184, col: 67}, {ofs: 5211, row: 184, col: 81}], _aether._userInfo, false);\n                                    tmp679 = FRIEND_ATTRACTION;\n                                    _aether.logStatementStart([{ofs: 5168, row: 184, col: 38}, {ofs: 5231, row: 184, col: 101}]); tmp675 = _aether.createAPIClone(_aether, tmp676(_aether.restoreAPIClone(_aether, tmp677), _aether.restoreAPIClone(_aether, tmp678), _aether.restoreAPIClone(_aether, tmp679)));  _aether.logStatement([{ofs: 5168, row: 184, col: 38}, {ofs: 5231, row: 184, col: 101}], _aether._userInfo, false);\n                                    _aether.logStatementStart([{ofs: 5142, row: 184, col: 12}, {ofs: 5233, row: 184, col: 103}]); force = _aether.createAPIClone(_aether, tmp671[tmp672](_aether.restoreAPIClone(_aether, tmp674), _aether.restoreAPIClone(_aether, tmp675)));  _aether.logStatement([{ofs: 5142, row: 184, col: 12}, {ofs: 5233, row: 184, col: 103}], _aether._userInfo, false);\n                                }\n                                tmp664 = k;\n                                tmp665 = 1;\n                                k = tmp664 + tmp665;\n                                tmp662 = k;\n                                tmp663 = fLen;\n                                _aether.logStatementStart([{ofs: 5033, row: 179, col: 24}, {ofs: 5041, row: 179, col: 32}]); tmp659 = tmp662 < tmp663;  _aether.logStatement([{ofs: 5033, row: 179, col: 24}, {ofs: 5041, row: 179, col: 32}], _aether._userInfo, false);\n                            }\n                        }\n                        tmp686 = 'Vector';\n                        tmp684 = __global[tmp686];\n                        tmp685 = 'add';\n                        tmp687 = force;\n                        tmp689 = computeAttraction;\n                        tmp690 = friendPos;\n                        tmp694 = 'Vector';\n                        tmp693 = __global[tmp694];\n                        _aether.logStatementStart([{ofs: 5354, row: 188, col: 75}, {ofs: 5357, row: 188, col: 78}]); tmp697 = 0.1;  _aether.logStatement([{ofs: 5354, row: 188, col: 75}, {ofs: 5357, row: 188, col: 78}], _aether._userInfo, false);\n                        _aether.logStatementStart([{ofs: 5353, row: 188, col: 74}, {ofs: 5357, row: 188, col: 78}]); tmp695 = -tmp697;  _aether.logStatement([{ofs: 5353, row: 188, col: 74}, {ofs: 5357, row: 188, col: 78}], _aether._userInfo, false);\n                        tmp698 = friendPos;\n                        tmp699 = 'y';\n                        _aether.logStatementStart([{ofs: 5359, row: 188, col: 80}, {ofs: 5370, row: 188, col: 91}]); tmp696 = tmp698[tmp699];  _aether.logStatement([{ofs: 5359, row: 188, col: 80}, {ofs: 5370, row: 188, col: 91}], _aether._userInfo, false);\n                        _aether.logStatementStart([{ofs: 5342, row: 188, col: 63}, {ofs: 5371, row: 188, col: 92}]); tmp691 = new tmp693(tmp695, tmp696);  _aether.logStatement([{ofs: 5342, row: 188, col: 63}, {ofs: 5371, row: 188, col: 92}], _aether._userInfo, false);\n                        tmp692 = WALL_ATTRACTION;\n                        _aether.logStatementStart([{ofs: 5313, row: 188, col: 34}, {ofs: 5389, row: 188, col: 110}]); tmp688 = _aether.createAPIClone(_aether, tmp689(_aether.restoreAPIClone(_aether, tmp690), _aether.restoreAPIClone(_aether, tmp691), _aether.restoreAPIClone(_aether, tmp692)));  _aether.logStatement([{ofs: 5313, row: 188, col: 34}, {ofs: 5389, row: 188, col: 110}], _aether._userInfo, false);\n                        _aether.logStatementStart([{ofs: 5287, row: 188, col: 8}, {ofs: 5391, row: 188, col: 112}]); force = _aether.createAPIClone(_aether, tmp684[tmp685](_aether.restoreAPIClone(_aether, tmp687), _aether.restoreAPIClone(_aether, tmp688)));  _aether.logStatement([{ofs: 5287, row: 188, col: 8}, {ofs: 5391, row: 188, col: 112}], _aether._userInfo, false);\n                        tmp702 = 'Vector';\n                        tmp700 = __global[tmp702];\n                        tmp701 = 'add';\n                        tmp703 = force;\n                        tmp705 = computeAttraction;\n                        tmp706 = friendPos;\n                        tmp710 = 'Vector';\n                        tmp709 = __global[tmp710];\n                        tmp713 = ARENA_WIDTH;\n                        _aether.logStatementStart([{ofs: 5488, row: 189, col: 88}, {ofs: 5491, row: 189, col: 91}]); tmp714 = 0.1;  _aether.logStatement([{ofs: 5488, row: 189, col: 88}, {ofs: 5491, row: 189, col: 91}], _aether._userInfo, false);\n                        _aether.logStatementStart([{ofs: 5474, row: 189, col: 74}, {ofs: 5491, row: 189, col: 91}]); tmp711 = tmp713 + tmp714;  _aether.logStatement([{ofs: 5474, row: 189, col: 74}, {ofs: 5491, row: 189, col: 91}], _aether._userInfo, false);\n                        tmp715 = friendPos;\n                        tmp716 = 'y';\n                        _aether.logStatementStart([{ofs: 5493, row: 189, col: 93}, {ofs: 5504, row: 189, col: 104}]); tmp712 = tmp715[tmp716];  _aether.logStatement([{ofs: 5493, row: 189, col: 93}, {ofs: 5504, row: 189, col: 104}], _aether._userInfo, false);\n                        _aether.logStatementStart([{ofs: 5463, row: 189, col: 63}, {ofs: 5505, row: 189, col: 105}]); tmp707 = new tmp709(tmp711, tmp712);  _aether.logStatement([{ofs: 5463, row: 189, col: 63}, {ofs: 5505, row: 189, col: 105}], _aether._userInfo, false);\n                        tmp708 = WALL_ATTRACTION;\n                        _aether.logStatementStart([{ofs: 5434, row: 189, col: 34}, {ofs: 5523, row: 189, col: 123}]); tmp704 = _aether.createAPIClone(_aether, tmp705(_aether.restoreAPIClone(_aether, tmp706), _aether.restoreAPIClone(_aether, tmp707), _aether.restoreAPIClone(_aether, tmp708)));  _aether.logStatement([{ofs: 5434, row: 189, col: 34}, {ofs: 5523, row: 189, col: 123}], _aether._userInfo, false);\n                        _aether.logStatementStart([{ofs: 5408, row: 189, col: 8}, {ofs: 5525, row: 189, col: 125}]); force = _aether.createAPIClone(_aether, tmp700[tmp701](_aether.restoreAPIClone(_aether, tmp703), _aether.restoreAPIClone(_aether, tmp704)));  _aether.logStatement([{ofs: 5408, row: 189, col: 8}, {ofs: 5525, row: 189, col: 125}], _aether._userInfo, false);\n                        tmp719 = 'Vector';\n                        tmp717 = __global[tmp719];\n                        tmp718 = 'add';\n                        tmp720 = force;\n                        tmp722 = computeAttraction;\n                        tmp723 = friendPos;\n                        tmp727 = 'Vector';\n                        tmp726 = __global[tmp727];\n                        tmp730 = friendPos;\n                        tmp731 = 'x';\n                        _aether.logStatementStart([{ofs: 5609, row: 190, col: 74}, {ofs: 5620, row: 190, col: 85}]); tmp728 = tmp730[tmp731];  _aether.logStatement([{ofs: 5609, row: 190, col: 74}, {ofs: 5620, row: 190, col: 85}], _aether._userInfo, false);\n                        _aether.logStatementStart([{ofs: 5623, row: 190, col: 88}, {ofs: 5626, row: 190, col: 91}]); tmp732 = 0.1;  _aether.logStatement([{ofs: 5623, row: 190, col: 88}, {ofs: 5626, row: 190, col: 91}], _aether._userInfo, false);\n                        _aether.logStatementStart([{ofs: 5622, row: 190, col: 87}, {ofs: 5626, row: 190, col: 91}]); tmp729 = -tmp732;  _aether.logStatement([{ofs: 5622, row: 190, col: 87}, {ofs: 5626, row: 190, col: 91}], _aether._userInfo, false);\n                        _aether.logStatementStart([{ofs: 5598, row: 190, col: 63}, {ofs: 5627, row: 190, col: 92}]); tmp724 = new tmp726(tmp728, tmp729);  _aether.logStatement([{ofs: 5598, row: 190, col: 63}, {ofs: 5627, row: 190, col: 92}], _aether._userInfo, false);\n                        tmp725 = WALL_ATTRACTION;\n                        _aether.logStatementStart([{ofs: 5569, row: 190, col: 34}, {ofs: 5645, row: 190, col: 110}]); tmp721 = _aether.createAPIClone(_aether, tmp722(_aether.restoreAPIClone(_aether, tmp723), _aether.restoreAPIClone(_aether, tmp724), _aether.restoreAPIClone(_aether, tmp725)));  _aether.logStatement([{ofs: 5569, row: 190, col: 34}, {ofs: 5645, row: 190, col: 110}], _aether._userInfo, false);\n                        _aether.logStatementStart([{ofs: 5543, row: 190, col: 8}, {ofs: 5647, row: 190, col: 112}]); force = _aether.createAPIClone(_aether, tmp717[tmp718](_aether.restoreAPIClone(_aether, tmp720), _aether.restoreAPIClone(_aether, tmp721)));  _aether.logStatement([{ofs: 5543, row: 190, col: 8}, {ofs: 5647, row: 190, col: 112}], _aether._userInfo, false);\n                        tmp735 = 'Vector';\n                        tmp733 = __global[tmp735];\n                        tmp734 = 'add';\n                        tmp736 = force;\n                        tmp738 = computeAttraction;\n                        tmp739 = friendPos;\n                        tmp743 = 'Vector';\n                        tmp742 = __global[tmp743];\n                        tmp746 = friendPos;\n                        tmp747 = 'x';\n                        _aether.logStatementStart([{ofs: 5732, row: 191, col: 74}, {ofs: 5743, row: 191, col: 85}]); tmp744 = tmp746[tmp747];  _aether.logStatement([{ofs: 5732, row: 191, col: 74}, {ofs: 5743, row: 191, col: 85}], _aether._userInfo, false);\n                        tmp748 = ARENA_HEIGHT;\n                        _aether.logStatementStart([{ofs: 5760, row: 191, col: 102}, {ofs: 5763, row: 191, col: 105}]); tmp749 = 0.1;  _aether.logStatement([{ofs: 5760, row: 191, col: 102}, {ofs: 5763, row: 191, col: 105}], _aether._userInfo, false);\n                        _aether.logStatementStart([{ofs: 5745, row: 191, col: 87}, {ofs: 5763, row: 191, col: 105}]); tmp745 = tmp748 + tmp749;  _aether.logStatement([{ofs: 5745, row: 191, col: 87}, {ofs: 5763, row: 191, col: 105}], _aether._userInfo, false);\n                        _aether.logStatementStart([{ofs: 5721, row: 191, col: 63}, {ofs: 5764, row: 191, col: 106}]); tmp740 = new tmp742(tmp744, tmp745);  _aether.logStatement([{ofs: 5721, row: 191, col: 63}, {ofs: 5764, row: 191, col: 106}], _aether._userInfo, false);\n                        tmp741 = WALL_ATTRACTION;\n                        _aether.logStatementStart([{ofs: 5692, row: 191, col: 34}, {ofs: 5782, row: 191, col: 124}]); tmp737 = _aether.createAPIClone(_aether, tmp738(_aether.restoreAPIClone(_aether, tmp739), _aether.restoreAPIClone(_aether, tmp740), _aether.restoreAPIClone(_aether, tmp741)));  _aether.logStatement([{ofs: 5692, row: 191, col: 34}, {ofs: 5782, row: 191, col: 124}], _aether._userInfo, false);\n                        _aether.logStatementStart([{ofs: 5666, row: 191, col: 8}, {ofs: 5784, row: 191, col: 126}]); force = _aether.createAPIClone(_aether, tmp733[tmp734](_aether.restoreAPIClone(_aether, tmp736), _aether.restoreAPIClone(_aether, tmp737)));  _aether.logStatement([{ofs: 5666, row: 191, col: 8}, {ofs: 5784, row: 191, col: 126}], _aether._userInfo, false);\n                        tmp752 = 'Vector';\n                        tmp750 = __global[tmp752];\n                        tmp751 = 'add';\n                        tmp753 = friendPos;\n                        tmp757 = 'Vector';\n                        tmp755 = __global[tmp757];\n                        tmp756 = 'multiply';\n                        tmp762 = 'Vector';\n                        tmp760 = __global[tmp762];\n                        tmp761 = 'normalize';\n                        tmp763 = force;\n                        _aether.logStatementStart([{ofs: 5860, row: 193, col: 59}, {ofs: 5883, row: 193, col: 82}]); tmp758 = _aether.createAPIClone(_aether, tmp760[tmp761](_aether.restoreAPIClone(_aether, tmp763)));  _aether.logStatement([{ofs: 5860, row: 193, col: 59}, {ofs: 5883, row: 193, col: 82}], _aether._userInfo, false);\n                        tmp759 = DIRECTION_CASTAHEAD;\n                        _aether.logStatementStart([{ofs: 5844, row: 193, col: 43}, {ofs: 5905, row: 193, col: 104}]); tmp754 = _aether.createAPIClone(_aether, tmp755[tmp756](_aether.restoreAPIClone(_aether, tmp758), _aether.restoreAPIClone(_aether, tmp759)));  _aether.logStatement([{ofs: 5844, row: 193, col: 43}, {ofs: 5905, row: 193, col: 104}], _aether._userInfo, false);\n                        _aether.logStatementStart([{ofs: 5809, row: 193, col: 8}, {ofs: 5907, row: 193, col: 106}]); newPos = _aether.createAPIClone(_aether, tmp750[tmp751](_aether.restoreAPIClone(_aether, tmp753), _aether.restoreAPIClone(_aether, tmp754)));  _aether.logStatement([{ofs: 5809, row: 193, col: 8}, {ofs: 5907, row: 193, col: 106}], _aether._userInfo, false);\n                        tmp765 = 'Vector';\n                        tmp764 = __global[tmp765];\n                        tmp770 = 'Math';\n                        tmp768 = __global[tmp770];\n                        tmp769 = 'min';\n                        tmp775 = 'Math';\n                        tmp773 = __global[tmp775];\n                        tmp774 = 'max';\n                        tmp778 = newPos;\n                        tmp779 = 'x';\n                        _aether.logStatementStart([{ofs: 5967, row: 195, col: 30}, {ofs: 5975, row: 195, col: 38}]); tmp776 = tmp778[tmp779];  _aether.logStatement([{ofs: 5967, row: 195, col: 30}, {ofs: 5975, row: 195, col: 38}], _aether._userInfo, false);\n                        _aether.logStatementStart([{ofs: 5977, row: 195, col: 40}, {ofs: 5980, row: 195, col: 43}]); tmp777 = 0;  _aether.logStatement([{ofs: 5977, row: 195, col: 40}, {ofs: 5980, row: 195, col: 43}], _aether._userInfo, false);\n                        _aether.logStatementStart([{ofs: 5958, row: 195, col: 21}, {ofs: 5981, row: 195, col: 44}]); tmp771 = _aether.createAPIClone(_aether, tmp773[tmp774](_aether.restoreAPIClone(_aether, tmp776), _aether.restoreAPIClone(_aether, tmp777)));  _aether.logStatement([{ofs: 5958, row: 195, col: 21}, {ofs: 5981, row: 195, col: 44}], _aether._userInfo, false);\n                        tmp772 = ARENA_WIDTH;\n                        _aether.logStatementStart([{ofs: 5949, row: 195, col: 12}, {ofs: 5995, row: 195, col: 58}]); tmp766 = _aether.createAPIClone(_aether, tmp768[tmp769](_aether.restoreAPIClone(_aether, tmp771), _aether.restoreAPIClone(_aether, tmp772)));  _aether.logStatement([{ofs: 5949, row: 195, col: 12}, {ofs: 5995, row: 195, col: 58}], _aether._userInfo, false);\n                        tmp782 = 'Math';\n                        tmp780 = __global[tmp782];\n                        tmp781 = 'min';\n                        tmp787 = 'Math';\n                        tmp785 = __global[tmp787];\n                        tmp786 = 'max';\n                        tmp790 = newPos;\n                        tmp791 = 'y';\n                        _aether.logStatementStart([{ofs: 6027, row: 196, col: 30}, {ofs: 6035, row: 196, col: 38}]); tmp788 = tmp790[tmp791];  _aether.logStatement([{ofs: 6027, row: 196, col: 30}, {ofs: 6035, row: 196, col: 38}], _aether._userInfo, false);\n                        _aether.logStatementStart([{ofs: 6037, row: 196, col: 40}, {ofs: 6040, row: 196, col: 43}]); tmp789 = 0;  _aether.logStatement([{ofs: 6037, row: 196, col: 40}, {ofs: 6040, row: 196, col: 43}], _aether._userInfo, false);\n                        _aether.logStatementStart([{ofs: 6018, row: 196, col: 21}, {ofs: 6041, row: 196, col: 44}]); tmp783 = _aether.createAPIClone(_aether, tmp785[tmp786](_aether.restoreAPIClone(_aether, tmp788), _aether.restoreAPIClone(_aether, tmp789)));  _aether.logStatement([{ofs: 6018, row: 196, col: 21}, {ofs: 6041, row: 196, col: 44}], _aether._userInfo, false);\n                        tmp784 = ARENA_HEIGHT;\n                        _aether.logStatementStart([{ofs: 6009, row: 196, col: 12}, {ofs: 6056, row: 196, col: 59}]); tmp767 = _aether.createAPIClone(_aether, tmp780[tmp781](_aether.restoreAPIClone(_aether, tmp783), _aether.restoreAPIClone(_aether, tmp784)));  _aether.logStatement([{ofs: 6009, row: 196, col: 12}, {ofs: 6056, row: 196, col: 59}], _aether._userInfo, false);\n                        _aether.logStatementStart([{ofs: 5916, row: 194, col: 8}, {ofs: 6058, row: 196, col: 61}]); newPos = new tmp764(tmp766, tmp767);  _aether.logStatement([{ofs: 5916, row: 194, col: 8}, {ofs: 6058, row: 196, col: 61}], _aether._userInfo, false);\n                        tmp792 = assignments;\n                        tmp793 = 'push';\n                        tmp795 = friend;\n                        tmp796 = newPos;\n                        _aether.logStatementStart([{ofs: 6093, row: 198, col: 25}, {ofs: 6122, row: 198, col: 54}]); tmp794 = {\n                            src: tmp795,\n                            target: tmp796\n                        };  _aether.logStatement([{ofs: 6093, row: 198, col: 25}, {ofs: 6122, row: 198, col: 54}], _aether._userInfo, false);\n                        _aether.logStatementStart([{ofs: 6076, row: 198, col: 8}, {ofs: 6123, row: 198, col: 55}]); tmp797 = _aether.createAPIClone(_aether, tmp792[tmp793](_aether.restoreAPIClone(_aether, tmp794)));  _aether.logStatement([{ofs: 6076, row: 198, col: 8}, {ofs: 6123, row: 198, col: 55}], _aether._userInfo, false);\n                    }\n                    tmp595 = i;\n                    tmp596 = 1;\n                    i = tmp595 + tmp596;\n                    tmp593 = i;\n                    tmp594 = fLen;\n                    _aether.logStatementStart([{ofs: 4362, row: 163, col: 43}, {ofs: 4370, row: 163, col: 51}]); tmp590 = tmp593 < tmp594;  _aether.logStatement([{ofs: 4362, row: 163, col: 43}, {ofs: 4370, row: 163, col: 51}], _aether._userInfo, false);\n                }\n            }\n            tmp798 = assignments;\n            return _aether.restoreAPIClone(_aether, tmp798);\n        };  _aether.logStatement([{ofs: 3990, row: 150, col: 0}, {ofs: 6161, row: 202, col: 1}], _aether._userInfo, false);\n        _aether.logStatementStart([{ofs: 6834, row: 224, col: 0}, {ofs: 7486, row: 243, col: 1}]); createRegressionFunc = function (points) {\n            var n, sumX, sumY, meanX, meanY, sumXSquared, sumXY, slope, intercept, tmp799, tmp800, tmp801, tmp802, tmp803, tmp804, tmp810, tmp811, tmp812, tmp813, tmp819, tmp820, tmp821, tmp822, tmp823, tmp824, tmp825, tmp826, tmp836, tmp837, tmp838, tmp839, tmp849, tmp850, tmp851, tmp852, tmp853, tmp854, tmp855, tmp856, tmp857, tmp858, tmp859, tmp860, tmp861, tmp862, tmp863, tmp864, tmp865, tmp866, tmp867; points = _aether.createAPIClone(_aether, points); for(var __argIndexer = 0; __argIndexer < arguments.length; ++__argIndexer) arguments[__argIndexer] = _aether.createAPIClone(_aether, arguments[__argIndexer]);\n            tmp799 = points;\n            tmp800 = 'length';\n            _aether.logStatementStart([{ofs: 6878, row: 225, col: 4}, {ofs: 6900, row: 225, col: 26}]); n = tmp799[tmp800];  _aether.logStatement([{ofs: 6878, row: 225, col: 4}, {ofs: 6900, row: 225, col: 26}], _aether._userInfo, false);\n            tmp801 = points;\n            tmp802 = 'reduce';\n            _aether.logStatementStart([{ofs: 6935, row: 227, col: 29}, {ofs: 6969, row: 227, col: 63}]); tmp803 = function (a, b) {\n                var tmp805, tmp806, tmp807, tmp808, tmp809; a = _aether.createAPIClone(_aether, a); b = _aether.createAPIClone(_aether, b); for(var __argIndexer = 0; __argIndexer < arguments.length; ++__argIndexer) arguments[__argIndexer] = _aether.createAPIClone(_aether, arguments[__argIndexer]);\n                tmp806 = a;\n                tmp808 = b;\n                tmp809 = 'x';\n                _aether.logStatementStart([{ofs: 6963, row: 227, col: 57}, {ofs: 6966, row: 227, col: 60}]); tmp807 = tmp808[tmp809];  _aether.logStatement([{ofs: 6963, row: 227, col: 57}, {ofs: 6966, row: 227, col: 60}], _aether._userInfo, false);\n                _aether.logStatementStart([{ofs: 6959, row: 227, col: 53}, {ofs: 6966, row: 227, col: 60}]); tmp805 = tmp806 + tmp807;  _aether.logStatement([{ofs: 6959, row: 227, col: 53}, {ofs: 6966, row: 227, col: 60}], _aether._userInfo, false);\n                return _aether.restoreAPIClone(_aether, tmp805);\n            };  _aether.logStatement([{ofs: 6935, row: 227, col: 29}, {ofs: 6969, row: 227, col: 63}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 6971, row: 227, col: 65}, {ofs: 6972, row: 227, col: 66}]); tmp804 = 0;  _aether.logStatement([{ofs: 6971, row: 227, col: 65}, {ofs: 6972, row: 227, col: 66}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 6910, row: 227, col: 4}, {ofs: 6974, row: 227, col: 68}]); sumX = _aether.createAPIClone(_aether, tmp801[tmp802](_aether.restoreAPIClone(_aether, tmp803), _aether.restoreAPIClone(_aether, tmp804)));  _aether.logStatement([{ofs: 6910, row: 227, col: 4}, {ofs: 6974, row: 227, col: 68}], _aether._userInfo, false);\n            tmp810 = points;\n            tmp811 = 'reduce';\n            _aether.logStatementStart([{ofs: 7004, row: 228, col: 29}, {ofs: 7038, row: 228, col: 63}]); tmp812 = function (a, b) {\n                var tmp814, tmp815, tmp816, tmp817, tmp818; a = _aether.createAPIClone(_aether, a); b = _aether.createAPIClone(_aether, b); for(var __argIndexer = 0; __argIndexer < arguments.length; ++__argIndexer) arguments[__argIndexer] = _aether.createAPIClone(_aether, arguments[__argIndexer]);\n                tmp815 = a;\n                tmp817 = b;\n                tmp818 = 'y';\n                _aether.logStatementStart([{ofs: 7032, row: 228, col: 57}, {ofs: 7035, row: 228, col: 60}]); tmp816 = tmp817[tmp818];  _aether.logStatement([{ofs: 7032, row: 228, col: 57}, {ofs: 7035, row: 228, col: 60}], _aether._userInfo, false);\n                _aether.logStatementStart([{ofs: 7028, row: 228, col: 53}, {ofs: 7035, row: 228, col: 60}]); tmp814 = tmp815 + tmp816;  _aether.logStatement([{ofs: 7028, row: 228, col: 53}, {ofs: 7035, row: 228, col: 60}], _aether._userInfo, false);\n                return _aether.restoreAPIClone(_aether, tmp814);\n            };  _aether.logStatement([{ofs: 7004, row: 228, col: 29}, {ofs: 7038, row: 228, col: 63}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 7040, row: 228, col: 65}, {ofs: 7041, row: 228, col: 66}]); tmp813 = 0;  _aether.logStatement([{ofs: 7040, row: 228, col: 65}, {ofs: 7041, row: 228, col: 66}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 6979, row: 228, col: 4}, {ofs: 7043, row: 228, col: 68}]); sumY = _aether.createAPIClone(_aether, tmp810[tmp811](_aether.restoreAPIClone(_aether, tmp812), _aether.restoreAPIClone(_aether, tmp813)));  _aether.logStatement([{ofs: 6979, row: 228, col: 4}, {ofs: 7043, row: 228, col: 68}], _aether._userInfo, false);\n            tmp819 = sumX;\n            tmp820 = n;\n            _aether.logStatementStart([{ofs: 7048, row: 229, col: 4}, {ofs: 7069, row: 229, col: 25}]); meanX = tmp819 / tmp820;  _aether.logStatement([{ofs: 7048, row: 229, col: 4}, {ofs: 7069, row: 229, col: 25}], _aether._userInfo, false);\n            tmp821 = sumY;\n            tmp822 = n;\n            _aether.logStatementStart([{ofs: 7074, row: 230, col: 4}, {ofs: 7095, row: 230, col: 25}]); meanY = tmp821 / tmp822;  _aether.logStatement([{ofs: 7074, row: 230, col: 4}, {ofs: 7095, row: 230, col: 25}], _aether._userInfo, false);\n            tmp823 = points;\n            tmp824 = 'reduce';\n            _aether.logStatementStart([{ofs: 7137, row: 232, col: 36}, {ofs: 7179, row: 232, col: 78}]); tmp825 = function (a, b) {\n                var tmp827, tmp828, tmp829, tmp830, tmp831, tmp832, tmp833, tmp834, tmp835; a = _aether.createAPIClone(_aether, a); b = _aether.createAPIClone(_aether, b); for(var __argIndexer = 0; __argIndexer < arguments.length; ++__argIndexer) arguments[__argIndexer] = _aether.createAPIClone(_aether, arguments[__argIndexer]);\n                tmp828 = a;\n                tmp832 = b;\n                tmp833 = 'x';\n                _aether.logStatementStart([{ofs: 7166, row: 232, col: 65}, {ofs: 7169, row: 232, col: 68}]); tmp830 = tmp832[tmp833];  _aether.logStatement([{ofs: 7166, row: 232, col: 65}, {ofs: 7169, row: 232, col: 68}], _aether._userInfo, false);\n                tmp834 = b;\n                tmp835 = 'x';\n                _aether.logStatementStart([{ofs: 7172, row: 232, col: 71}, {ofs: 7175, row: 232, col: 74}]); tmp831 = tmp834[tmp835];  _aether.logStatement([{ofs: 7172, row: 232, col: 71}, {ofs: 7175, row: 232, col: 74}], _aether._userInfo, false);\n                _aether.logStatementStart([{ofs: 7166, row: 232, col: 65}, {ofs: 7175, row: 232, col: 74}]); tmp829 = tmp830 * tmp831;  _aether.logStatement([{ofs: 7166, row: 232, col: 65}, {ofs: 7175, row: 232, col: 74}], _aether._userInfo, false);\n                _aether.logStatementStart([{ofs: 7161, row: 232, col: 60}, {ofs: 7176, row: 232, col: 75}]); tmp827 = tmp828 + tmp829;  _aether.logStatement([{ofs: 7161, row: 232, col: 60}, {ofs: 7176, row: 232, col: 75}], _aether._userInfo, false);\n                return _aether.restoreAPIClone(_aether, tmp827);\n            };  _aether.logStatement([{ofs: 7137, row: 232, col: 36}, {ofs: 7179, row: 232, col: 78}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 7181, row: 232, col: 80}, {ofs: 7182, row: 232, col: 81}]); tmp826 = 0;  _aether.logStatement([{ofs: 7181, row: 232, col: 80}, {ofs: 7182, row: 232, col: 81}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 7105, row: 232, col: 4}, {ofs: 7184, row: 232, col: 83}]); sumXSquared = _aether.createAPIClone(_aether, tmp823[tmp824](_aether.restoreAPIClone(_aether, tmp825), _aether.restoreAPIClone(_aether, tmp826)));  _aether.logStatement([{ofs: 7105, row: 232, col: 4}, {ofs: 7184, row: 232, col: 83}], _aether._userInfo, false);\n            tmp836 = points;\n            tmp837 = 'reduce';\n            _aether.logStatementStart([{ofs: 7220, row: 234, col: 30}, {ofs: 7262, row: 234, col: 72}]); tmp838 = function (a, b) {\n                var tmp840, tmp841, tmp842, tmp843, tmp844, tmp845, tmp846, tmp847, tmp848; a = _aether.createAPIClone(_aether, a); b = _aether.createAPIClone(_aether, b); for(var __argIndexer = 0; __argIndexer < arguments.length; ++__argIndexer) arguments[__argIndexer] = _aether.createAPIClone(_aether, arguments[__argIndexer]);\n                tmp841 = a;\n                tmp845 = b;\n                tmp846 = 'x';\n                _aether.logStatementStart([{ofs: 7249, row: 234, col: 59}, {ofs: 7252, row: 234, col: 62}]); tmp843 = tmp845[tmp846];  _aether.logStatement([{ofs: 7249, row: 234, col: 59}, {ofs: 7252, row: 234, col: 62}], _aether._userInfo, false);\n                tmp847 = b;\n                tmp848 = 'y';\n                _aether.logStatementStart([{ofs: 7255, row: 234, col: 65}, {ofs: 7258, row: 234, col: 68}]); tmp844 = tmp847[tmp848];  _aether.logStatement([{ofs: 7255, row: 234, col: 65}, {ofs: 7258, row: 234, col: 68}], _aether._userInfo, false);\n                _aether.logStatementStart([{ofs: 7249, row: 234, col: 59}, {ofs: 7258, row: 234, col: 68}]); tmp842 = tmp843 * tmp844;  _aether.logStatement([{ofs: 7249, row: 234, col: 59}, {ofs: 7258, row: 234, col: 68}], _aether._userInfo, false);\n                _aether.logStatementStart([{ofs: 7244, row: 234, col: 54}, {ofs: 7259, row: 234, col: 69}]); tmp840 = tmp841 + tmp842;  _aether.logStatement([{ofs: 7244, row: 234, col: 54}, {ofs: 7259, row: 234, col: 69}], _aether._userInfo, false);\n                return _aether.restoreAPIClone(_aether, tmp840);\n            };  _aether.logStatement([{ofs: 7220, row: 234, col: 30}, {ofs: 7262, row: 234, col: 72}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 7264, row: 234, col: 74}, {ofs: 7265, row: 234, col: 75}]); tmp839 = 0;  _aether.logStatement([{ofs: 7264, row: 234, col: 74}, {ofs: 7265, row: 234, col: 75}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 7194, row: 234, col: 4}, {ofs: 7267, row: 234, col: 77}]); sumXY = _aether.createAPIClone(_aether, tmp836[tmp837](_aether.restoreAPIClone(_aether, tmp838), _aether.restoreAPIClone(_aether, tmp839)));  _aether.logStatement([{ofs: 7194, row: 234, col: 4}, {ofs: 7267, row: 234, col: 77}], _aether._userInfo, false);\n            tmp851 = sumXY;\n            tmp855 = sumX;\n            tmp856 = sumY;\n            _aether.logStatementStart([{ofs: 7300, row: 236, col: 27}, {ofs: 7311, row: 236, col: 38}]); tmp853 = tmp855 * tmp856;  _aether.logStatement([{ofs: 7300, row: 236, col: 27}, {ofs: 7311, row: 236, col: 38}], _aether._userInfo, false);\n            tmp854 = n;\n            _aether.logStatementStart([{ofs: 7299, row: 236, col: 26}, {ofs: 7316, row: 236, col: 43}]); tmp852 = tmp853 / tmp854;  _aether.logStatement([{ofs: 7299, row: 236, col: 26}, {ofs: 7316, row: 236, col: 43}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 7290, row: 236, col: 17}, {ofs: 7317, row: 236, col: 44}]); tmp849 = tmp851 - tmp852;  _aether.logStatement([{ofs: 7290, row: 236, col: 17}, {ofs: 7317, row: 236, col: 44}], _aether._userInfo, false);\n            tmp857 = sumXSquared;\n            tmp861 = sumX;\n            tmp862 = sumX;\n            _aether.logStatementStart([{ofs: 7338, row: 236, col: 65}, {ofs: 7349, row: 236, col: 76}]); tmp859 = tmp861 * tmp862;  _aether.logStatement([{ofs: 7338, row: 236, col: 65}, {ofs: 7349, row: 236, col: 76}], _aether._userInfo, false);\n            tmp860 = n;\n            _aether.logStatementStart([{ofs: 7337, row: 236, col: 64}, {ofs: 7354, row: 236, col: 81}]); tmp858 = tmp859 / tmp860;  _aether.logStatement([{ofs: 7337, row: 236, col: 64}, {ofs: 7354, row: 236, col: 81}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 7322, row: 236, col: 49}, {ofs: 7355, row: 236, col: 82}]); tmp850 = tmp857 - tmp858;  _aether.logStatement([{ofs: 7322, row: 236, col: 49}, {ofs: 7355, row: 236, col: 82}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 7277, row: 236, col: 4}, {ofs: 7357, row: 236, col: 84}]); slope = tmp849 / tmp850;  _aether.logStatement([{ofs: 7277, row: 236, col: 4}, {ofs: 7357, row: 236, col: 84}], _aether._userInfo, false);\n            tmp863 = meanY;\n            tmp865 = slope;\n            tmp866 = meanX;\n            _aether.logStatementStart([{ofs: 7392, row: 238, col: 29}, {ofs: 7405, row: 238, col: 42}]); tmp864 = tmp865 * tmp866;  _aether.logStatement([{ofs: 7392, row: 238, col: 29}, {ofs: 7405, row: 238, col: 42}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 7367, row: 238, col: 4}, {ofs: 7407, row: 238, col: 44}]); intercept = tmp863 - tmp864;  _aether.logStatement([{ofs: 7367, row: 238, col: 4}, {ofs: 7407, row: 238, col: 44}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 7424, row: 240, col: 11}, {ofs: 7483, row: 242, col: 5}]); tmp867 = function (x) {\n                var tmp868, tmp869, tmp870, tmp871, tmp872; x = _aether.createAPIClone(_aether, x); for(var __argIndexer = 0; __argIndexer < arguments.length; ++__argIndexer) arguments[__argIndexer] = _aether.createAPIClone(_aether, arguments[__argIndexer]);\n                tmp871 = slope;\n                tmp872 = x;\n                _aether.logStatementStart([{ofs: 7454, row: 241, col: 16}, {ofs: 7463, row: 241, col: 25}]); tmp869 = tmp871 * tmp872;  _aether.logStatement([{ofs: 7454, row: 241, col: 16}, {ofs: 7463, row: 241, col: 25}], _aether._userInfo, false);\n                tmp870 = intercept;\n                _aether.logStatementStart([{ofs: 7453, row: 241, col: 15}, {ofs: 7476, row: 241, col: 38}]); tmp868 = tmp869 + tmp870;  _aether.logStatement([{ofs: 7453, row: 241, col: 15}, {ofs: 7476, row: 241, col: 38}], _aether._userInfo, false);\n                return _aether.restoreAPIClone(_aether, tmp868);\n            };  _aether.logStatement([{ofs: 7424, row: 240, col: 11}, {ofs: 7483, row: 242, col: 5}], _aether._userInfo, false);\n            return _aether.restoreAPIClone(_aether, tmp867);\n        };  _aether.logStatement([{ofs: 6834, row: 224, col: 0}, {ofs: 7486, row: 243, col: 1}], _aether._userInfo, false);\n        _aether.logStatementStart([{ofs: 7488, row: 245, col: 0}, {ofs: 7700, row: 249, col: 1}]); estimateVariance = function (points, regFunc) {\n            var mseSum, mse, tmp873, tmp874, tmp875, tmp876, tmp890, tmp891, tmp892, tmp893, tmp894, tmp895, tmp896; points = _aether.createAPIClone(_aether, points); regFunc = _aether.createAPIClone(_aether, regFunc); for(var __argIndexer = 0; __argIndexer < arguments.length; ++__argIndexer) arguments[__argIndexer] = _aether.createAPIClone(_aether, arguments[__argIndexer]);\n            tmp873 = points;\n            tmp874 = 'reduce';\n            _aether.logStatementStart([{ofs: 7564, row: 246, col: 31}, {ofs: 7633, row: 246, col: 100}]); tmp875 = function (a, b) {\n                var ms, tmp877, tmp878, tmp879, tmp880, tmp881, tmp882, tmp883, tmp884, tmp885, tmp886, tmp887, tmp888, tmp889; a = _aether.createAPIClone(_aether, a); b = _aether.createAPIClone(_aether, b); for(var __argIndexer = 0; __argIndexer < arguments.length; ++__argIndexer) arguments[__argIndexer] = _aether.createAPIClone(_aether, arguments[__argIndexer]);\n                tmp879 = b;\n                tmp880 = 'y';\n                _aether.logStatementStart([{ofs: 7590, row: 246, col: 57}, {ofs: 7593, row: 246, col: 60}]); tmp877 = tmp879[tmp880];  _aether.logStatement([{ofs: 7590, row: 246, col: 57}, {ofs: 7593, row: 246, col: 60}], _aether._userInfo, false);\n                tmp881 = regFunc;\n                tmp883 = b;\n                tmp884 = 'x';\n                _aether.logStatementStart([{ofs: 7604, row: 246, col: 71}, {ofs: 7607, row: 246, col: 74}]); tmp882 = tmp883[tmp884];  _aether.logStatement([{ofs: 7604, row: 246, col: 71}, {ofs: 7607, row: 246, col: 74}], _aether._userInfo, false);\n                _aether.logStatementStart([{ofs: 7596, row: 246, col: 63}, {ofs: 7608, row: 246, col: 75}]); tmp878 = _aether.createAPIClone(_aether, tmp881(_aether.restoreAPIClone(_aether, tmp882)));  _aether.logStatement([{ofs: 7596, row: 246, col: 63}, {ofs: 7608, row: 246, col: 75}], _aether._userInfo, false);\n                _aether.logStatementStart([{ofs: 7581, row: 246, col: 48}, {ofs: 7609, row: 246, col: 76}]); ms = tmp877 - tmp878;  _aether.logStatement([{ofs: 7581, row: 246, col: 48}, {ofs: 7609, row: 246, col: 76}], _aether._userInfo, false);\n                tmp886 = a;\n                tmp888 = ms;\n                tmp889 = ms;\n                _aether.logStatementStart([{ofs: 7622, row: 246, col: 89}, {ofs: 7629, row: 246, col: 96}]); tmp887 = tmp888 * tmp889;  _aether.logStatement([{ofs: 7622, row: 246, col: 89}, {ofs: 7629, row: 246, col: 96}], _aether._userInfo, false);\n                _aether.logStatementStart([{ofs: 7617, row: 246, col: 84}, {ofs: 7630, row: 246, col: 97}]); tmp885 = tmp886 + tmp887;  _aether.logStatement([{ofs: 7617, row: 246, col: 84}, {ofs: 7630, row: 246, col: 97}], _aether._userInfo, false);\n                return _aether.restoreAPIClone(_aether, tmp885);\n            };  _aether.logStatement([{ofs: 7564, row: 246, col: 31}, {ofs: 7633, row: 246, col: 100}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 7635, row: 246, col: 102}, {ofs: 7636, row: 246, col: 103}]); tmp876 = 0;  _aether.logStatement([{ofs: 7635, row: 246, col: 102}, {ofs: 7636, row: 246, col: 103}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 7537, row: 246, col: 4}, {ofs: 7638, row: 246, col: 105}]); mseSum = _aether.createAPIClone(_aether, tmp873[tmp874](_aether.restoreAPIClone(_aether, tmp875), _aether.restoreAPIClone(_aether, tmp876)));  _aether.logStatement([{ofs: 7537, row: 246, col: 4}, {ofs: 7638, row: 246, col: 105}], _aether._userInfo, false);\n            tmp890 = mseSum;\n            tmp894 = points;\n            tmp895 = 'length';\n            _aether.logStatementStart([{ofs: 7663, row: 247, col: 24}, {ofs: 7676, row: 247, col: 37}]); tmp892 = tmp894[tmp895];  _aether.logStatement([{ofs: 7663, row: 247, col: 24}, {ofs: 7676, row: 247, col: 37}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 7679, row: 247, col: 40}, {ofs: 7680, row: 247, col: 41}]); tmp893 = 2;  _aether.logStatement([{ofs: 7679, row: 247, col: 40}, {ofs: 7680, row: 247, col: 41}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 7663, row: 247, col: 24}, {ofs: 7680, row: 247, col: 41}]); tmp891 = tmp892 - tmp893;  _aether.logStatement([{ofs: 7663, row: 247, col: 24}, {ofs: 7680, row: 247, col: 41}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 7643, row: 247, col: 4}, {ofs: 7682, row: 247, col: 43}]); mse = tmp890 / tmp891;  _aether.logStatement([{ofs: 7643, row: 247, col: 4}, {ofs: 7682, row: 247, col: 43}], _aether._userInfo, false);\n            tmp896 = mse;\n            return _aether.restoreAPIClone(_aether, tmp896);\n        };  _aether.logStatement([{ofs: 7488, row: 245, col: 0}, {ofs: 7700, row: 249, col: 1}], _aether._userInfo, false);\n        _aether.logStatementStart([{ofs: 7702, row: 251, col: 0}, {ofs: 8470, row: 272, col: 1}]); estimateHighLow = function (points, time) {\n            var regFunc, deviation, bound, start, lowStart, highStart, end, lowEnd, highEnd, upperBound, lowerBound, estimate, tmp897, tmp898, tmp899, tmp900, tmp901, tmp902, tmp903, tmp904, tmp905, tmp906, tmp907, tmp908, tmp909, tmp910, tmp911, tmp912, tmp913, tmp914, tmp915, tmp916, tmp917, tmp918, tmp919, tmp920, tmp921, tmp922, tmp923, tmp924, tmp925, tmp926, tmp927, tmp928, tmp929, tmp930, tmp931, tmp932, tmp933, tmp934, tmp935, tmp936, tmp937, tmp938, tmp939, tmp940, tmp941, tmp942, tmp943, tmp944, tmp945, tmp946, tmp947, tmp948, tmp949, tmp950, tmp951, tmp952, tmp953, tmp954, tmp955, tmp956, tmp957, tmp958, tmp959, tmp960, tmp961, tmp962, tmp963, tmp964, tmp965, tmp966, tmp967, tmp968, tmp969, tmp970, tmp971, tmp972, tmp973, tmp974, tmp975, tmp976, tmp977, tmp978, tmp979, tmp980, tmp981, tmp982, tmp983, tmp984, tmp985, tmp986, tmp987, tmp988, tmp989; points = _aether.createAPIClone(_aether, points); time = _aether.createAPIClone(_aether, time); for(var __argIndexer = 0; __argIndexer < arguments.length; ++__argIndexer) arguments[__argIndexer] = _aether.createAPIClone(_aether, arguments[__argIndexer]);\n            tmp897 = createRegressionFunc;\n            tmp898 = points;\n            _aether.logStatementStart([{ofs: 7747, row: 252, col: 4}, {ofs: 7790, row: 252, col: 47}]); regFunc = _aether.createAPIClone(_aether, tmp897(_aether.restoreAPIClone(_aether, tmp898)));  _aether.logStatement([{ofs: 7747, row: 252, col: 4}, {ofs: 7790, row: 252, col: 47}], _aether._userInfo, false);\n            tmp901 = 'Math';\n            tmp899 = __global[tmp901];\n            tmp900 = 'sqrt';\n            tmp903 = estimateVariance;\n            tmp904 = points;\n            tmp905 = regFunc;\n            _aether.logStatementStart([{ofs: 7826, row: 254, col: 30}, {ofs: 7859, row: 254, col: 63}]); tmp902 = _aether.createAPIClone(_aether, tmp903(_aether.restoreAPIClone(_aether, tmp904), _aether.restoreAPIClone(_aether, tmp905)));  _aether.logStatement([{ofs: 7826, row: 254, col: 30}, {ofs: 7859, row: 254, col: 63}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 7800, row: 254, col: 4}, {ofs: 7861, row: 254, col: 65}]); deviation = _aether.createAPIClone(_aether, tmp899[tmp900](_aether.restoreAPIClone(_aether, tmp902)));  _aether.logStatement([{ofs: 7800, row: 254, col: 4}, {ofs: 7861, row: 254, col: 65}], _aether._userInfo, false);\n            tmp906 = deviation;\n            _aether.logStatementStart([{ofs: 7890, row: 255, col: 28}, {ofs: 7891, row: 255, col: 29}]); tmp907 = 2;  _aether.logStatement([{ofs: 7890, row: 255, col: 28}, {ofs: 7891, row: 255, col: 29}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 7866, row: 255, col: 4}, {ofs: 7892, row: 255, col: 30}]); bound = tmp906 * tmp907;  _aether.logStatement([{ofs: 7866, row: 255, col: 4}, {ofs: 7892, row: 255, col: 30}], _aether._userInfo, false);\n            tmp908 = regFunc;\n            tmp912 = points;\n            _aether.logStatementStart([{ofs: 7946, row: 257, col: 31}, {ofs: 7947, row: 257, col: 32}]); tmp913 = 0;  _aether.logStatement([{ofs: 7946, row: 257, col: 31}, {ofs: 7947, row: 257, col: 32}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 7939, row: 257, col: 24}, {ofs: 7948, row: 257, col: 33}]); tmp910 = tmp912[tmp913];  _aether.logStatement([{ofs: 7939, row: 257, col: 24}, {ofs: 7948, row: 257, col: 33}], _aether._userInfo, false);\n            tmp911 = 'x';\n            _aether.logStatementStart([{ofs: 7939, row: 257, col: 24}, {ofs: 7950, row: 257, col: 35}]); tmp909 = tmp910[tmp911];  _aether.logStatement([{ofs: 7939, row: 257, col: 24}, {ofs: 7950, row: 257, col: 35}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 7919, row: 257, col: 4}, {ofs: 7952, row: 257, col: 37}]); start = _aether.createAPIClone(_aether, tmp908(_aether.restoreAPIClone(_aether, tmp909)));  _aether.logStatement([{ofs: 7919, row: 257, col: 4}, {ofs: 7952, row: 257, col: 37}], _aether._userInfo, false);\n            tmp914 = start;\n            tmp915 = bound;\n            _aether.logStatementStart([{ofs: 7957, row: 258, col: 4}, {ofs: 7986, row: 258, col: 33}]); lowStart = tmp914 - tmp915;  _aether.logStatement([{ofs: 7957, row: 258, col: 4}, {ofs: 7986, row: 258, col: 33}], _aether._userInfo, false);\n            tmp916 = start;\n            tmp917 = bound;\n            _aether.logStatementStart([{ofs: 7991, row: 259, col: 4}, {ofs: 8021, row: 259, col: 34}]); highStart = tmp916 + tmp917;  _aether.logStatement([{ofs: 7991, row: 259, col: 4}, {ofs: 8021, row: 259, col: 34}], _aether._userInfo, false);\n            tmp918 = regFunc;\n            tmp922 = points;\n            tmp926 = points;\n            tmp927 = 'length';\n            _aether.logStatementStart([{ofs: 8056, row: 261, col: 29}, {ofs: 8069, row: 261, col: 42}]); tmp924 = tmp926[tmp927];  _aether.logStatement([{ofs: 8056, row: 261, col: 29}, {ofs: 8069, row: 261, col: 42}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 8072, row: 261, col: 45}, {ofs: 8073, row: 261, col: 46}]); tmp925 = 1;  _aether.logStatement([{ofs: 8072, row: 261, col: 45}, {ofs: 8073, row: 261, col: 46}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 8056, row: 261, col: 29}, {ofs: 8073, row: 261, col: 46}]); tmp923 = tmp924 - tmp925;  _aether.logStatement([{ofs: 8056, row: 261, col: 29}, {ofs: 8073, row: 261, col: 46}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 8049, row: 261, col: 22}, {ofs: 8074, row: 261, col: 47}]); tmp920 = tmp922[tmp923];  _aether.logStatement([{ofs: 8049, row: 261, col: 22}, {ofs: 8074, row: 261, col: 47}], _aether._userInfo, false);\n            tmp921 = 'x';\n            _aether.logStatementStart([{ofs: 8049, row: 261, col: 22}, {ofs: 8076, row: 261, col: 49}]); tmp919 = tmp920[tmp921];  _aether.logStatement([{ofs: 8049, row: 261, col: 22}, {ofs: 8076, row: 261, col: 49}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 8031, row: 261, col: 4}, {ofs: 8078, row: 261, col: 51}]); end = _aether.createAPIClone(_aether, tmp918(_aether.restoreAPIClone(_aether, tmp919)));  _aether.logStatement([{ofs: 8031, row: 261, col: 4}, {ofs: 8078, row: 261, col: 51}], _aether._userInfo, false);\n            tmp928 = end;\n            tmp929 = bound;\n            _aether.logStatementStart([{ofs: 8083, row: 262, col: 4}, {ofs: 8108, row: 262, col: 29}]); lowEnd = tmp928 - tmp929;  _aether.logStatement([{ofs: 8083, row: 262, col: 4}, {ofs: 8108, row: 262, col: 29}], _aether._userInfo, false);\n            tmp930 = end;\n            tmp931 = bound;\n            _aether.logStatementStart([{ofs: 8113, row: 263, col: 4}, {ofs: 8139, row: 263, col: 30}]); highEnd = tmp930 + tmp931;  _aether.logStatement([{ofs: 8113, row: 263, col: 4}, {ofs: 8139, row: 263, col: 30}], _aether._userInfo, false);\n            tmp932 = lerp;\n            tmp933 = lowStart;\n            tmp934 = highEnd;\n            tmp938 = time;\n            tmp942 = points;\n            _aether.logStatementStart([{ofs: 8205, row: 265, col: 60}, {ofs: 8206, row: 265, col: 61}]); tmp943 = 0;  _aether.logStatement([{ofs: 8205, row: 265, col: 60}, {ofs: 8206, row: 265, col: 61}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 8198, row: 265, col: 53}, {ofs: 8207, row: 265, col: 62}]); tmp940 = tmp942[tmp943];  _aether.logStatement([{ofs: 8198, row: 265, col: 53}, {ofs: 8207, row: 265, col: 62}], _aether._userInfo, false);\n            tmp941 = 'x';\n            _aether.logStatementStart([{ofs: 8198, row: 265, col: 53}, {ofs: 8209, row: 265, col: 64}]); tmp939 = tmp940[tmp941];  _aether.logStatement([{ofs: 8198, row: 265, col: 53}, {ofs: 8209, row: 265, col: 64}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 8191, row: 265, col: 46}, {ofs: 8209, row: 265, col: 64}]); tmp936 = tmp938 - tmp939;  _aether.logStatement([{ofs: 8191, row: 265, col: 46}, {ofs: 8209, row: 265, col: 64}], _aether._userInfo, false);\n            tmp948 = points;\n            tmp952 = points;\n            tmp953 = 'length';\n            _aether.logStatementStart([{ofs: 8221, row: 265, col: 76}, {ofs: 8234, row: 265, col: 89}]); tmp950 = tmp952[tmp953];  _aether.logStatement([{ofs: 8221, row: 265, col: 76}, {ofs: 8234, row: 265, col: 89}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 8237, row: 265, col: 92}, {ofs: 8238, row: 265, col: 93}]); tmp951 = 1;  _aether.logStatement([{ofs: 8237, row: 265, col: 92}, {ofs: 8238, row: 265, col: 93}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 8221, row: 265, col: 76}, {ofs: 8238, row: 265, col: 93}]); tmp949 = tmp950 - tmp951;  _aether.logStatement([{ofs: 8221, row: 265, col: 76}, {ofs: 8238, row: 265, col: 93}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 8214, row: 265, col: 69}, {ofs: 8239, row: 265, col: 94}]); tmp946 = tmp948[tmp949];  _aether.logStatement([{ofs: 8214, row: 265, col: 69}, {ofs: 8239, row: 265, col: 94}], _aether._userInfo, false);\n            tmp947 = 'x';\n            _aether.logStatementStart([{ofs: 8214, row: 265, col: 69}, {ofs: 8241, row: 265, col: 96}]); tmp944 = tmp946[tmp947];  _aether.logStatement([{ofs: 8214, row: 265, col: 69}, {ofs: 8241, row: 265, col: 96}], _aether._userInfo, false);\n            tmp956 = points;\n            _aether.logStatementStart([{ofs: 8251, row: 265, col: 106}, {ofs: 8252, row: 265, col: 107}]); tmp957 = 0;  _aether.logStatement([{ofs: 8251, row: 265, col: 106}, {ofs: 8252, row: 265, col: 107}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 8244, row: 265, col: 99}, {ofs: 8253, row: 265, col: 108}]); tmp954 = tmp956[tmp957];  _aether.logStatement([{ofs: 8244, row: 265, col: 99}, {ofs: 8253, row: 265, col: 108}], _aether._userInfo, false);\n            tmp955 = 'x';\n            _aether.logStatementStart([{ofs: 8244, row: 265, col: 99}, {ofs: 8255, row: 265, col: 110}]); tmp945 = tmp954[tmp955];  _aether.logStatement([{ofs: 8244, row: 265, col: 99}, {ofs: 8255, row: 265, col: 110}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 8214, row: 265, col: 69}, {ofs: 8255, row: 265, col: 110}]); tmp937 = tmp944 - tmp945;  _aether.logStatement([{ofs: 8214, row: 265, col: 69}, {ofs: 8255, row: 265, col: 110}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 8190, row: 265, col: 45}, {ofs: 8256, row: 265, col: 111}]); tmp935 = tmp936 / tmp937;  _aether.logStatement([{ofs: 8190, row: 265, col: 45}, {ofs: 8256, row: 265, col: 111}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 8149, row: 265, col: 4}, {ofs: 8258, row: 265, col: 113}]); upperBound = _aether.createAPIClone(_aether, tmp932(_aether.restoreAPIClone(_aether, tmp933), _aether.restoreAPIClone(_aether, tmp934), _aether.restoreAPIClone(_aether, tmp935)));  _aether.logStatement([{ofs: 8149, row: 265, col: 4}, {ofs: 8258, row: 265, col: 113}], _aether._userInfo, false);\n            tmp958 = lerp;\n            tmp959 = highStart;\n            tmp960 = lowEnd;\n            tmp964 = time;\n            tmp968 = points;\n            _aether.logStatementStart([{ofs: 8319, row: 266, col: 60}, {ofs: 8320, row: 266, col: 61}]); tmp969 = 0;  _aether.logStatement([{ofs: 8319, row: 266, col: 60}, {ofs: 8320, row: 266, col: 61}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 8312, row: 266, col: 53}, {ofs: 8321, row: 266, col: 62}]); tmp966 = tmp968[tmp969];  _aether.logStatement([{ofs: 8312, row: 266, col: 53}, {ofs: 8321, row: 266, col: 62}], _aether._userInfo, false);\n            tmp967 = 'x';\n            _aether.logStatementStart([{ofs: 8312, row: 266, col: 53}, {ofs: 8323, row: 266, col: 64}]); tmp965 = tmp966[tmp967];  _aether.logStatement([{ofs: 8312, row: 266, col: 53}, {ofs: 8323, row: 266, col: 64}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 8305, row: 266, col: 46}, {ofs: 8323, row: 266, col: 64}]); tmp962 = tmp964 - tmp965;  _aether.logStatement([{ofs: 8305, row: 266, col: 46}, {ofs: 8323, row: 266, col: 64}], _aether._userInfo, false);\n            tmp974 = points;\n            tmp978 = points;\n            tmp979 = 'length';\n            _aether.logStatementStart([{ofs: 8335, row: 266, col: 76}, {ofs: 8348, row: 266, col: 89}]); tmp976 = tmp978[tmp979];  _aether.logStatement([{ofs: 8335, row: 266, col: 76}, {ofs: 8348, row: 266, col: 89}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 8351, row: 266, col: 92}, {ofs: 8352, row: 266, col: 93}]); tmp977 = 1;  _aether.logStatement([{ofs: 8351, row: 266, col: 92}, {ofs: 8352, row: 266, col: 93}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 8335, row: 266, col: 76}, {ofs: 8352, row: 266, col: 93}]); tmp975 = tmp976 - tmp977;  _aether.logStatement([{ofs: 8335, row: 266, col: 76}, {ofs: 8352, row: 266, col: 93}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 8328, row: 266, col: 69}, {ofs: 8353, row: 266, col: 94}]); tmp972 = tmp974[tmp975];  _aether.logStatement([{ofs: 8328, row: 266, col: 69}, {ofs: 8353, row: 266, col: 94}], _aether._userInfo, false);\n            tmp973 = 'x';\n            _aether.logStatementStart([{ofs: 8328, row: 266, col: 69}, {ofs: 8355, row: 266, col: 96}]); tmp970 = tmp972[tmp973];  _aether.logStatement([{ofs: 8328, row: 266, col: 69}, {ofs: 8355, row: 266, col: 96}], _aether._userInfo, false);\n            tmp982 = points;\n            _aether.logStatementStart([{ofs: 8365, row: 266, col: 106}, {ofs: 8366, row: 266, col: 107}]); tmp983 = 0;  _aether.logStatement([{ofs: 8365, row: 266, col: 106}, {ofs: 8366, row: 266, col: 107}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 8358, row: 266, col: 99}, {ofs: 8367, row: 266, col: 108}]); tmp980 = tmp982[tmp983];  _aether.logStatement([{ofs: 8358, row: 266, col: 99}, {ofs: 8367, row: 266, col: 108}], _aether._userInfo, false);\n            tmp981 = 'x';\n            _aether.logStatementStart([{ofs: 8358, row: 266, col: 99}, {ofs: 8369, row: 266, col: 110}]); tmp971 = tmp980[tmp981];  _aether.logStatement([{ofs: 8358, row: 266, col: 99}, {ofs: 8369, row: 266, col: 110}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 8328, row: 266, col: 69}, {ofs: 8369, row: 266, col: 110}]); tmp963 = tmp970 - tmp971;  _aether.logStatement([{ofs: 8328, row: 266, col: 69}, {ofs: 8369, row: 266, col: 110}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 8304, row: 266, col: 45}, {ofs: 8370, row: 266, col: 111}]); tmp961 = tmp962 / tmp963;  _aether.logStatement([{ofs: 8304, row: 266, col: 45}, {ofs: 8370, row: 266, col: 111}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 8263, row: 266, col: 4}, {ofs: 8372, row: 266, col: 113}]); lowerBound = _aether.createAPIClone(_aether, tmp958(_aether.restoreAPIClone(_aether, tmp959), _aether.restoreAPIClone(_aether, tmp960), _aether.restoreAPIClone(_aether, tmp961)));  _aether.logStatement([{ofs: 8263, row: 266, col: 4}, {ofs: 8372, row: 266, col: 113}], _aether._userInfo, false);\n            tmp984 = regFunc;\n            tmp985 = time;\n            _aether.logStatementStart([{ofs: 8382, row: 268, col: 4}, {ofs: 8411, row: 268, col: 33}]); estimate = _aether.createAPIClone(_aether, tmp984(_aether.restoreAPIClone(_aether, tmp985)));  _aether.logStatement([{ofs: 8382, row: 268, col: 4}, {ofs: 8411, row: 268, col: 33}], _aether._userInfo, false);\n            tmp987 = upperBound;\n            tmp988 = estimate;\n            tmp989 = lowerBound;\n            _aether.logStatementStart([{ofs: 8433, row: 271, col: 11}, {ofs: 8467, row: 271, col: 45}]); tmp986 = [\n                tmp987,\n                tmp988,\n                tmp989\n            ];  _aether.logStatement([{ofs: 8433, row: 271, col: 11}, {ofs: 8467, row: 271, col: 45}], _aether._userInfo, false);\n            return _aether.restoreAPIClone(_aether, tmp986);\n        };  _aether.logStatement([{ofs: 7702, row: 251, col: 0}, {ofs: 8470, row: 272, col: 1}], _aether._userInfo, false);\n        _aether.logStatementStart([{ofs: 11737, row: 400, col: 0}, {ofs: 12713, row: 428, col: 1}]); decideMilitaryToBuild = function (base) {\n            var soldierPercent, friendlyLibs, libPercent, friendlyGrif, grifPercent, friendlyKnight, knightPercent, tmp990, tmp991, tmp992, tmp993, tmp994, tmp995, tmp996, tmp997, tmp998, tmp999, tmp1000, tmp1001, tmp1002, tmp1003, tmp1004, tmp1005, tmp1006, tmp1007, tmp1008, tmp1009, tmp1010, tmp1011, tmp1012, tmp1013, tmp1014, tmp1015, tmp1016, tmp1017, tmp1018, tmp1019, tmp1020, tmp1021, tmp1022, tmp1023, tmp1024, tmp1025, tmp1026, tmp1027, tmp1028, tmp1029, tmp1030, tmp1031, tmp1032, tmp1033, tmp1034, tmp1035, tmp1036, tmp1037, tmp1038, tmp1039, tmp1040, tmp1041, tmp1042, tmp1043, tmp1044, tmp1045, tmp1046, tmp1047, tmp1048, tmp1049, tmp1050, tmp1051, tmp1052, tmp1053, tmp1054, tmp1055, tmp1056, tmp1057, tmp1058, tmp1059, tmp1060, tmp1061, tmp1062, tmp1063, tmp1064, tmp1065; base = _aether.createAPIClone(_aether, base); for(var __argIndexer = 0; __argIndexer < arguments.length; ++__argIndexer) arguments[__argIndexer] = _aether.createAPIClone(_aether, arguments[__argIndexer]);\n            tmp992 = friendlySoldiers;\n            tmp993 = 'length';\n            _aether.logStatementStart([{ofs: 11801, row: 401, col: 25}, {ofs: 11824, row: 401, col: 48}]); tmp990 = tmp992[tmp993];  _aether.logStatement([{ofs: 11801, row: 401, col: 25}, {ofs: 11824, row: 401, col: 48}], _aether._userInfo, false);\n            tmp994 = militaryFriends;\n            tmp995 = 'length';\n            _aether.logStatementStart([{ofs: 11827, row: 401, col: 51}, {ofs: 11849, row: 401, col: 73}]); tmp991 = tmp994[tmp995];  _aether.logStatement([{ofs: 11827, row: 401, col: 51}, {ofs: 11849, row: 401, col: 73}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 11780, row: 401, col: 4}, {ofs: 11850, row: 401, col: 74}]); soldierPercent = tmp990 / tmp991;  _aether.logStatement([{ofs: 11780, row: 401, col: 4}, {ofs: 11850, row: 401, col: 74}], _aether._userInfo, false);\n            tmp1000 = friendlySoldiers;\n            tmp1001 = 'length';\n            _aether.logStatementStart([{ofs: 11864, row: 403, col: 8}, {ofs: 11887, row: 403, col: 31}]); tmp998 = tmp1000[tmp1001];  _aether.logStatement([{ofs: 11864, row: 403, col: 8}, {ofs: 11887, row: 403, col: 31}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 11890, row: 403, col: 34}, {ofs: 11891, row: 403, col: 35}]); tmp999 = 3;  _aether.logStatement([{ofs: 11890, row: 403, col: 34}, {ofs: 11891, row: 403, col: 35}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 11864, row: 403, col: 8}, {ofs: 11891, row: 403, col: 35}]); tmp997 = tmp998 < tmp999;  _aether.logStatement([{ofs: 11864, row: 403, col: 8}, {ofs: 11891, row: 403, col: 35}], _aether._userInfo, false);\n            if (tmp997) {\n                _aether.logStatementStart([{ofs: 11864, row: 403, col: 8}, {ofs: 11917, row: 403, col: 61}]); tmp996 = tmp997;  _aether.logStatement([{ofs: 11864, row: 403, col: 8}, {ofs: 11917, row: 403, col: 61}], _aether._userInfo, false);\n            } else {\n                tmp1002 = soldierPercent;\n                _aether.logStatementStart([{ofs: 11913, row: 403, col: 57}, {ofs: 11917, row: 403, col: 61}]); tmp1003 = 0.45;  _aether.logStatement([{ofs: 11913, row: 403, col: 57}, {ofs: 11917, row: 403, col: 61}], _aether._userInfo, false);\n                _aether.logStatementStart([{ofs: 11895, row: 403, col: 39}, {ofs: 11917, row: 403, col: 61}]); tmp996 = tmp1002 <= tmp1003;  _aether.logStatement([{ofs: 11895, row: 403, col: 39}, {ofs: 11917, row: 403, col: 61}], _aether._userInfo, false);\n            }\n            if (tmp996) {\n                tmp1005 = alliedTypes;\n                tmp1006 = 'soldier';\n                _aether.logStatementStart([{ofs: 11936, row: 404, col: 15}, {ofs: 11955, row: 404, col: 34}]); tmp1004 = tmp1005[tmp1006];  _aether.logStatement([{ofs: 11936, row: 404, col: 15}, {ofs: 11955, row: 404, col: 34}], _aether._userInfo, false);\n                return _aether.restoreAPIClone(_aether, tmp1004);\n            } else {\n                ;\n            }\n            tmp1007 = filterType;\n            tmp1010 = alliedTypes;\n            tmp1011 = 'librarian';\n            _aether.logStatementStart([{ofs: 12002, row: 407, col: 34}, {ofs: 12023, row: 407, col: 55}]); tmp1008 = tmp1010[tmp1011];  _aether.logStatement([{ofs: 12002, row: 407, col: 34}, {ofs: 12023, row: 407, col: 55}], _aether._userInfo, false);\n            tmp1009 = militaryFriends;\n            _aether.logStatementStart([{ofs: 11972, row: 407, col: 4}, {ofs: 12042, row: 407, col: 74}]); friendlyLibs = _aether.createAPIClone(_aether, tmp1007(_aether.restoreAPIClone(_aether, tmp1008), _aether.restoreAPIClone(_aether, tmp1009)));  _aether.logStatement([{ofs: 11972, row: 407, col: 4}, {ofs: 12042, row: 407, col: 74}], _aether._userInfo, false);\n            tmp1014 = friendlyLibs;\n            tmp1015 = 'length';\n            _aether.logStatementStart([{ofs: 12064, row: 408, col: 21}, {ofs: 12083, row: 408, col: 40}]); tmp1012 = tmp1014[tmp1015];  _aether.logStatement([{ofs: 12064, row: 408, col: 21}, {ofs: 12083, row: 408, col: 40}], _aether._userInfo, false);\n            tmp1016 = militaryFriends;\n            tmp1017 = 'length';\n            _aether.logStatementStart([{ofs: 12086, row: 408, col: 43}, {ofs: 12108, row: 408, col: 65}]); tmp1013 = tmp1016[tmp1017];  _aether.logStatement([{ofs: 12086, row: 408, col: 43}, {ofs: 12108, row: 408, col: 65}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 12047, row: 408, col: 4}, {ofs: 12109, row: 408, col: 66}]); libPercent = tmp1012 / tmp1013;  _aether.logStatement([{ofs: 12047, row: 408, col: 4}, {ofs: 12109, row: 408, col: 66}], _aether._userInfo, false);\n            tmp1022 = friendlyLibs;\n            tmp1023 = 'length';\n            _aether.logStatementStart([{ofs: 12123, row: 410, col: 8}, {ofs: 12142, row: 410, col: 27}]); tmp1020 = tmp1022[tmp1023];  _aether.logStatement([{ofs: 12123, row: 410, col: 8}, {ofs: 12142, row: 410, col: 27}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 12145, row: 410, col: 30}, {ofs: 12146, row: 410, col: 31}]); tmp1021 = 2;  _aether.logStatement([{ofs: 12145, row: 410, col: 30}, {ofs: 12146, row: 410, col: 31}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 12123, row: 410, col: 8}, {ofs: 12146, row: 410, col: 31}]); tmp1019 = tmp1020 < tmp1021;  _aether.logStatement([{ofs: 12123, row: 410, col: 8}, {ofs: 12146, row: 410, col: 31}], _aether._userInfo, false);\n            if (tmp1019) {\n                _aether.logStatementStart([{ofs: 12123, row: 410, col: 8}, {ofs: 12168, row: 410, col: 53}]); tmp1018 = tmp1019;  _aether.logStatement([{ofs: 12123, row: 410, col: 8}, {ofs: 12168, row: 410, col: 53}], _aether._userInfo, false);\n            } else {\n                tmp1024 = libPercent;\n                _aether.logStatementStart([{ofs: 12164, row: 410, col: 49}, {ofs: 12168, row: 410, col: 53}]); tmp1025 = 0.33;  _aether.logStatement([{ofs: 12164, row: 410, col: 49}, {ofs: 12168, row: 410, col: 53}], _aether._userInfo, false);\n                _aether.logStatementStart([{ofs: 12150, row: 410, col: 35}, {ofs: 12168, row: 410, col: 53}]); tmp1018 = tmp1024 <= tmp1025;  _aether.logStatement([{ofs: 12150, row: 410, col: 35}, {ofs: 12168, row: 410, col: 53}], _aether._userInfo, false);\n            }\n            if (tmp1018) {\n                tmp1027 = alliedTypes;\n                tmp1028 = 'librarian';\n                _aether.logStatementStart([{ofs: 12187, row: 411, col: 15}, {ofs: 12208, row: 411, col: 36}]); tmp1026 = tmp1027[tmp1028];  _aether.logStatement([{ofs: 12187, row: 411, col: 15}, {ofs: 12208, row: 411, col: 36}], _aether._userInfo, false);\n                return _aether.restoreAPIClone(_aether, tmp1026);\n            } else {\n                ;\n            }\n            tmp1029 = filterType;\n            tmp1032 = alliedTypes;\n            tmp1033 = 'griffinRider';\n            _aether.logStatementStart([{ofs: 12255, row: 414, col: 34}, {ofs: 12279, row: 414, col: 58}]); tmp1030 = tmp1032[tmp1033];  _aether.logStatement([{ofs: 12255, row: 414, col: 34}, {ofs: 12279, row: 414, col: 58}], _aether._userInfo, false);\n            tmp1031 = militaryFriends;\n            _aether.logStatementStart([{ofs: 12225, row: 414, col: 4}, {ofs: 12298, row: 414, col: 77}]); friendlyGrif = _aether.createAPIClone(_aether, tmp1029(_aether.restoreAPIClone(_aether, tmp1030), _aether.restoreAPIClone(_aether, tmp1031)));  _aether.logStatement([{ofs: 12225, row: 414, col: 4}, {ofs: 12298, row: 414, col: 77}], _aether._userInfo, false);\n            tmp1036 = friendlyGrif;\n            tmp1037 = 'length';\n            _aether.logStatementStart([{ofs: 12321, row: 415, col: 22}, {ofs: 12340, row: 415, col: 41}]); tmp1034 = tmp1036[tmp1037];  _aether.logStatement([{ofs: 12321, row: 415, col: 22}, {ofs: 12340, row: 415, col: 41}], _aether._userInfo, false);\n            tmp1038 = militaryFriends;\n            tmp1039 = 'length';\n            _aether.logStatementStart([{ofs: 12343, row: 415, col: 44}, {ofs: 12365, row: 415, col: 66}]); tmp1035 = tmp1038[tmp1039];  _aether.logStatement([{ofs: 12343, row: 415, col: 44}, {ofs: 12365, row: 415, col: 66}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 12303, row: 415, col: 4}, {ofs: 12366, row: 415, col: 67}]); grifPercent = tmp1034 / tmp1035;  _aether.logStatement([{ofs: 12303, row: 415, col: 4}, {ofs: 12366, row: 415, col: 67}], _aether._userInfo, false);\n            tmp1041 = grifPercent;\n            _aether.logStatementStart([{ofs: 12394, row: 417, col: 22}, {ofs: 12399, row: 417, col: 27}]); tmp1042 = 0.125;  _aether.logStatement([{ofs: 12394, row: 417, col: 22}, {ofs: 12399, row: 417, col: 27}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 12380, row: 417, col: 8}, {ofs: 12399, row: 417, col: 27}]); tmp1040 = tmp1041 < tmp1042;  _aether.logStatement([{ofs: 12380, row: 417, col: 8}, {ofs: 12399, row: 417, col: 27}], _aether._userInfo, false);\n            if (tmp1040) {\n                tmp1044 = alliedTypes;\n                tmp1045 = 'griffinRider';\n                _aether.logStatementStart([{ofs: 12418, row: 418, col: 15}, {ofs: 12442, row: 418, col: 39}]); tmp1043 = tmp1044[tmp1045];  _aether.logStatement([{ofs: 12418, row: 418, col: 15}, {ofs: 12442, row: 418, col: 39}], _aether._userInfo, false);\n                return _aether.restoreAPIClone(_aether, tmp1043);\n            } else {\n                ;\n            }\n            tmp1046 = filterType;\n            tmp1049 = alliedTypes;\n            tmp1050 = 'knight';\n            _aether.logStatementStart([{ofs: 12491, row: 421, col: 36}, {ofs: 12509, row: 421, col: 54}]); tmp1047 = tmp1049[tmp1050];  _aether.logStatement([{ofs: 12491, row: 421, col: 36}, {ofs: 12509, row: 421, col: 54}], _aether._userInfo, false);\n            tmp1048 = militaryFriends;\n            _aether.logStatementStart([{ofs: 12459, row: 421, col: 4}, {ofs: 12528, row: 421, col: 73}]); friendlyKnight = _aether.createAPIClone(_aether, tmp1046(_aether.restoreAPIClone(_aether, tmp1047), _aether.restoreAPIClone(_aether, tmp1048)));  _aether.logStatement([{ofs: 12459, row: 421, col: 4}, {ofs: 12528, row: 421, col: 73}], _aether._userInfo, false);\n            tmp1053 = friendlyKnight;\n            tmp1054 = 'length';\n            _aether.logStatementStart([{ofs: 12553, row: 422, col: 24}, {ofs: 12574, row: 422, col: 45}]); tmp1051 = tmp1053[tmp1054];  _aether.logStatement([{ofs: 12553, row: 422, col: 24}, {ofs: 12574, row: 422, col: 45}], _aether._userInfo, false);\n            tmp1055 = militaryFriends;\n            tmp1056 = 'length';\n            _aether.logStatementStart([{ofs: 12577, row: 422, col: 48}, {ofs: 12599, row: 422, col: 70}]); tmp1052 = tmp1055[tmp1056];  _aether.logStatement([{ofs: 12577, row: 422, col: 48}, {ofs: 12599, row: 422, col: 70}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 12533, row: 422, col: 4}, {ofs: 12600, row: 422, col: 71}]); knightPercent = tmp1051 / tmp1052;  _aether.logStatement([{ofs: 12533, row: 422, col: 4}, {ofs: 12600, row: 422, col: 71}], _aether._userInfo, false);\n            tmp1058 = knightPercent;\n            _aether.logStatementStart([{ofs: 12625, row: 423, col: 24}, {ofs: 12630, row: 423, col: 29}]); tmp1059 = 0.1;  _aether.logStatement([{ofs: 12625, row: 423, col: 24}, {ofs: 12630, row: 423, col: 29}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 12609, row: 423, col: 8}, {ofs: 12630, row: 423, col: 29}]); tmp1057 = tmp1058 < tmp1059;  _aether.logStatement([{ofs: 12609, row: 423, col: 8}, {ofs: 12630, row: 423, col: 29}], _aether._userInfo, false);\n            if (tmp1057) {\n                tmp1061 = alliedTypes;\n                tmp1062 = 'knight';\n                _aether.logStatementStart([{ofs: 12649, row: 424, col: 15}, {ofs: 12667, row: 424, col: 33}]); tmp1060 = tmp1061[tmp1062];  _aether.logStatement([{ofs: 12649, row: 424, col: 15}, {ofs: 12667, row: 424, col: 33}], _aether._userInfo, false);\n                return _aether.restoreAPIClone(_aether, tmp1060);\n            } else {\n                ;\n            }\n            tmp1064 = alliedTypes;\n            tmp1065 = 'soldier';\n            _aether.logStatementStart([{ofs: 12691, row: 427, col: 11}, {ofs: 12710, row: 427, col: 30}]); tmp1063 = tmp1064[tmp1065];  _aether.logStatement([{ofs: 12691, row: 427, col: 11}, {ofs: 12710, row: 427, col: 30}], _aether._userInfo, false);\n            return _aether.restoreAPIClone(_aether, tmp1063);\n        };  _aether.logStatement([{ofs: 11737, row: 400, col: 0}, {ofs: 12713, row: 428, col: 1}], _aether._userInfo, false);\n        _aether.logStatementStart([{ofs: 115, row: 3, col: 13}, {ofs: 124, row: 3, col: 22}]); tmp2 = 'peasant';  _aether.logStatement([{ofs: 115, row: 3, col: 13}, {ofs: 124, row: 3, col: 22}], _aether._userInfo, false);\n        _aether.logStatementStart([{ofs: 139, row: 4, col: 13}, {ofs: 148, row: 4, col: 22}]); tmp3 = 'soldier';  _aether.logStatement([{ofs: 139, row: 4, col: 13}, {ofs: 148, row: 4, col: 22}], _aether._userInfo, false);\n        _aether.logStatementStart([{ofs: 162, row: 5, col: 12}, {ofs: 170, row: 5, col: 20}]); tmp4 = 'knight';  _aether.logStatement([{ofs: 162, row: 5, col: 12}, {ofs: 170, row: 5, col: 20}], _aether._userInfo, false);\n        _aether.logStatementStart([{ofs: 187, row: 6, col: 15}, {ofs: 198, row: 6, col: 26}]); tmp5 = 'librarian';  _aether.logStatement([{ofs: 187, row: 6, col: 15}, {ofs: 198, row: 6, col: 26}], _aether._userInfo, false);\n        _aether.logStatementStart([{ofs: 218, row: 7, col: 18}, {ofs: 233, row: 7, col: 33}]); tmp6 = 'griffin-rider';  _aether.logStatement([{ofs: 218, row: 7, col: 18}, {ofs: 233, row: 7, col: 33}], _aether._userInfo, false);\n        _aether.logStatementStart([{ofs: 248, row: 8, col: 13}, {ofs: 257, row: 8, col: 22}]); tmp7 = 'captain';  _aether.logStatement([{ofs: 248, row: 8, col: 13}, {ofs: 257, row: 8, col: 22}], _aether._userInfo, false);\n        _aether.logStatementStart([{ofs: 82, row: 2, col: 0}, {ofs: 260, row: 9, col: 2}]); alliedTypes = {\n            peasant: tmp2,\n            soldier: tmp3,\n            knight: tmp4,\n            librarian: tmp5,\n            griffinRider: tmp6,\n            captain: tmp7\n        };  _aether.logStatement([{ofs: 82, row: 2, col: 0}, {ofs: 260, row: 9, col: 2}], _aether._userInfo, false);\n        _aether.logStatementStart([{ofs: 294, row: 12, col: 13}, {ofs: 300, row: 12, col: 19}]); tmp8 = 'peon';  _aether.logStatement([{ofs: 294, row: 12, col: 13}, {ofs: 300, row: 12, col: 19}], _aether._userInfo, false);\n        _aether.logStatementStart([{ofs: 315, row: 13, col: 13}, {ofs: 325, row: 13, col: 23}]); tmp9 = 'munchkin';  _aether.logStatement([{ofs: 315, row: 13, col: 13}, {ofs: 325, row: 13, col: 23}], _aether._userInfo, false);\n        _aether.logStatementStart([{ofs: 339, row: 14, col: 12}, {ofs: 345, row: 14, col: 18}]); tmp10 = 'ogre';  _aether.logStatement([{ofs: 339, row: 14, col: 12}, {ofs: 345, row: 14, col: 18}], _aether._userInfo, false);\n        _aether.logStatementStart([{ofs: 362, row: 15, col: 15}, {ofs: 370, row: 15, col: 23}]); tmp11 = 'shaman';  _aether.logStatement([{ofs: 362, row: 15, col: 15}, {ofs: 370, row: 15, col: 23}], _aether._userInfo, false);\n        _aether.logStatementStart([{ofs: 390, row: 16, col: 18}, {ofs: 401, row: 16, col: 29}]); tmp12 = 'fangrider';  _aether.logStatement([{ofs: 390, row: 16, col: 18}, {ofs: 401, row: 16, col: 29}], _aether._userInfo, false);\n        _aether.logStatementStart([{ofs: 416, row: 17, col: 13}, {ofs: 425, row: 17, col: 22}]); tmp13 = 'brawler';  _aether.logStatement([{ofs: 416, row: 17, col: 13}, {ofs: 425, row: 17, col: 22}], _aether._userInfo, false);\n        _aether.logStatementStart([{ofs: 262, row: 11, col: 0}, {ofs: 428, row: 18, col: 2}]); enemyTypes = {\n            peasant: tmp8,\n            soldier: tmp9,\n            knight: tmp10,\n            librarian: tmp11,\n            griffinRider: tmp12,\n            captain: tmp13\n        };  _aether.logStatement([{ofs: 262, row: 11, col: 0}, {ofs: 428, row: 18, col: 2}], _aether._userInfo, false);\n        tmp19 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n        tmp20 = 'buildables';\n        _aether.logStatementStart([{ofs: 434, row: 20, col: 4}, {ofs: 449, row: 20, col: 19}]); tmp17 = tmp19[tmp20];  _aether.logStatement([{ofs: 434, row: 20, col: 4}, {ofs: 449, row: 20, col: 19}], _aether._userInfo, false);\n        tmp18 = 'peasant';\n        _aether.logStatementStart([{ofs: 434, row: 20, col: 4}, {ofs: 457, row: 20, col: 27}]); tmp15 = tmp17[tmp18];  _aether.logStatement([{ofs: 434, row: 20, col: 4}, {ofs: 457, row: 20, col: 27}], _aether._userInfo, false);\n        tmp21 = 'undefined';\n        tmp16 = __global[tmp21];\n        _aether.logStatementStart([{ofs: 434, row: 20, col: 4}, {ofs: 471, row: 20, col: 41}]); tmp14 = tmp15 === tmp16;  _aether.logStatement([{ofs: 434, row: 20, col: 4}, {ofs: 471, row: 20, col: 41}], _aether._userInfo, false);\n        if (tmp14) {\n            tmp = alliedTypes;\n            alliedTypes = enemyTypes;\n            enemyTypes = tmp;\n        } else {\n            ;\n        }\n        tmp22 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n        tmp23 = 'getItems';\n        _aether.logStatementStart([{ofs: 6245, row: 206, col: 0}, {ofs: 6273, row: 206, col: 28}]); items = _aether.createAPIClone(_aether, tmp22[tmp23]());  _aether.logStatement([{ofs: 6245, row: 206, col: 0}, {ofs: 6273, row: 206, col: 28}], _aether._userInfo, false);\n        tmp24 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n        tmp25 = 'getFriends';\n        _aether.logStatementStart([{ofs: 6274, row: 207, col: 0}, {ofs: 6306, row: 207, col: 32}]); friends = _aether.createAPIClone(_aether, tmp24[tmp25]());  _aether.logStatement([{ofs: 6274, row: 207, col: 0}, {ofs: 6306, row: 207, col: 32}], _aether._userInfo, false);\n        tmp26 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n        tmp27 = 'getEnemies';\n        _aether.logStatementStart([{ofs: 6307, row: 208, col: 0}, {ofs: 6339, row: 208, col: 32}]); enemies = _aether.createAPIClone(_aether, tmp26[tmp27]());  _aether.logStatement([{ofs: 6307, row: 208, col: 0}, {ofs: 6339, row: 208, col: 32}], _aether._userInfo, false);\n        tmp30 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n        tmp31 = 'getByType';\n        _aether.logStatementStart([{ofs: 6372, row: 210, col: 31}, {ofs: 6378, row: 210, col: 37}]); tmp32 = 'base';  _aether.logStatement([{ofs: 6372, row: 210, col: 31}, {ofs: 6378, row: 210, col: 37}], _aether._userInfo, false);\n        _aether.logStatementStart([{ofs: 6357, row: 210, col: 16}, {ofs: 6379, row: 210, col: 38}]); tmp28 = _aether.createAPIClone(_aether, tmp30[tmp31](_aether.restoreAPIClone(_aether, tmp32)));  _aether.logStatement([{ofs: 6357, row: 210, col: 16}, {ofs: 6379, row: 210, col: 38}], _aether._userInfo, false);\n        _aether.logStatementStart([{ofs: 6380, row: 210, col: 39}, {ofs: 6381, row: 210, col: 40}]); tmp29 = 0;  _aether.logStatement([{ofs: 6380, row: 210, col: 39}, {ofs: 6381, row: 210, col: 40}], _aether._userInfo, false);\n        _aether.logStatementStart([{ofs: 6341, row: 210, col: 0}, {ofs: 6383, row: 210, col: 42}]); enemyBase = tmp28[tmp29];  _aether.logStatement([{ofs: 6341, row: 210, col: 0}, {ofs: 6383, row: 210, col: 42}], _aether._userInfo, false);\n        tmp33 = enemyBase;\n        if (tmp33) {\n            tmp34 = enemyBase;\n            tmp35 = 'gold';\n            _aether.logStatementStart([{ofs: 6412, row: 211, col: 28}, {ofs: 6426, row: 211, col: 42}]); enemyGold = tmp34[tmp35];  _aether.logStatement([{ofs: 6412, row: 211, col: 28}, {ofs: 6426, row: 211, col: 42}], _aether._userInfo, false);\n        } else {\n            _aether.logStatementStart([{ofs: 6429, row: 211, col: 45}, {ofs: 6430, row: 211, col: 46}]); enemyGold = 0;  _aether.logStatement([{ofs: 6429, row: 211, col: 45}, {ofs: 6430, row: 211, col: 46}], _aether._userInfo, false);\n        }\n        tmp36 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n        tmp37 = 'getByType';\n        tmp39 = alliedTypes;\n        tmp40 = 'peasant';\n        _aether.logStatementStart([{ofs: 6463, row: 213, col: 30}, {ofs: 6482, row: 213, col: 49}]); tmp38 = tmp39[tmp40];  _aether.logStatement([{ofs: 6463, row: 213, col: 30}, {ofs: 6482, row: 213, col: 49}], _aether._userInfo, false);\n        _aether.logStatementStart([{ofs: 6433, row: 213, col: 0}, {ofs: 6484, row: 213, col: 51}]); peasants = _aether.createAPIClone(_aether, tmp36[tmp37](_aether.restoreAPIClone(_aether, tmp38)));  _aether.logStatement([{ofs: 6433, row: 213, col: 0}, {ofs: 6484, row: 213, col: 51}], _aether._userInfo, false);\n        tmp41 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n        tmp42 = 'getByType';\n        tmp44 = enemyTypes;\n        tmp45 = 'peasant';\n        _aether.logStatementStart([{ofs: 6512, row: 214, col: 27}, {ofs: 6530, row: 214, col: 45}]); tmp43 = tmp44[tmp45];  _aether.logStatement([{ofs: 6512, row: 214, col: 27}, {ofs: 6530, row: 214, col: 45}], _aether._userInfo, false);\n        _aether.logStatementStart([{ofs: 6485, row: 214, col: 0}, {ofs: 6532, row: 214, col: 47}]); peons = _aether.createAPIClone(_aether, tmp41[tmp42](_aether.restoreAPIClone(_aether, tmp43)));  _aether.logStatement([{ofs: 6485, row: 214, col: 0}, {ofs: 6532, row: 214, col: 47}], _aether._userInfo, false);\n        tmp46 = computeSpringAssignments;\n        tmp47 = peasants;\n        tmp48 = peons;\n        tmp49 = items;\n        tmp50 = computeAttractionSquared;\n        _aether.logStatementStart([{ofs: 6534, row: 216, col: 0}, {ofs: 6627, row: 216, col: 93}]); assignments = _aether.createAPIClone(_aether, tmp46(_aether.restoreAPIClone(_aether, tmp47), _aether.restoreAPIClone(_aether, tmp48), _aether.restoreAPIClone(_aether, tmp49), _aether.restoreAPIClone(_aether, tmp50)));  _aether.logStatement([{ofs: 6534, row: 216, col: 0}, {ofs: 6627, row: 216, col: 93}], _aether._userInfo, false);\n        _aether.logStatementStart([{ofs: 6633, row: 217, col: 5}, {ofs: 6642, row: 217, col: 14}]); i = 0;  _aether.logStatement([{ofs: 6633, row: 217, col: 5}, {ofs: 6642, row: 217, col: 14}], _aether._userInfo, false);\n        tmp52 = i;\n        tmp54 = assignments;\n        tmp55 = 'length';\n        _aether.logStatementStart([{ofs: 6648, row: 217, col: 20}, {ofs: 6666, row: 217, col: 38}]); tmp53 = tmp54[tmp55];  _aether.logStatement([{ofs: 6648, row: 217, col: 20}, {ofs: 6666, row: 217, col: 38}], _aether._userInfo, false);\n        _aether.logStatementStart([{ofs: 6644, row: 217, col: 16}, {ofs: 6666, row: 217, col: 38}]); tmp51 = tmp52 < tmp53;  _aether.logStatement([{ofs: 6644, row: 217, col: 16}, {ofs: 6666, row: 217, col: 38}], _aether._userInfo, false);\n        tmp62: {\n            while (tmp51) {\n                tmp63: {\n                    tmp64 = assignments;\n                    tmp65 = i;\n                    _aether.logStatementStart([{ofs: 6679, row: 218, col: 4}, {ofs: 6703, row: 218, col: 28}]); as = tmp64[tmp65];  _aether.logStatement([{ofs: 6679, row: 218, col: 4}, {ofs: 6703, row: 218, col: 28}], _aether._userInfo, false);\n                    tmp66 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n                    tmp67 = 'command';\n                    tmp71 = as;\n                    tmp72 = 'src';\n                    _aether.logStatementStart([{ofs: 6721, row: 219, col: 17}, {ofs: 6727, row: 219, col: 23}]); tmp68 = tmp71[tmp72];  _aether.logStatement([{ofs: 6721, row: 219, col: 17}, {ofs: 6727, row: 219, col: 23}], _aether._userInfo, false);\n                    _aether.logStatementStart([{ofs: 6729, row: 219, col: 25}, {ofs: 6735, row: 219, col: 31}]); tmp69 = 'move';  _aether.logStatement([{ofs: 6729, row: 219, col: 25}, {ofs: 6735, row: 219, col: 31}], _aether._userInfo, false);\n                    tmp73 = as;\n                    tmp74 = 'target';\n                    _aether.logStatementStart([{ofs: 6737, row: 219, col: 33}, {ofs: 6746, row: 219, col: 42}]); tmp70 = tmp73[tmp74];  _aether.logStatement([{ofs: 6737, row: 219, col: 33}, {ofs: 6746, row: 219, col: 42}], _aether._userInfo, false);\n                    _aether.logStatementStart([{ofs: 6708, row: 219, col: 4}, {ofs: 6747, row: 219, col: 43}]); tmp75 = _aether.createAPIClone(_aether, tmp66[tmp67](_aether.restoreAPIClone(_aether, tmp68), _aether.restoreAPIClone(_aether, tmp69), _aether.restoreAPIClone(_aether, tmp70)));  _aether.logStatement([{ofs: 6708, row: 219, col: 4}, {ofs: 6747, row: 219, col: 43}], _aether._userInfo, false);\n                }\n                tmp60 = i;\n                tmp61 = 1;\n                i = tmp60 + tmp61;\n                tmp56 = i;\n                tmp58 = assignments;\n                tmp59 = 'length';\n                _aether.logStatementStart([{ofs: 6648, row: 217, col: 20}, {ofs: 6666, row: 217, col: 38}]); tmp57 = tmp58[tmp59];  _aether.logStatement([{ofs: 6648, row: 217, col: 20}, {ofs: 6666, row: 217, col: 38}], _aether._userInfo, false);\n                _aether.logStatementStart([{ofs: 6644, row: 217, col: 16}, {ofs: 6666, row: 217, col: 38}]); tmp51 = tmp56 < tmp57;  _aether.logStatement([{ofs: 6644, row: 217, col: 16}, {ofs: 6666, row: 217, col: 38}], _aether._userInfo, false);\n            }\n        }\n        tmp76 = filterNotType;\n        tmp79 = alliedTypes;\n        tmp80 = 'peasant';\n        _aether.logStatementStart([{ofs: 8590, row: 276, col: 36}, {ofs: 8609, row: 276, col: 55}]); tmp77 = tmp79[tmp80];  _aether.logStatement([{ofs: 8590, row: 276, col: 36}, {ofs: 8609, row: 276, col: 55}], _aether._userInfo, false);\n        tmp78 = friends;\n        _aether.logStatementStart([{ofs: 8554, row: 276, col: 0}, {ofs: 8620, row: 276, col: 66}]); militaryFriends = _aether.createAPIClone(_aether, tmp76(_aether.restoreAPIClone(_aether, tmp77), _aether.restoreAPIClone(_aether, tmp78)));  _aether.logStatement([{ofs: 8554, row: 276, col: 0}, {ofs: 8620, row: 276, col: 66}], _aether._userInfo, false);\n        tmp81 = filterType;\n        tmp84 = alliedTypes;\n        tmp85 = 'soldier';\n        _aether.logStatementStart([{ofs: 8655, row: 277, col: 34}, {ofs: 8674, row: 277, col: 53}]); tmp82 = tmp84[tmp85];  _aether.logStatement([{ofs: 8655, row: 277, col: 34}, {ofs: 8674, row: 277, col: 53}], _aether._userInfo, false);\n        tmp83 = friends;\n        _aether.logStatementStart([{ofs: 8621, row: 277, col: 0}, {ofs: 8685, row: 277, col: 64}]); friendlySoldiers = _aether.createAPIClone(_aether, tmp81(_aether.restoreAPIClone(_aether, tmp82), _aether.restoreAPIClone(_aether, tmp83)));  _aether.logStatement([{ofs: 8621, row: 277, col: 0}, {ofs: 8685, row: 277, col: 64}], _aether._userInfo, false);\n        tmp86 = filterNotType;\n        _aether.logStatementStart([{ofs: 8722, row: 278, col: 36}, {ofs: 8728, row: 278, col: 42}]); tmp87 = 'base';  _aether.logStatement([{ofs: 8722, row: 278, col: 36}, {ofs: 8728, row: 278, col: 42}], _aether._userInfo, false);\n        tmp89 = filterNotType;\n        tmp92 = enemyTypes;\n        tmp93 = 'peasant';\n        _aether.logStatementStart([{ofs: 8744, row: 278, col: 58}, {ofs: 8762, row: 278, col: 76}]); tmp90 = tmp92[tmp93];  _aether.logStatement([{ofs: 8744, row: 278, col: 58}, {ofs: 8762, row: 278, col: 76}], _aether._userInfo, false);\n        tmp91 = enemies;\n        _aether.logStatementStart([{ofs: 8730, row: 278, col: 44}, {ofs: 8772, row: 278, col: 86}]); tmp88 = _aether.createAPIClone(_aether, tmp89(_aether.restoreAPIClone(_aether, tmp90), _aether.restoreAPIClone(_aether, tmp91)));  _aether.logStatement([{ofs: 8730, row: 278, col: 44}, {ofs: 8772, row: 278, col: 86}], _aether._userInfo, false);\n        _aether.logStatementStart([{ofs: 8686, row: 278, col: 0}, {ofs: 8774, row: 278, col: 88}]); militaryEnemies = _aether.createAPIClone(_aether, tmp86(_aether.restoreAPIClone(_aether, tmp87), _aether.restoreAPIClone(_aether, tmp88)));  _aether.logStatement([{ofs: 8686, row: 278, col: 0}, {ofs: 8774, row: 278, col: 88}], _aether._userInfo, false);\n        tmp94 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n        tmp95 = 'getNearest';\n        tmp96 = militaryEnemies;\n        _aether.logStatementStart([{ofs: 8775, row: 279, col: 0}, {ofs: 8827, row: 279, col: 52}]); nearestEnemy = _aether.createAPIClone(_aether, tmp94[tmp95](_aether.restoreAPIClone(_aether, tmp96)));  _aether.logStatement([{ofs: 8775, row: 279, col: 0}, {ofs: 8827, row: 279, col: 52}], _aether._userInfo, false);\n        tmp100 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n        tmp101 = 'enemyGoldHistory';\n        _aether.logStatementStart([{ofs: 8915, row: 283, col: 4}, {ofs: 8936, row: 283, col: 25}]); tmp98 = tmp100[tmp101];  _aether.logStatement([{ofs: 8915, row: 283, col: 4}, {ofs: 8936, row: 283, col: 25}], _aether._userInfo, false);\n        tmp102 = 'undefined';\n        tmp99 = __global[tmp102];\n        _aether.logStatementStart([{ofs: 8915, row: 283, col: 4}, {ofs: 8950, row: 283, col: 39}]); tmp97 = tmp98 === tmp99;  _aether.logStatement([{ofs: 8915, row: 283, col: 4}, {ofs: 8950, row: 283, col: 39}], _aether._userInfo, false);\n        if (tmp97) {\n            tmp103 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n            tmp104 = 'enemyGoldHistory';\n            _aether.logStatementStart([{ofs: 8958, row: 284, col: 4}, {ofs: 8985, row: 284, col: 31}]); tmp105 = [];  _aether.logStatement([{ofs: 8958, row: 284, col: 4}, {ofs: 8985, row: 284, col: 31}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 8958, row: 284, col: 4}, {ofs: 8984, row: 284, col: 30}]); tmp103[tmp104] = tmp105;  _aether.logStatement([{ofs: 8958, row: 284, col: 4}, {ofs: 8984, row: 284, col: 30}], _aether._userInfo, false);\n        } else {\n            ;\n        }\n        tmp109 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n        tmp110 = 'counter';\n        _aether.logStatementStart([{ofs: 8993, row: 287, col: 4}, {ofs: 9005, row: 287, col: 16}]); tmp107 = tmp109[tmp110];  _aether.logStatement([{ofs: 8993, row: 287, col: 4}, {ofs: 9005, row: 287, col: 16}], _aether._userInfo, false);\n        tmp111 = 'undefined';\n        tmp108 = __global[tmp111];\n        _aether.logStatementStart([{ofs: 8993, row: 287, col: 4}, {ofs: 9019, row: 287, col: 30}]); tmp106 = tmp107 === tmp108;  _aether.logStatement([{ofs: 8993, row: 287, col: 4}, {ofs: 9019, row: 287, col: 30}], _aether._userInfo, false);\n        if (tmp106) {\n            tmp112 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n            tmp113 = 'counter';\n            _aether.logStatementStart([{ofs: 9027, row: 288, col: 4}, {ofs: 9044, row: 288, col: 21}]); tmp114 = 0;  _aether.logStatement([{ofs: 9027, row: 288, col: 4}, {ofs: 9044, row: 288, col: 21}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 9027, row: 288, col: 4}, {ofs: 9043, row: 288, col: 20}]); tmp112[tmp113] = tmp114;  _aether.logStatement([{ofs: 9027, row: 288, col: 4}, {ofs: 9043, row: 288, col: 20}], _aether._userInfo, false);\n        } else {\n            ;\n        }\n        _aether.logStatementStart([{ofs: 9048, row: 291, col: 0}, {ofs: 9082, row: 291, col: 34}]); PREDICTOR_HISTORY_LENGTH = 25;  _aether.logStatement([{ofs: 9048, row: 291, col: 0}, {ofs: 9082, row: 291, col: 34}], _aether._userInfo, false);\n        _aether.logStatementStart([{ofs: 9083, row: 292, col: 0}, {ofs: 9117, row: 292, col: 34}]); PREDICTOR_SAMPLE_INTERVAL = 4;  _aether.logStatement([{ofs: 9083, row: 292, col: 0}, {ofs: 9117, row: 292, col: 34}], _aether._userInfo, false);\n        _aether.logStatementStart([{ofs: 9118, row: 293, col: 0}, {ofs: 9152, row: 293, col: 34}]); PREDICTOR_LOOKAHEAD_TIME = 17;  _aether.logStatement([{ofs: 9118, row: 293, col: 0}, {ofs: 9152, row: 293, col: 34}], _aether._userInfo, false);\n        _aether.logStatementStart([{ofs: 9154, row: 295, col: 0}, {ofs: 9178, row: 295, col: 24}]); enemyTotalWorth = 0;  _aether.logStatement([{ofs: 9154, row: 295, col: 0}, {ofs: 9178, row: 295, col: 24}], _aether._userInfo, false);\n        tmp115 = enemyBase;\n        if (tmp115) {\n            tmp118 = valuateFighters;\n            tmp120 = enemyBase;\n            tmp121 = 'built';\n            _aether.logStatementStart([{ofs: 9234, row: 297, col: 38}, {ofs: 9249, row: 297, col: 53}]); tmp119 = tmp120[tmp121];  _aether.logStatement([{ofs: 9234, row: 297, col: 38}, {ofs: 9249, row: 297, col: 53}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 9218, row: 297, col: 22}, {ofs: 9250, row: 297, col: 54}]); tmp116 = _aether.createAPIClone(_aether, tmp118(_aether.restoreAPIClone(_aether, tmp119)));  _aether.logStatement([{ofs: 9218, row: 297, col: 22}, {ofs: 9250, row: 297, col: 54}], _aether._userInfo, false);\n            tmp117 = enemyGold;\n            _aether.logStatementStart([{ofs: 9200, row: 297, col: 4}, {ofs: 9263, row: 297, col: 67}]); enemyTotalWorth = tmp116 + tmp117;  _aether.logStatement([{ofs: 9200, row: 297, col: 4}, {ofs: 9263, row: 297, col: 67}], _aether._userInfo, false);\n        } else {\n            ;\n        }\n        tmp127 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n        tmp128 = 'counter';\n        _aether.logStatementStart([{ofs: 9271, row: 300, col: 4}, {ofs: 9285, row: 300, col: 18}]); tmp125 = tmp127[tmp128];  _aether.logStatement([{ofs: 9271, row: 300, col: 4}, {ofs: 9285, row: 300, col: 18}], _aether._userInfo, false);\n        _aether.logStatementStart([{ofs: 9271, row: 300, col: 4}, {ofs: 9285, row: 300, col: 18}]); tmp130 = 1;  _aether.logStatement([{ofs: 9271, row: 300, col: 4}, {ofs: 9285, row: 300, col: 18}], _aether._userInfo, false);\n        _aether.logStatementStart([{ofs: 9271, row: 300, col: 4}, {ofs: 9285, row: 300, col: 18}]); tmp129 = tmp125 + tmp130;  _aether.logStatement([{ofs: 9271, row: 300, col: 4}, {ofs: 9285, row: 300, col: 18}], _aether._userInfo, false);\n        _aether.logStatementStart([{ofs: 9271, row: 300, col: 4}, {ofs: 9285, row: 300, col: 18}]); tmp127[tmp128] = tmp129;  _aether.logStatement([{ofs: 9271, row: 300, col: 4}, {ofs: 9285, row: 300, col: 18}], _aether._userInfo, false);\n        tmp126 = PREDICTOR_SAMPLE_INTERVAL;\n        _aether.logStatementStart([{ofs: 9271, row: 300, col: 4}, {ofs: 9313, row: 300, col: 46}]); tmp123 = tmp125 % tmp126;  _aether.logStatement([{ofs: 9271, row: 300, col: 4}, {ofs: 9313, row: 300, col: 46}], _aether._userInfo, false);\n        _aether.logStatementStart([{ofs: 9318, row: 300, col: 51}, {ofs: 9319, row: 300, col: 52}]); tmp124 = 0;  _aether.logStatement([{ofs: 9318, row: 300, col: 51}, {ofs: 9319, row: 300, col: 52}], _aether._userInfo, false);\n        _aether.logStatementStart([{ofs: 9271, row: 300, col: 4}, {ofs: 9319, row: 300, col: 52}]); tmp122 = tmp123 === tmp124;  _aether.logStatement([{ofs: 9271, row: 300, col: 4}, {ofs: 9319, row: 300, col: 52}], _aether._userInfo, false);\n        if (tmp122) {\n            tmp133 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n            tmp134 = 'enemyGoldHistory';\n            _aether.logStatementStart([{ofs: 9327, row: 301, col: 4}, {ofs: 9348, row: 301, col: 25}]); tmp131 = tmp133[tmp134];  _aether.logStatement([{ofs: 9327, row: 301, col: 4}, {ofs: 9348, row: 301, col: 25}], _aether._userInfo, false);\n            tmp132 = 'push';\n            tmp138 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n            tmp139 = 'now';\n            _aether.logStatementStart([{ofs: 9358, row: 301, col: 35}, {ofs: 9368, row: 301, col: 45}]); tmp136 = _aether.createAPIClone(_aether, tmp138[tmp139]());  _aether.logStatement([{ofs: 9358, row: 301, col: 35}, {ofs: 9368, row: 301, col: 45}], _aether._userInfo, false);\n            tmp137 = enemyTotalWorth;\n            _aether.logStatementStart([{ofs: 9354, row: 301, col: 31}, {ofs: 9389, row: 301, col: 66}]); tmp135 = {\n                x: tmp136,\n                y: tmp137\n            };  _aether.logStatement([{ofs: 9354, row: 301, col: 31}, {ofs: 9389, row: 301, col: 66}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 9327, row: 301, col: 4}, {ofs: 9390, row: 301, col: 67}]); tmp140 = _aether.createAPIClone(_aether, tmp131[tmp132](_aether.restoreAPIClone(_aether, tmp135)));  _aether.logStatement([{ofs: 9327, row: 301, col: 4}, {ofs: 9390, row: 301, col: 67}], _aether._userInfo, false);\n        } else {\n            ;\n        }\n        tmp146 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n        tmp147 = 'enemyGoldHistory';\n        _aether.logStatementStart([{ofs: 9399, row: 304, col: 4}, {ofs: 9420, row: 304, col: 25}]); tmp144 = tmp146[tmp147];  _aether.logStatement([{ofs: 9399, row: 304, col: 4}, {ofs: 9420, row: 304, col: 25}], _aether._userInfo, false);\n        tmp145 = 'length';\n        _aether.logStatementStart([{ofs: 9399, row: 304, col: 4}, {ofs: 9427, row: 304, col: 32}]); tmp142 = tmp144[tmp145];  _aether.logStatement([{ofs: 9399, row: 304, col: 4}, {ofs: 9427, row: 304, col: 32}], _aether._userInfo, false);\n        tmp143 = PREDICTOR_HISTORY_LENGTH;\n        _aether.logStatementStart([{ofs: 9399, row: 304, col: 4}, {ofs: 9454, row: 304, col: 59}]); tmp141 = tmp142 > tmp143;  _aether.logStatement([{ofs: 9399, row: 304, col: 4}, {ofs: 9454, row: 304, col: 59}], _aether._userInfo, false);\n        if (tmp141) {\n            tmp150 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n            tmp151 = 'enemyGoldHistory';\n            _aether.logStatementStart([{ofs: 9462, row: 305, col: 4}, {ofs: 9483, row: 305, col: 25}]); tmp148 = tmp150[tmp151];  _aether.logStatement([{ofs: 9462, row: 305, col: 4}, {ofs: 9483, row: 305, col: 25}], _aether._userInfo, false);\n            tmp149 = 'shift';\n            _aether.logStatementStart([{ofs: 9462, row: 305, col: 4}, {ofs: 9491, row: 305, col: 33}]); tmp152 = _aether.createAPIClone(_aether, tmp148[tmp149]());  _aether.logStatement([{ofs: 9462, row: 305, col: 4}, {ofs: 9491, row: 305, col: 33}], _aether._userInfo, false);\n        } else {\n            ;\n        }\n        tmp153 = valuateFighters;\n        tmp154 = militaryFriends;\n        _aether.logStatementStart([{ofs: 9496, row: 308, col: 0}, {ofs: 9555, row: 308, col: 59}]); ourMilitaryStrength = _aether.createAPIClone(_aether, tmp153(_aether.restoreAPIClone(_aether, tmp154)));  _aether.logStatement([{ofs: 9496, row: 308, col: 0}, {ofs: 9555, row: 308, col: 59}], _aether._userInfo, false);\n        tmp155 = valuateFighters;\n        tmp156 = militaryEnemies;\n        _aether.logStatementStart([{ofs: 9556, row: 309, col: 0}, {ofs: 9617, row: 309, col: 61}]); enemyMilitaryStrength = _aether.createAPIClone(_aether, tmp155(_aether.restoreAPIClone(_aether, tmp156)));  _aether.logStatement([{ofs: 9556, row: 309, col: 0}, {ofs: 9617, row: 309, col: 61}], _aether._userInfo, false);\n        tmp157 = ourMilitaryStrength;\n        tmp159 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n        tmp160 = 'gold';\n        _aether.logStatementStart([{ofs: 9659, row: 311, col: 40}, {ofs: 9668, row: 311, col: 49}]); tmp158 = tmp159[tmp160];  _aether.logStatement([{ofs: 9659, row: 311, col: 40}, {ofs: 9668, row: 311, col: 49}], _aether._userInfo, false);\n        _aether.logStatementStart([{ofs: 9619, row: 311, col: 0}, {ofs: 9669, row: 311, col: 50}]); ourStrength = tmp157 + tmp158;  _aether.logStatement([{ofs: 9619, row: 311, col: 0}, {ofs: 9669, row: 311, col: 50}], _aether._userInfo, false);\n        tmp161 = enemyMilitaryStrength;\n        tmp162 = enemyGold;\n        _aether.logStatementStart([{ofs: 9670, row: 312, col: 0}, {ofs: 9724, row: 312, col: 54}]); enemyStrength = tmp161 + tmp162;  _aether.logStatement([{ofs: 9670, row: 312, col: 0}, {ofs: 9724, row: 312, col: 54}], _aether._userInfo, false);\n        _aether.logStatementStart([{ofs: 9725, row: 313, col: 0}, {ofs: 9758, row: 313, col: 33}]); enemyStrengthForecast = null;  _aether.logStatement([{ofs: 9725, row: 313, col: 0}, {ofs: 9758, row: 313, col: 33}], _aether._userInfo, false);\n        tmp168 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n        tmp169 = 'enemyGoldHistory';\n        _aether.logStatementStart([{ofs: 9764, row: 315, col: 4}, {ofs: 9785, row: 315, col: 25}]); tmp166 = tmp168[tmp169];  _aether.logStatement([{ofs: 9764, row: 315, col: 4}, {ofs: 9785, row: 315, col: 25}], _aether._userInfo, false);\n        tmp167 = 'length';\n        _aether.logStatementStart([{ofs: 9764, row: 315, col: 4}, {ofs: 9792, row: 315, col: 32}]); tmp164 = tmp166[tmp167];  _aether.logStatement([{ofs: 9764, row: 315, col: 4}, {ofs: 9792, row: 315, col: 32}], _aether._userInfo, false);\n        tmp165 = PREDICTOR_HISTORY_LENGTH;\n        _aether.logStatementStart([{ofs: 9764, row: 315, col: 4}, {ofs: 9820, row: 315, col: 60}]); tmp163 = tmp164 >= tmp165;  _aether.logStatement([{ofs: 9764, row: 315, col: 4}, {ofs: 9820, row: 315, col: 60}], _aether._userInfo, false);\n        if (tmp163) {\n            tmp170 = estimateHighLow;\n            tmp173 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n            tmp174 = 'enemyGoldHistory';\n            _aether.logStatementStart([{ofs: 9859, row: 316, col: 35}, {ofs: 9880, row: 316, col: 56}]); tmp171 = tmp173[tmp174];  _aether.logStatement([{ofs: 9859, row: 316, col: 35}, {ofs: 9880, row: 316, col: 56}], _aether._userInfo, false);\n            tmp177 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n            tmp178 = 'now';\n            _aether.logStatementStart([{ofs: 9882, row: 316, col: 58}, {ofs: 9892, row: 316, col: 68}]); tmp175 = _aether.createAPIClone(_aether, tmp177[tmp178]());  _aether.logStatement([{ofs: 9882, row: 316, col: 58}, {ofs: 9892, row: 316, col: 68}], _aether._userInfo, false);\n            tmp176 = PREDICTOR_LOOKAHEAD_TIME;\n            _aether.logStatementStart([{ofs: 9882, row: 316, col: 58}, {ofs: 9919, row: 316, col: 95}]); tmp172 = tmp175 + tmp176;  _aether.logStatement([{ofs: 9882, row: 316, col: 58}, {ofs: 9919, row: 316, col: 95}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 9828, row: 316, col: 4}, {ofs: 9921, row: 316, col: 97}]); highLowE = _aether.createAPIClone(_aether, tmp170(_aether.restoreAPIClone(_aether, tmp171), _aether.restoreAPIClone(_aether, tmp172)));  _aether.logStatement([{ofs: 9828, row: 316, col: 4}, {ofs: 9921, row: 316, col: 97}], _aether._userInfo, false);\n            tmp181 = highLowE;\n            _aether.logStatementStart([{ofs: 9958, row: 317, col: 36}, {ofs: 9959, row: 317, col: 37}]); tmp182 = 0;  _aether.logStatement([{ofs: 9958, row: 317, col: 36}, {ofs: 9959, row: 317, col: 37}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 9949, row: 317, col: 27}, {ofs: 9960, row: 317, col: 38}]); tmp179 = tmp181[tmp182];  _aether.logStatement([{ofs: 9949, row: 317, col: 27}, {ofs: 9960, row: 317, col: 38}], _aether._userInfo, false);\n            tmp180 = enemyTotalWorth;\n            _aether.logStatementStart([{ofs: 9926, row: 317, col: 4}, {ofs: 9979, row: 317, col: 57}]); futureEnemyBonus = tmp179 - tmp180;  _aether.logStatement([{ofs: 9926, row: 317, col: 4}, {ofs: 9979, row: 317, col: 57}], _aether._userInfo, false);\n            tmp183 = enemyStrength;\n            tmp184 = futureEnemyBonus;\n            _aether.logStatementStart([{ofs: 9985, row: 319, col: 4}, {ofs: 10042, row: 319, col: 61}]); enemyStrengthForecast = tmp183 + tmp184;  _aether.logStatement([{ofs: 9985, row: 319, col: 4}, {ofs: 10042, row: 319, col: 61}], _aether._userInfo, false);\n        } else {\n            ;\n        }\n        _aether.logStatementStart([{ofs: 10161, row: 325, col: 10}, {ofs: 10172, row: 325, col: 21}]); tmp185 = 'doNothing';  _aether.logStatement([{ofs: 10161, row: 325, col: 10}, {ofs: 10172, row: 325, col: 21}], _aether._userInfo, false);\n        _aether.logStatementStart([{ofs: 10197, row: 327, col: 18}, {ofs: 10236, row: 329, col: 5}]); tmp186 = function () {\n            var tmp188;  for(var __argIndexer = 0; __argIndexer < arguments.length; ++__argIndexer) arguments[__argIndexer] = _aether.createAPIClone(_aether, arguments[__argIndexer]);\n            _aether.logStatementStart([{ofs: 10225, row: 328, col: 15}, {ofs: 10229, row: 328, col: 19}]); tmp188 = true;  _aether.logStatement([{ofs: 10225, row: 328, col: 15}, {ofs: 10229, row: 328, col: 19}], _aether._userInfo, false);\n            return _aether.restoreAPIClone(_aether, tmp188);\n        };  _aether.logStatement([{ofs: 10197, row: 327, col: 18}, {ofs: 10236, row: 329, col: 5}], _aether._userInfo, false);\n        _aether.logStatementStart([{ofs: 10268, row: 331, col: 21}, {ofs: 10307, row: 333, col: 5}]); tmp187 = function () {\n            var tmp189;  for(var __argIndexer = 0; __argIndexer < arguments.length; ++__argIndexer) arguments[__argIndexer] = _aether.createAPIClone(_aether, arguments[__argIndexer]);\n            _aether.logStatementStart([{ofs: 10296, row: 332, col: 15}, {ofs: 10300, row: 332, col: 19}]); tmp189 = null;  _aether.logStatement([{ofs: 10296, row: 332, col: 15}, {ofs: 10300, row: 332, col: 19}], _aether._userInfo, false);\n            return _aether.restoreAPIClone(_aether, tmp189);\n        };  _aether.logStatement([{ofs: 10268, row: 331, col: 21}, {ofs: 10307, row: 333, col: 5}], _aether._userInfo, false);\n        _aether.logStatementStart([{ofs: 10128, row: 324, col: 0}, {ofs: 10310, row: 334, col: 2}]); doNothingState = {\n            name: tmp185,\n            wantsControl: tmp186,\n            selectBuildType: tmp187\n        };  _aether.logStatement([{ofs: 10128, row: 324, col: 0}, {ofs: 10310, row: 334, col: 2}], _aether._userInfo, false);\n        _aether.logStatementStart([{ofs: 10343, row: 337, col: 10}, {ofs: 10352, row: 337, col: 19}]); tmp190 = 'collect';  _aether.logStatement([{ofs: 10343, row: 337, col: 10}, {ofs: 10352, row: 337, col: 19}], _aether._userInfo, false);\n        _aether.logStatementStart([{ofs: 10377, row: 339, col: 18}, {ofs: 10963, row: 358, col: 5}]); tmp191 = function (base) {\n            var coinsPerPeasant, tmp193, tmp194, tmp195, tmp196, tmp197, tmp198, tmp199, tmp200, tmp201, tmp202, tmp203, tmp204, tmp205, tmp206, tmp207, tmp208, tmp209, tmp210, tmp211, tmp212, tmp213, tmp214, tmp215, tmp216, tmp217, tmp218, tmp219, tmp220, tmp221, tmp222, tmp223, tmp224, tmp225; base = _aether.createAPIClone(_aether, base); for(var __argIndexer = 0; __argIndexer < arguments.length; ++__argIndexer) arguments[__argIndexer] = _aether.createAPIClone(_aether, arguments[__argIndexer]);\n            tmp196 = peasants;\n            tmp197 = 'length';\n            _aether.logStatementStart([{ofs: 10451, row: 341, col: 13}, {ofs: 10466, row: 341, col: 28}]); tmp194 = tmp196[tmp197];  _aether.logStatement([{ofs: 10451, row: 341, col: 13}, {ofs: 10466, row: 341, col: 28}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 10469, row: 341, col: 31}, {ofs: 10470, row: 341, col: 32}]); tmp195 = 1;  _aether.logStatement([{ofs: 10469, row: 341, col: 31}, {ofs: 10470, row: 341, col: 32}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 10451, row: 341, col: 13}, {ofs: 10470, row: 341, col: 32}]); tmp193 = tmp194 < tmp195;  _aether.logStatement([{ofs: 10451, row: 341, col: 13}, {ofs: 10470, row: 341, col: 32}], _aether._userInfo, false);\n            if (tmp193) {\n                _aether.logStatementStart([{ofs: 10493, row: 342, col: 19}, {ofs: 10497, row: 342, col: 23}]); tmp198 = true;  _aether.logStatement([{ofs: 10493, row: 342, col: 19}, {ofs: 10497, row: 342, col: 23}], _aether._userInfo, false);\n                return _aether.restoreAPIClone(_aether, tmp198);\n            } else {\n                ;\n            }\n            tmp202 = enemyGold;\n            _aether.logStatementStart([{ofs: 10597, row: 346, col: 25}, {ofs: 10599, row: 346, col: 27}]); tmp203 = 70;  _aether.logStatement([{ofs: 10597, row: 346, col: 25}, {ofs: 10599, row: 346, col: 27}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 10584, row: 346, col: 12}, {ofs: 10599, row: 346, col: 27}]); tmp201 = tmp202 <= tmp203;  _aether.logStatement([{ofs: 10584, row: 346, col: 12}, {ofs: 10599, row: 346, col: 27}], _aether._userInfo, false);\n            if (tmp201) {\n                tmp206 = peasants;\n                tmp207 = 'length';\n                _aether.logStatementStart([{ofs: 10603, row: 346, col: 31}, {ofs: 10618, row: 346, col: 46}]); tmp204 = tmp206[tmp207];  _aether.logStatement([{ofs: 10603, row: 346, col: 31}, {ofs: 10618, row: 346, col: 46}], _aether._userInfo, false);\n                tmp208 = peons;\n                tmp209 = 'length';\n                _aether.logStatementStart([{ofs: 10621, row: 346, col: 49}, {ofs: 10633, row: 346, col: 61}]); tmp205 = tmp208[tmp209];  _aether.logStatement([{ofs: 10621, row: 346, col: 49}, {ofs: 10633, row: 346, col: 61}], _aether._userInfo, false);\n                _aether.logStatementStart([{ofs: 10603, row: 346, col: 31}, {ofs: 10633, row: 346, col: 61}]); tmp200 = tmp204 < tmp205;  _aether.logStatement([{ofs: 10603, row: 346, col: 31}, {ofs: 10633, row: 346, col: 61}], _aether._userInfo, false);\n            } else {\n                _aether.logStatementStart([{ofs: 10584, row: 346, col: 12}, {ofs: 10633, row: 346, col: 61}]); tmp200 = tmp201;  _aether.logStatement([{ofs: 10584, row: 346, col: 12}, {ofs: 10633, row: 346, col: 61}], _aether._userInfo, false);\n            }\n            if (tmp200) {\n                tmp212 = peasants;\n                tmp213 = 'length';\n                _aether.logStatementStart([{ofs: 10637, row: 346, col: 65}, {ofs: 10652, row: 346, col: 80}]); tmp210 = tmp212[tmp213];  _aether.logStatement([{ofs: 10637, row: 346, col: 65}, {ofs: 10652, row: 346, col: 80}], _aether._userInfo, false);\n                _aether.logStatementStart([{ofs: 10655, row: 346, col: 83}, {ofs: 10656, row: 346, col: 84}]); tmp211 = 6;  _aether.logStatement([{ofs: 10655, row: 346, col: 83}, {ofs: 10656, row: 346, col: 84}], _aether._userInfo, false);\n                _aether.logStatementStart([{ofs: 10637, row: 346, col: 65}, {ofs: 10656, row: 346, col: 84}]); tmp199 = tmp210 < tmp211;  _aether.logStatement([{ofs: 10637, row: 346, col: 65}, {ofs: 10656, row: 346, col: 84}], _aether._userInfo, false);\n            } else {\n                _aether.logStatementStart([{ofs: 10584, row: 346, col: 12}, {ofs: 10656, row: 346, col: 84}]); tmp199 = tmp200;  _aether.logStatement([{ofs: 10584, row: 346, col: 12}, {ofs: 10656, row: 346, col: 84}], _aether._userInfo, false);\n            }\n            if (tmp199) {\n                _aether.logStatementStart([{ofs: 10679, row: 347, col: 19}, {ofs: 10683, row: 347, col: 23}]); tmp214 = true;  _aether.logStatement([{ofs: 10679, row: 347, col: 19}, {ofs: 10683, row: 347, col: 23}], _aether._userInfo, false);\n                return _aether.restoreAPIClone(_aether, tmp214);\n            } else {\n                ;\n            }\n            tmp217 = items;\n            tmp218 = 'length';\n            _aether.logStatementStart([{ofs: 10824, row: 352, col: 30}, {ofs: 10836, row: 352, col: 42}]); tmp215 = tmp217[tmp218];  _aether.logStatement([{ofs: 10824, row: 352, col: 30}, {ofs: 10836, row: 352, col: 42}], _aether._userInfo, false);\n            tmp219 = peasants;\n            tmp220 = 'length';\n            _aether.logStatementStart([{ofs: 10839, row: 352, col: 45}, {ofs: 10854, row: 352, col: 60}]); tmp216 = tmp219[tmp220];  _aether.logStatement([{ofs: 10839, row: 352, col: 45}, {ofs: 10854, row: 352, col: 60}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 10802, row: 352, col: 8}, {ofs: 10855, row: 352, col: 61}]); coinsPerPeasant = tmp215 / tmp216;  _aether.logStatement([{ofs: 10802, row: 352, col: 8}, {ofs: 10855, row: 352, col: 61}], _aether._userInfo, false);\n            tmp222 = coinsPerPeasant;\n            _aether.logStatementStart([{ofs: 10887, row: 353, col: 31}, {ofs: 10888, row: 353, col: 32}]); tmp223 = 2;  _aether.logStatement([{ofs: 10887, row: 353, col: 31}, {ofs: 10888, row: 353, col: 32}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 10868, row: 353, col: 12}, {ofs: 10888, row: 353, col: 32}]); tmp221 = tmp222 >= tmp223;  _aether.logStatement([{ofs: 10868, row: 353, col: 12}, {ofs: 10888, row: 353, col: 32}], _aether._userInfo, false);\n            if (tmp221) {\n                _aether.logStatementStart([{ofs: 10911, row: 354, col: 19}, {ofs: 10915, row: 354, col: 23}]); tmp224 = true;  _aether.logStatement([{ofs: 10911, row: 354, col: 19}, {ofs: 10915, row: 354, col: 23}], _aether._userInfo, false);\n                return _aether.restoreAPIClone(_aether, tmp224);\n            } else {\n                ;\n            }\n            _aether.logStatementStart([{ofs: 10951, row: 357, col: 15}, {ofs: 10956, row: 357, col: 20}]); tmp225 = false;  _aether.logStatement([{ofs: 10951, row: 357, col: 15}, {ofs: 10956, row: 357, col: 20}], _aether._userInfo, false);\n            return _aether.restoreAPIClone(_aether, tmp225);\n        };  _aether.logStatement([{ofs: 10377, row: 339, col: 18}, {ofs: 10963, row: 358, col: 5}], _aether._userInfo, false);\n        _aether.logStatementStart([{ofs: 10995, row: 360, col: 21}, {ofs: 11053, row: 362, col: 5}]); tmp192 = function (base) {\n            var tmp226, tmp227, tmp228; base = _aether.createAPIClone(_aether, base); for(var __argIndexer = 0; __argIndexer < arguments.length; ++__argIndexer) arguments[__argIndexer] = _aether.createAPIClone(_aether, arguments[__argIndexer]);\n            tmp227 = alliedTypes;\n            tmp228 = 'peasant';\n            _aether.logStatementStart([{ofs: 11027, row: 361, col: 15}, {ofs: 11046, row: 361, col: 34}]); tmp226 = tmp227[tmp228];  _aether.logStatement([{ofs: 11027, row: 361, col: 15}, {ofs: 11046, row: 361, col: 34}], _aether._userInfo, false);\n            return _aether.restoreAPIClone(_aether, tmp226);\n        };  _aether.logStatement([{ofs: 10995, row: 360, col: 21}, {ofs: 11053, row: 362, col: 5}], _aether._userInfo, false);\n        _aether.logStatementStart([{ofs: 10312, row: 336, col: 0}, {ofs: 11056, row: 363, col: 2}]); collectState = {\n            name: tmp190,\n            wantsControl: tmp191,\n            selectBuildType: tmp192\n        };  _aether.logStatement([{ofs: 10312, row: 336, col: 0}, {ofs: 11056, row: 363, col: 2}], _aether._userInfo, false);\n        _aether.logStatementStart([{ofs: 11086, row: 366, col: 10}, {ofs: 11092, row: 366, col: 16}]); tmp229 = 'poke';  _aether.logStatement([{ofs: 11086, row: 366, col: 10}, {ofs: 11092, row: 366, col: 16}], _aether._userInfo, false);\n        _aether.logStatementStart([{ofs: 11117, row: 368, col: 18}, {ofs: 11167, row: 370, col: 5}]); tmp230 = function (base) {\n            var tmp232, tmp233, tmp234, tmp235; base = _aether.createAPIClone(_aether, base); for(var __argIndexer = 0; __argIndexer < arguments.length; ++__argIndexer) arguments[__argIndexer] = _aether.createAPIClone(_aether, arguments[__argIndexer]);\n            tmp234 = base;\n            tmp235 = 'poked';\n            _aether.logStatementStart([{ofs: 11150, row: 369, col: 16}, {ofs: 11160, row: 369, col: 26}]); tmp233 = tmp234[tmp235];  _aether.logStatement([{ofs: 11150, row: 369, col: 16}, {ofs: 11160, row: 369, col: 26}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 11149, row: 369, col: 15}, {ofs: 11160, row: 369, col: 26}]); tmp232 = !tmp233;  _aether.logStatement([{ofs: 11149, row: 369, col: 15}, {ofs: 11160, row: 369, col: 26}], _aether._userInfo, false);\n            return _aether.restoreAPIClone(_aether, tmp232);\n        };  _aether.logStatement([{ofs: 11117, row: 368, col: 18}, {ofs: 11167, row: 370, col: 5}], _aether._userInfo, false);\n        _aether.logStatementStart([{ofs: 11199, row: 372, col: 21}, {ofs: 11363, row: 379, col: 5}]); tmp231 = function (base) {\n            var tmp236, tmp237, tmp238, tmp239, tmp240, tmp241, tmp242, tmp243, tmp244, tmp245, tmp246, tmp247; base = _aether.createAPIClone(_aether, base); for(var __argIndexer = 0; __argIndexer < arguments.length; ++__argIndexer) arguments[__argIndexer] = _aether.createAPIClone(_aether, arguments[__argIndexer]);\n            tmp239 = base;\n            tmp240 = 'gold';\n            _aether.logStatementStart([{ofs: 11228, row: 373, col: 12}, {ofs: 11237, row: 373, col: 21}]); tmp237 = tmp239[tmp240];  _aether.logStatement([{ofs: 11228, row: 373, col: 12}, {ofs: 11237, row: 373, col: 21}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 11241, row: 373, col: 25}, {ofs: 11243, row: 373, col: 27}]); tmp238 = 10;  _aether.logStatement([{ofs: 11241, row: 373, col: 25}, {ofs: 11243, row: 373, col: 27}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 11228, row: 373, col: 12}, {ofs: 11243, row: 373, col: 27}]); tmp236 = tmp237 >= tmp238;  _aether.logStatement([{ofs: 11228, row: 373, col: 12}, {ofs: 11243, row: 373, col: 27}], _aether._userInfo, false);\n            if (tmp236) {\n                tmp241 = base;\n                tmp242 = 'poked';\n                _aether.logStatementStart([{ofs: 11259, row: 374, col: 12}, {ofs: 11277, row: 374, col: 30}]); tmp243 = true;  _aether.logStatement([{ofs: 11259, row: 374, col: 12}, {ofs: 11277, row: 374, col: 30}], _aether._userInfo, false);\n                _aether.logStatementStart([{ofs: 11259, row: 374, col: 12}, {ofs: 11276, row: 374, col: 29}]); tmp241[tmp242] = tmp243;  _aether.logStatement([{ofs: 11259, row: 374, col: 12}, {ofs: 11276, row: 374, col: 29}], _aether._userInfo, false);\n                tmp245 = alliedTypes;\n                tmp246 = 'soldier';\n                _aether.logStatementStart([{ofs: 11297, row: 375, col: 19}, {ofs: 11316, row: 375, col: 38}]); tmp244 = tmp245[tmp246];  _aether.logStatement([{ofs: 11297, row: 375, col: 19}, {ofs: 11316, row: 375, col: 38}], _aether._userInfo, false);\n                return _aether.restoreAPIClone(_aether, tmp244);\n            } else {\n                ;\n            }\n            _aether.logStatementStart([{ofs: 11352, row: 378, col: 15}, {ofs: 11356, row: 378, col: 19}]); tmp247 = null;  _aether.logStatement([{ofs: 11352, row: 378, col: 15}, {ofs: 11356, row: 378, col: 19}], _aether._userInfo, false);\n            return _aether.restoreAPIClone(_aether, tmp247);\n        };  _aether.logStatement([{ofs: 11199, row: 372, col: 21}, {ofs: 11363, row: 379, col: 5}], _aether._userInfo, false);\n        _aether.logStatementStart([{ofs: 11058, row: 365, col: 0}, {ofs: 11366, row: 380, col: 2}]); pokeState = {\n            name: tmp229,\n            wantsControl: tmp230,\n            selectBuildType: tmp231\n        };  _aether.logStatement([{ofs: 11058, row: 365, col: 0}, {ofs: 11366, row: 380, col: 2}], _aether._userInfo, false);\n        _aether.logStatementStart([{ofs: 11401, row: 383, col: 10}, {ofs: 11412, row: 383, col: 21}]); tmp248 = 'stockpile';  _aether.logStatement([{ofs: 11401, row: 383, col: 10}, {ofs: 11412, row: 383, col: 21}], _aether._userInfo, false);\n        _aether.logStatementStart([{ofs: 11437, row: 385, col: 18}, {ofs: 11657, row: 393, col: 5}]); tmp249 = function (base) {\n            var strengthRatio, tmp251, tmp252, tmp253, tmp254, tmp255, tmp256, tmp257, tmp258, tmp259, tmp260, tmp261; base = _aether.createAPIClone(_aether, base); for(var __argIndexer = 0; __argIndexer < arguments.length; ++__argIndexer) arguments[__argIndexer] = _aether.createAPIClone(_aether, arguments[__argIndexer]);\n            tmp253 = ourMilitaryStrength;\n            tmp255 = base;\n            tmp256 = 'gold';\n            _aether.logStatementStart([{ofs: 11505, row: 386, col: 51}, {ofs: 11514, row: 386, col: 60}]); tmp254 = tmp255[tmp256];  _aether.logStatement([{ofs: 11505, row: 386, col: 51}, {ofs: 11514, row: 386, col: 60}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 11483, row: 386, col: 29}, {ofs: 11514, row: 386, col: 60}]); tmp251 = tmp253 + tmp254;  _aether.logStatement([{ofs: 11483, row: 386, col: 29}, {ofs: 11514, row: 386, col: 60}], _aether._userInfo, false);\n            tmp252 = enemyMilitaryStrength;\n            _aether.logStatementStart([{ofs: 11462, row: 386, col: 8}, {ofs: 11540, row: 386, col: 86}]); strengthRatio = tmp251 / tmp252;  _aether.logStatement([{ofs: 11462, row: 386, col: 8}, {ofs: 11540, row: 386, col: 86}], _aether._userInfo, false);\n            tmp258 = strengthRatio;\n            _aether.logStatementStart([{ofs: 11579, row: 388, col: 29}, {ofs: 11582, row: 388, col: 32}]); tmp259 = 1.2;  _aether.logStatement([{ofs: 11579, row: 388, col: 29}, {ofs: 11582, row: 388, col: 32}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 11562, row: 388, col: 12}, {ofs: 11582, row: 388, col: 32}]); tmp257 = tmp258 <= tmp259;  _aether.logStatement([{ofs: 11562, row: 388, col: 12}, {ofs: 11582, row: 388, col: 32}], _aether._userInfo, false);\n            if (tmp257) {\n                _aether.logStatementStart([{ofs: 11605, row: 389, col: 19}, {ofs: 11609, row: 389, col: 23}]); tmp260 = true;  _aether.logStatement([{ofs: 11605, row: 389, col: 19}, {ofs: 11609, row: 389, col: 23}], _aether._userInfo, false);\n                return _aether.restoreAPIClone(_aether, tmp260);\n            } else {\n                ;\n            }\n            _aether.logStatementStart([{ofs: 11645, row: 392, col: 15}, {ofs: 11650, row: 392, col: 20}]); tmp261 = false;  _aether.logStatement([{ofs: 11645, row: 392, col: 15}, {ofs: 11650, row: 392, col: 20}], _aether._userInfo, false);\n            return _aether.restoreAPIClone(_aether, tmp261);\n        };  _aether.logStatement([{ofs: 11437, row: 385, col: 18}, {ofs: 11657, row: 393, col: 5}], _aether._userInfo, false);\n        _aether.logStatementStart([{ofs: 11689, row: 395, col: 21}, {ofs: 11732, row: 397, col: 5}]); tmp250 = function (base) {\n            var tmp262; base = _aether.createAPIClone(_aether, base); for(var __argIndexer = 0; __argIndexer < arguments.length; ++__argIndexer) arguments[__argIndexer] = _aether.createAPIClone(_aether, arguments[__argIndexer]);\n            _aether.logStatementStart([{ofs: 11721, row: 396, col: 15}, {ofs: 11725, row: 396, col: 19}]); tmp262 = null;  _aether.logStatement([{ofs: 11721, row: 396, col: 15}, {ofs: 11725, row: 396, col: 19}], _aether._userInfo, false);\n            return _aether.restoreAPIClone(_aether, tmp262);\n        };  _aether.logStatement([{ofs: 11689, row: 395, col: 21}, {ofs: 11732, row: 397, col: 5}], _aether._userInfo, false);\n        _aether.logStatementStart([{ofs: 11368, row: 382, col: 0}, {ofs: 11735, row: 398, col: 2}]); stockpileState = {\n            name: tmp248,\n            wantsControl: tmp249,\n            selectBuildType: tmp250\n        };  _aether.logStatement([{ofs: 11368, row: 382, col: 0}, {ofs: 11735, row: 398, col: 2}], _aether._userInfo, false);\n        _aether.logStatementStart([{ofs: 12745, row: 431, col: 10}, {ofs: 12753, row: 431, col: 18}]); tmp263 = 'attack';  _aether.logStatement([{ofs: 12745, row: 431, col: 10}, {ofs: 12753, row: 431, col: 18}], _aether._userInfo, false);\n        _aether.logStatementStart([{ofs: 12778, row: 433, col: 18}, {ofs: 13301, row: 447, col: 5}]); tmp264 = function (base) {\n            var threshold, tmp266, tmp267, tmp268, tmp269, tmp270, tmp271, tmp272, tmp273, tmp274, tmp275, tmp276, tmp277, tmp278, tmp279, tmp280, tmp281, tmp282, tmp283, tmp284, tmp285, tmp286, tmp287, tmp288, tmp289; base = _aether.createAPIClone(_aether, base); for(var __argIndexer = 0; __argIndexer < arguments.length; ++__argIndexer) arguments[__argIndexer] = _aether.createAPIClone(_aether, arguments[__argIndexer]);\n            tmp269 = base;\n            tmp270 = 'now';\n            _aether.logStatementStart([{ofs: 12863, row: 435, col: 12}, {ofs: 12873, row: 435, col: 22}]); tmp267 = _aether.createAPIClone(_aether, tmp269[tmp270]());  _aether.logStatement([{ofs: 12863, row: 435, col: 12}, {ofs: 12873, row: 435, col: 22}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 12877, row: 435, col: 26}, {ofs: 12880, row: 435, col: 29}]); tmp268 = 140;  _aether.logStatement([{ofs: 12877, row: 435, col: 26}, {ofs: 12880, row: 435, col: 29}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 12863, row: 435, col: 12}, {ofs: 12880, row: 435, col: 29}]); tmp266 = tmp267 >= tmp268;  _aether.logStatement([{ofs: 12863, row: 435, col: 12}, {ofs: 12880, row: 435, col: 29}], _aether._userInfo, false);\n            if (tmp266) {\n                _aether.logStatementStart([{ofs: 12903, row: 436, col: 19}, {ofs: 12907, row: 436, col: 23}]); tmp271 = true;  _aether.logStatement([{ofs: 12903, row: 436, col: 19}, {ofs: 12907, row: 436, col: 23}], _aether._userInfo, false);\n                return _aether.restoreAPIClone(_aether, tmp271);\n            } else {\n                ;\n            }\n            tmp274 = base;\n            tmp275 = 'currentState';\n            _aether.logStatementStart([{ofs: 13073, row: 441, col: 25}, {ofs: 13090, row: 441, col: 42}]); tmp273 = tmp274[tmp275];  _aether.logStatement([{ofs: 13073, row: 441, col: 25}, {ofs: 13090, row: 441, col: 42}], _aether._userInfo, false);\n            if (tmp273) {\n                tmp280 = base;\n                tmp281 = 'currentState';\n                _aether.logStatementStart([{ofs: 13094, row: 441, col: 46}, {ofs: 13111, row: 441, col: 63}]); tmp278 = tmp280[tmp281];  _aether.logStatement([{ofs: 13094, row: 441, col: 46}, {ofs: 13111, row: 441, col: 63}], _aether._userInfo, false);\n                tmp279 = 'name';\n                _aether.logStatementStart([{ofs: 13094, row: 441, col: 46}, {ofs: 13116, row: 441, col: 68}]); tmp276 = tmp278[tmp279];  _aether.logStatement([{ofs: 13094, row: 441, col: 46}, {ofs: 13116, row: 441, col: 68}], _aether._userInfo, false);\n                _aether.logStatementStart([{ofs: 13121, row: 441, col: 73}, {ofs: 13129, row: 441, col: 81}]); tmp277 = 'attack';  _aether.logStatement([{ofs: 13121, row: 441, col: 73}, {ofs: 13129, row: 441, col: 81}], _aether._userInfo, false);\n                _aether.logStatementStart([{ofs: 13094, row: 441, col: 46}, {ofs: 13129, row: 441, col: 81}]); tmp272 = tmp276 === tmp277;  _aether.logStatement([{ofs: 13094, row: 441, col: 46}, {ofs: 13129, row: 441, col: 81}], _aether._userInfo, false);\n            } else {\n                _aether.logStatementStart([{ofs: 13073, row: 441, col: 25}, {ofs: 13129, row: 441, col: 81}]); tmp272 = tmp273;  _aether.logStatement([{ofs: 13073, row: 441, col: 25}, {ofs: 13129, row: 441, col: 81}], _aether._userInfo, false);\n            }\n            if (tmp272) {\n                _aether.logStatementStart([{ofs: 13133, row: 441, col: 85}, {ofs: 13134, row: 441, col: 86}]); threshold = 0;  _aether.logStatement([{ofs: 13133, row: 441, col: 85}, {ofs: 13134, row: 441, col: 86}], _aether._userInfo, false);\n            } else {\n                _aether.logStatementStart([{ofs: 13137, row: 441, col: 89}, {ofs: 13139, row: 441, col: 91}]); threshold = 20;  _aether.logStatement([{ofs: 13137, row: 441, col: 89}, {ofs: 13139, row: 441, col: 91}], _aether._userInfo, false);\n            }\n            tmp283 = enemyStrengthForecast;\n            if (tmp283) {\n                tmp286 = ourStrength;\n                tmp287 = enemyStrengthForecast;\n                _aether.logStatementStart([{ofs: 13178, row: 442, col: 37}, {ofs: 13213, row: 442, col: 72}]); tmp284 = tmp286 - tmp287;  _aether.logStatement([{ofs: 13178, row: 442, col: 37}, {ofs: 13213, row: 442, col: 72}], _aether._userInfo, false);\n                tmp285 = threshold;\n                _aether.logStatementStart([{ofs: 13178, row: 442, col: 37}, {ofs: 13226, row: 442, col: 85}]); tmp282 = tmp284 >= tmp285;  _aether.logStatement([{ofs: 13178, row: 442, col: 37}, {ofs: 13226, row: 442, col: 85}], _aether._userInfo, false);\n            } else {\n                _aether.logStatementStart([{ofs: 13153, row: 442, col: 12}, {ofs: 13226, row: 442, col: 85}]); tmp282 = tmp283;  _aether.logStatement([{ofs: 13153, row: 442, col: 12}, {ofs: 13226, row: 442, col: 85}], _aether._userInfo, false);\n            }\n            if (tmp282) {\n                _aether.logStatementStart([{ofs: 13249, row: 443, col: 19}, {ofs: 13253, row: 443, col: 23}]); tmp288 = true;  _aether.logStatement([{ofs: 13249, row: 443, col: 19}, {ofs: 13253, row: 443, col: 23}], _aether._userInfo, false);\n                return _aether.restoreAPIClone(_aether, tmp288);\n            } else {\n                ;\n            }\n            _aether.logStatementStart([{ofs: 13289, row: 446, col: 15}, {ofs: 13294, row: 446, col: 20}]); tmp289 = false;  _aether.logStatement([{ofs: 13289, row: 446, col: 15}, {ofs: 13294, row: 446, col: 20}], _aether._userInfo, false);\n            return _aether.restoreAPIClone(_aether, tmp289);\n        };  _aether.logStatement([{ofs: 12778, row: 433, col: 18}, {ofs: 13301, row: 447, col: 5}], _aether._userInfo, false);\n        tmp265 = decideMilitaryToBuild;\n        _aether.logStatementStart([{ofs: 12715, row: 430, col: 0}, {ofs: 13357, row: 450, col: 2}]); attackState = {\n            name: tmp263,\n            wantsControl: tmp264,\n            selectBuildType: tmp265\n        };  _aether.logStatement([{ofs: 12715, row: 430, col: 0}, {ofs: 13357, row: 450, col: 2}], _aether._userInfo, false);\n        _aether.logStatementStart([{ofs: 13389, row: 453, col: 10}, {ofs: 13397, row: 453, col: 18}]); tmp290 = 'defend';  _aether.logStatement([{ofs: 13389, row: 453, col: 10}, {ofs: 13397, row: 453, col: 18}], _aether._userInfo, false);\n        _aether.logStatementStart([{ofs: 13422, row: 455, col: 18}, {ofs: 13872, row: 466, col: 5}]); tmp291 = function (base) {\n            var nearEnemies, militaryRatio, tmp293, tmp294, tmp295, tmp302, tmp303, tmp304, tmp305, tmp306, tmp307, tmp308, tmp309, tmp310, tmp311, tmp312, tmp313, tmp314, tmp315, tmp316, tmp317; base = _aether.createAPIClone(_aether, base); for(var __argIndexer = 0; __argIndexer < arguments.length; ++__argIndexer) arguments[__argIndexer] = _aether.createAPIClone(_aether, arguments[__argIndexer]);\n            tmp293 = militaryEnemies;\n            tmp294 = 'filter';\n            _aether.logStatementStart([{ofs: 13488, row: 456, col: 49}, {ofs: 13533, row: 456, col: 94}]); tmp295 = function (x) {\n                var tmp296, tmp297, tmp298, tmp299, tmp300, tmp301; x = _aether.createAPIClone(_aether, x); for(var __argIndexer = 0; __argIndexer < arguments.length; ++__argIndexer) arguments[__argIndexer] = _aether.createAPIClone(_aether, arguments[__argIndexer]);\n                tmp299 = base;\n                tmp300 = 'distance';\n                tmp301 = x;\n                _aether.logStatementStart([{ofs: 13509, row: 456, col: 70}, {ofs: 13525, row: 456, col: 86}]); tmp297 = _aether.createAPIClone(_aether, tmp299[tmp300](_aether.restoreAPIClone(_aether, tmp301)));  _aether.logStatement([{ofs: 13509, row: 456, col: 70}, {ofs: 13525, row: 456, col: 86}], _aether._userInfo, false);\n                _aether.logStatementStart([{ofs: 13528, row: 456, col: 89}, {ofs: 13530, row: 456, col: 91}]); tmp298 = 55;  _aether.logStatement([{ofs: 13528, row: 456, col: 89}, {ofs: 13530, row: 456, col: 91}], _aether._userInfo, false);\n                _aether.logStatementStart([{ofs: 13509, row: 456, col: 70}, {ofs: 13530, row: 456, col: 91}]); tmp296 = tmp297 < tmp298;  _aether.logStatement([{ofs: 13509, row: 456, col: 70}, {ofs: 13530, row: 456, col: 91}], _aether._userInfo, false);\n                return _aether.restoreAPIClone(_aether, tmp296);\n            };  _aether.logStatement([{ofs: 13488, row: 456, col: 49}, {ofs: 13533, row: 456, col: 94}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 13447, row: 456, col: 8}, {ofs: 13535, row: 456, col: 96}]); nearEnemies = _aether.createAPIClone(_aether, tmp293[tmp294](_aether.restoreAPIClone(_aether, tmp295)));  _aether.logStatement([{ofs: 13447, row: 456, col: 8}, {ofs: 13535, row: 456, col: 96}], _aether._userInfo, false);\n            tmp302 = ourMilitaryStrength;\n            tmp304 = valuateFighters;\n            tmp305 = nearEnemies;\n            _aether.logStatementStart([{ofs: 13595, row: 458, col: 50}, {ofs: 13623, row: 458, col: 78}]); tmp303 = _aether.createAPIClone(_aether, tmp304(_aether.restoreAPIClone(_aether, tmp305)));  _aether.logStatement([{ofs: 13595, row: 458, col: 50}, {ofs: 13623, row: 458, col: 78}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 13553, row: 458, col: 8}, {ofs: 13624, row: 458, col: 79}]); militaryRatio = tmp302 / tmp303;  _aether.logStatement([{ofs: 13553, row: 458, col: 8}, {ofs: 13624, row: 458, col: 79}], _aether._userInfo, false);\n            tmp308 = nearestEnemy;\n            if (tmp308) {\n                tmp311 = base;\n                tmp312 = 'distance';\n                tmp313 = nearestEnemy;\n                _aether.logStatementStart([{ofs: 13741, row: 461, col: 28}, {ofs: 13768, row: 461, col: 55}]); tmp309 = _aether.createAPIClone(_aether, tmp311[tmp312](_aether.restoreAPIClone(_aether, tmp313)));  _aether.logStatement([{ofs: 13741, row: 461, col: 28}, {ofs: 13768, row: 461, col: 55}], _aether._userInfo, false);\n                _aether.logStatementStart([{ofs: 13772, row: 461, col: 59}, {ofs: 13774, row: 461, col: 61}]); tmp310 = 40;  _aether.logStatement([{ofs: 13772, row: 461, col: 59}, {ofs: 13774, row: 461, col: 61}], _aether._userInfo, false);\n                _aether.logStatementStart([{ofs: 13741, row: 461, col: 28}, {ofs: 13774, row: 461, col: 61}]); tmp307 = tmp309 <= tmp310;  _aether.logStatement([{ofs: 13741, row: 461, col: 28}, {ofs: 13774, row: 461, col: 61}], _aether._userInfo, false);\n            } else {\n                _aether.logStatementStart([{ofs: 13725, row: 461, col: 12}, {ofs: 13774, row: 461, col: 61}]); tmp307 = tmp308;  _aether.logStatement([{ofs: 13725, row: 461, col: 12}, {ofs: 13774, row: 461, col: 61}], _aether._userInfo, false);\n            }\n            if (tmp307) {\n                tmp314 = militaryRatio;\n                _aether.logStatementStart([{ofs: 13794, row: 461, col: 81}, {ofs: 13797, row: 461, col: 84}]); tmp315 = 1.2;  _aether.logStatement([{ofs: 13794, row: 461, col: 81}, {ofs: 13797, row: 461, col: 84}], _aether._userInfo, false);\n                _aether.logStatementStart([{ofs: 13778, row: 461, col: 65}, {ofs: 13797, row: 461, col: 84}]); tmp306 = tmp314 < tmp315;  _aether.logStatement([{ofs: 13778, row: 461, col: 65}, {ofs: 13797, row: 461, col: 84}], _aether._userInfo, false);\n            } else {\n                _aether.logStatementStart([{ofs: 13725, row: 461, col: 12}, {ofs: 13797, row: 461, col: 84}]); tmp306 = tmp307;  _aether.logStatement([{ofs: 13725, row: 461, col: 12}, {ofs: 13797, row: 461, col: 84}], _aether._userInfo, false);\n            }\n            if (tmp306) {\n                _aether.logStatementStart([{ofs: 13820, row: 462, col: 19}, {ofs: 13824, row: 462, col: 23}]); tmp316 = true;  _aether.logStatement([{ofs: 13820, row: 462, col: 19}, {ofs: 13824, row: 462, col: 23}], _aether._userInfo, false);\n                return _aether.restoreAPIClone(_aether, tmp316);\n            } else {\n                ;\n            }\n            _aether.logStatementStart([{ofs: 13860, row: 465, col: 15}, {ofs: 13865, row: 465, col: 20}]); tmp317 = false;  _aether.logStatement([{ofs: 13860, row: 465, col: 15}, {ofs: 13865, row: 465, col: 20}], _aether._userInfo, false);\n            return _aether.restoreAPIClone(_aether, tmp317);\n        };  _aether.logStatement([{ofs: 13422, row: 455, col: 18}, {ofs: 13872, row: 466, col: 5}], _aether._userInfo, false);\n        tmp292 = decideMilitaryToBuild;\n        _aether.logStatementStart([{ofs: 13359, row: 452, col: 0}, {ofs: 13924, row: 469, col: 2}]); defendState = {\n            name: tmp290,\n            wantsControl: tmp291,\n            selectBuildType: tmp292\n        };  _aether.logStatement([{ofs: 13359, row: 452, col: 0}, {ofs: 13924, row: 469, col: 2}], _aether._userInfo, false);\n        tmp318 = attackState;\n        tmp319 = defendState;\n        tmp320 = stockpileState;\n        tmp321 = collectState;\n        tmp322 = pokeState;\n        tmp323 = doNothingState;\n        _aether.logStatementStart([{ofs: 14008, row: 473, col: 0}, {ofs: 14131, row: 480, col: 2}]); states = [\n            tmp318,\n            tmp319,\n            tmp320,\n            tmp321,\n            tmp322,\n            tmp323\n        ];  _aether.logStatement([{ofs: 14008, row: 473, col: 0}, {ofs: 14131, row: 480, col: 2}], _aether._userInfo, false);\n        tmp324 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n        tmp325 = 'updateState';\n        _aether.logStatementStart([{ofs: 14133, row: 482, col: 0}, {ofs: 14362, row: 490, col: 2}]); tmp326 = function () {\n            var i, sLen, st, tmp327, tmp328, tmp329, tmp330, tmp331, tmp332, tmp333, tmp334, tmp335, tmp338, tmp339, tmp340, tmp341, tmp342, tmp343, tmp344, tmp345, tmp346;  for(var __argIndexer = 0; __argIndexer < arguments.length; ++__argIndexer) arguments[__argIndexer] = _aether.createAPIClone(_aether, arguments[__argIndexer]);\n            _aether.logStatementStart([{ofs: 14174, row: 483, col: 9}, {ofs: 14205, row: 483, col: 40}]); i = 0;  _aether.logStatement([{ofs: 14174, row: 483, col: 9}, {ofs: 14205, row: 483, col: 40}], _aether._userInfo, false);\n            tmp327 = states;\n            tmp328 = 'length';\n            _aether.logStatementStart([{ofs: 14174, row: 483, col: 9}, {ofs: 14205, row: 483, col: 40}]); sLen = tmp327[tmp328];  _aether.logStatement([{ofs: 14174, row: 483, col: 9}, {ofs: 14205, row: 483, col: 40}], _aether._userInfo, false);\n            tmp330 = i;\n            tmp331 = sLen;\n            _aether.logStatementStart([{ofs: 14207, row: 483, col: 42}, {ofs: 14215, row: 483, col: 50}]); tmp329 = tmp330 < tmp331;  _aether.logStatement([{ofs: 14207, row: 483, col: 42}, {ofs: 14215, row: 483, col: 50}], _aether._userInfo, false);\n            tmp336: {\n                while (tmp329) {\n                    tmp337: {\n                        tmp338 = states;\n                        tmp339 = i;\n                        _aether.logStatementStart([{ofs: 14232, row: 484, col: 8}, {ofs: 14251, row: 484, col: 27}]); st = tmp338[tmp339];  _aether.logStatement([{ofs: 14232, row: 484, col: 8}, {ofs: 14251, row: 484, col: 27}], _aether._userInfo, false);\n                        tmp341 = st;\n                        tmp342 = 'wantsControl';\n                        tmp343 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n                        _aether.logStatementStart([{ofs: 14264, row: 485, col: 12}, {ofs: 14285, row: 485, col: 33}]); tmp340 = _aether.createAPIClone(_aether, tmp341[tmp342](_aether.restoreAPIClone(_aether, tmp343)));  _aether.logStatement([{ofs: 14264, row: 485, col: 12}, {ofs: 14285, row: 485, col: 33}], _aether._userInfo, false);\n                        if (tmp340) {\n                            tmp344 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n                            tmp345 = 'currentState';\n                            tmp346 = st;\n                            _aether.logStatementStart([{ofs: 14301, row: 486, col: 12}, {ofs: 14323, row: 486, col: 34}]); tmp344[tmp345] = tmp346;  _aether.logStatement([{ofs: 14301, row: 486, col: 12}, {ofs: 14323, row: 486, col: 34}], _aether._userInfo, false);\n                            break tmp336;\n                        } else {\n                            ;\n                        }\n                    }\n                    tmp334 = i;\n                    tmp335 = 1;\n                    i = tmp334 + tmp335;\n                    tmp332 = i;\n                    tmp333 = sLen;\n                    _aether.logStatementStart([{ofs: 14207, row: 483, col: 42}, {ofs: 14215, row: 483, col: 50}]); tmp329 = tmp332 < tmp333;  _aether.logStatement([{ofs: 14207, row: 483, col: 42}, {ofs: 14215, row: 483, col: 50}], _aether._userInfo, false);\n                }\n            }\n            return;\n        };  _aether.logStatement([{ofs: 14133, row: 482, col: 0}, {ofs: 14362, row: 490, col: 2}], _aether._userInfo, false);\n        _aether.logStatementStart([{ofs: 14133, row: 482, col: 0}, {ofs: 14361, row: 490, col: 1}]); tmp324[tmp325] = tmp326;  _aether.logStatement([{ofs: 14133, row: 482, col: 0}, {ofs: 14361, row: 490, col: 1}], _aether._userInfo, false);\n        tmp347 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n        tmp348 = 'updateState';\n        _aether.logStatementStart([{ofs: 14446, row: 494, col: 0}, {ofs: 14464, row: 494, col: 18}]); tmp349 = _aether.createAPIClone(_aether, tmp347[tmp348]());  _aether.logStatement([{ofs: 14446, row: 494, col: 0}, {ofs: 14464, row: 494, col: 18}], _aether._userInfo, false);\n        tmp352 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n        tmp353 = 'currentState';\n        _aether.logStatementStart([{ofs: 14478, row: 496, col: 11}, {ofs: 14495, row: 496, col: 28}]); tmp350 = tmp352[tmp353];  _aether.logStatement([{ofs: 14478, row: 496, col: 11}, {ofs: 14495, row: 496, col: 28}], _aether._userInfo, false);\n        tmp351 = 'selectBuildType';\n        tmp354 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n        _aether.logStatementStart([{ofs: 14467, row: 496, col: 0}, {ofs: 14518, row: 496, col: 51}]); type = _aether.createAPIClone(_aether, tmp350[tmp351](_aether.restoreAPIClone(_aether, tmp354)));  _aether.logStatement([{ofs: 14467, row: 496, col: 0}, {ofs: 14518, row: 496, col: 51}], _aether._userInfo, false);\n        tmp356 = type;\n        if (tmp356) {\n            tmp359 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n            tmp360 = 'gold';\n            _aether.logStatementStart([{ofs: 14532, row: 498, col: 12}, {ofs: 14541, row: 498, col: 21}]); tmp357 = tmp359[tmp360];  _aether.logStatement([{ofs: 14532, row: 498, col: 12}, {ofs: 14541, row: 498, col: 21}], _aether._userInfo, false);\n            tmp365 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n            tmp366 = 'buildables';\n            _aether.logStatementStart([{ofs: 14545, row: 498, col: 25}, {ofs: 14560, row: 498, col: 40}]); tmp363 = tmp365[tmp366];  _aether.logStatement([{ofs: 14545, row: 498, col: 25}, {ofs: 14560, row: 498, col: 40}], _aether._userInfo, false);\n            tmp364 = type;\n            _aether.logStatementStart([{ofs: 14545, row: 498, col: 25}, {ofs: 14566, row: 498, col: 46}]); tmp361 = tmp363[tmp364];  _aether.logStatement([{ofs: 14545, row: 498, col: 25}, {ofs: 14566, row: 498, col: 46}], _aether._userInfo, false);\n            tmp362 = 'goldCost';\n            _aether.logStatementStart([{ofs: 14545, row: 498, col: 25}, {ofs: 14575, row: 498, col: 55}]); tmp358 = tmp361[tmp362];  _aether.logStatement([{ofs: 14545, row: 498, col: 25}, {ofs: 14575, row: 498, col: 55}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 14532, row: 498, col: 12}, {ofs: 14575, row: 498, col: 55}]); tmp355 = tmp357 >= tmp358;  _aether.logStatement([{ofs: 14532, row: 498, col: 12}, {ofs: 14575, row: 498, col: 55}], _aether._userInfo, false);\n        } else {\n            _aether.logStatementStart([{ofs: 14524, row: 498, col: 4}, {ofs: 14575, row: 498, col: 55}]); tmp355 = tmp356;  _aether.logStatement([{ofs: 14524, row: 498, col: 4}, {ofs: 14575, row: 498, col: 55}], _aether._userInfo, false);\n        }\n        if (tmp355) {\n            tmp367 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n            tmp368 = 'build';\n            tmp369 = type;\n            _aether.logStatementStart([{ofs: 14583, row: 499, col: 4}, {ofs: 14599, row: 499, col: 20}]); tmp370 = _aether.createAPIClone(_aether, tmp367[tmp368](_aether.restoreAPIClone(_aether, tmp369)));  _aether.logStatement([{ofs: 14583, row: 499, col: 4}, {ofs: 14599, row: 499, col: 20}], _aether._userInfo, false);\n        } else {\n            ;\n        }\n        _aether.logCallEnd(); return;\n    };\n    tmp0 = 'chooseAction';\n    __global[tmp0] = tmp1;\n}(this));"
         }
       },
-      "totalScore": 36.7927193835314,
+      "teamSpells": {
+        "humans": [
+          "human-base/chooseAction"
+        ],
+        "ogres": [
+          "ogre-base/chooseAction"
+        ],
+        "common": [
+          "well/chooseAction"
+        ]
+      },
+      "totalScore": 36.77589873873074,
       "submitted": true,
       "submittedCodeLanguage": "javascript",
       "playtime": 12893,
@@ -422,6 +508,10 @@ responses =
     },
     {
       "_id": "5356fc2e1bfa9bba14b5e039",
+      "level": {
+        "original": "53558b5a9914f5a90d7ccddb",
+        "majorVersion": 0
+      },
       "team": "humans",
       "levelID": "greed",
       "levelName": "Greed",
@@ -433,65 +523,108 @@ responses =
           "chooseAction": "if(!this.inventorySystem) this.inventorySystem = this.world.getSystem('Inventory');\n// Cap at 120 coins for rendering performance reasons.\n// As many as ~420 by stalemate with default code, but one greedy collector -> ~70 tops.\nif(this.inventorySystem.collectables.length < 120) {\n    var x = Math.random();\n    var type = 'silver';\n    if (x < 0.05) type = 'gem';\n    else if (x < 0.15) type = 'gold';\n    else if (x < 0.35) type = 'copper';\n    this.build(type);\n}\n\nif(!this.causeFall) this.causeFall = function causeFall(target) {\n    target.addEffect({name: 'fall', duration: 1.5, reverts: false, factor: 0.1, targetProperty: 'scaleFactor'}, this);\n    target.maxAcceleration = 0;\n    target.addCurrentEvent('fall');\n    target.fellAt = this.now();\n};\n\nfor (var i = 0; i < this.inventorySystem.collectors.length; ++i) {\n    var thang = this.inventorySystem.collectors[i];\n    if ((thang.type == 'peasant' || thang.type == 'peon') &&\n        (thang.pos.x < -3 || thang.pos.x > 88 || thang.pos.y < -5 || thang.pos.y > 80)) {\n        if (thang.maxAcceleration)\n            this.causeFall(thang);\n        else if (thang.fellAt && thang.fellAt + 1.25 < this.now()) {\n            thang.setExists(false);\n            thang.fellAt = null;\n        }\n    }\n}"
         }
       },
-      "totalScore": 31.55513937890014,
+      "teamSpells": {
+        "humans": [
+          "human-base/chooseAction"
+        ],
+        "ogres": [
+          "ogre-base/chooseAction"
+        ],
+        "common": [
+          "well/chooseAction"
+        ]
+      },
+      "totalScore": 31.538998178536794,
       "submitted": true,
       "submittedCodeLanguage": "javascript",
-      "playtime": 14758,
+      "playtime": 15648,
       "codeLanguage": "javascript"
     },
     {
       "_id": "52fd5bf7e3c53130231726e1",
+      "level": {
+        "original": "52d97ecd32362bc86e004e87",
+        "majorVersion": 0
+      },
       "team": "ogres",
       "levelID": "brawlwood",
       "levelName": "Brawlwood",
       "submitted": true,
-      "totalScore": 54.324748499022,
+      "totalScore": 53.73511062513137,
+      "teamSpells": {
+        "humans": [
+          "programmable-artillery/chooseAction",
+          "programmable-artillery/hear",
+          "programmable-soldier/chooseAction",
+          "programmable-soldier/hear",
+          "s-arrow-tower/chooseAction",
+          "programmable-archer/chooseAction",
+          "programmable-archer/hear",
+          "human-base/chooseAction",
+          "human-base/hear"
+        ],
+        "ogres": [
+          "programmable-shaman/chooseAction",
+          "programmable-shaman/hear",
+          "n-beam-tower/chooseAction",
+          "programmable-thrower/chooseAction",
+          "programmable-thrower/hear",
+          "programmable-munchkin/chooseAction",
+          "programmable-munchkin/hear",
+          "ogre-base/chooseAction",
+          "ogre-base/hear"
+        ]
+      },
       "code": {
-        "human-base": {
-          "hear": "...",
-          "chooseAction": "..."
+        "ogre-base": {
+          "hear": "// When the base hears a say() message, this hear() method will be called.\nif(speaker.team !== this.team) return;\n\n// You can add code to respond to the message here.",
+          "chooseAction": "// This is the code for your base. Decide which unit to build each frame.\n// Units you build will go into the this.built array.\n// If you don't have enough gold, this.build() won't build anything.\n// You start with 100 gold and receive 2 gold per second.\n// Kill enemies, especially towers and brawlers, to earn more gold.\n// Destroy the enemy base within 90 seconds!\n// Check out the Guide just up and to the left for more info.\n\nvar type = 'munchkin';\nif(this.built.length % 10 === 3)\n    type = 'shaman';\nelse if(this.built.length % 6 === 1)\n    type = 'thrower';\n\n//this.say('Unit #' + this.built.length + ' will be a ' + type);\nthis.build(type);\n"
         },
-        "programmable-archer": {
-          "hear": "...",
-          "chooseAction": "..."
+        "programmable-munchkin": {
+          "hear": "// When the munchkin hears a say() message, this hear() method will be called.\nif(speaker.team !== this.team) return;\n\n// You can add code to respond to the message here.",
+          "chooseAction": "// This code is shared across all your Munchkins.\n// You can use this.buildIndex to have Munchkins do different things.\n// Munchkins are weak but cheap, fast melee units.\n\nthis.getEnemyMissiles();\nvar items;\nif(this.buildIndex === 0) {\n    items = this.getItems();\n    if(items.length) {\n        this.move(items[0].pos);\n        this.say(\"MINE\", {mission: \"coins\"});\n        return;\n    }\n}\nif(this.buildIndex === 2) {\n    items = this.getItems();\n    if(items.length) {\n        this.move(items[items.length - 1].pos);\n        this.say(\"MINE\", {mission: \"coins\"});\n        return;\n    }\n}\nvar enemies = this.getEnemies();\nvar nearestJuicyTarget = null;\nvar nearestJuicyTargetDistance = 9001;\nvar enemy;\nfor(var i = 0; i < enemies.length; ++i) {\n    enemy = enemies[i];\n    var d = this.distance(enemy);\n    if(enemy.type == 'soldier' && enemy.health > 15) continue;\n    if(enemy.type == 'burl' && enemy.health > 30) continue;\n    if(enemy.type == 'base' && enemy.health == enemy.maxHealth) continue;\n    if(d < nearestJuicyTargetDistance) {\n        nearestJuicyTarget = enemy;\n        nearestJuicyTargetDistance = d;\n    }\n}\nif(nearestJuicyTargetDistance < 15) {\n    this.attack(nearestJuicyTarget);\n    return;\n}\nenemy = this.getNearestEnemy();\nif (enemy && enemy.type !== 'burl') {\n    this.attack(enemy);\n}\nelse {\n    if(this.pos.y > 50 && this.pos.x > 50 && this.getFriends().length < 10) {\n        if(this.buildIndex % 2)\n            this.move({x: 53, y: 75});\n        else\n            this.move({x: 75, y: 53});\n        return;\n    }\n    this.move({x: 10, y: 10});\n}"
         },
-        "s-arrow-tower": {
-          "chooseAction": "..."
-        },
-        "programmable-soldier": {
-          "hear": "...",
-          "chooseAction": "..."
-        },
-        "programmable-artillery": {
-          "hear": "...",
-          "chooseAction": "..."
-        },
-        "programmable-shaman": {
-          "chooseAction": "if(this.shouldShrink && this.shouldShrink.length) {\n    this.castShrink(this.shouldShrink.pop());\n    return;\n}\n\nvar enemy;\nvar enemies = this.getEnemies();\nfor (var i = 0; i < enemies.length; ++i) {\n    enemy = enemies[i];\n    if(enemy.type === 'arrow-tower' && this.distance(enemy) < 42 && this.canCast('slow', enemy)) {\n        this.castSlow(enemy);\n        return;\n    }\n    else if((enemy.type === 'arrow-tower' || enemy.type === 'base') && enemy.health < enemy.maxHealth && this.canCast('shrink', enemy)) {\n        this.castShrink(enemy);\n        return;\n    }\n}\nfor (i = 0; i < enemies.length; ++i) {\n    enemy = enemies[i];\n    if (this.distance(enemy) > 30) continue;\n    if (this.canCast('shrink', enemy) && enemy.health < enemy.maxHealth && enemy.type != 'archer' && enemy.type != 'burl') {\n        this.say(\"Shrink, vile \" + enemy.type + \" \" + enemy.id);\n        this.castShrink(enemy);\n        return;\n    }\n    if (this.canCast('slow', enemy) && enemy.type != 'soldier' && enemy.type != 'burl') {\n        this.say(\"Slooooow, vile \" + enemy.type + \" \" + enemy.id);\n        this.castSlow(enemy);\n        return;\n    }\n}\n\nenemy = this.getNearestEnemy();\nif (enemy && (enemy.type !== 'burl' || (enemy.pos.x > 38 && enemy.pos.y > 38)))\n    this.attack(enemy);\nelse {\n    if(this.pos.y > 50 && this.pos.x > 50 && this.getFriends().length < 10) {\n        if(this.buildIndex % 2)\n            this.move({x: 53, y: 75});\n        else\n            this.move({x: 75, y: 53});\n        return;\n    }\n    this.move({x: 10, y: 10});\n}\n",
-          "hear": "// When the shaman hears a say() message, this hear() method will be called.\nif(speaker.team !== this.team) return;\n\nif(message == \"MINE\" && this.canCast('shrink', speaker) && this.now() < 3) {\n    if(!this.shouldShrink)\n        this.shouldShrink = [];\n    this.shouldShrink.push(speaker);\n}\n\n\n// You can add code to respond to the message here."
+        "programmable-thrower": {
+          "hear": "// When the thrower hears a say() message, this hear() method will be called.\nif(speaker.team !== this.team) return;\n\n// You can add code to respond to the message here.",
+          "chooseAction": "// This code is shared across all your Throwers.\n// You can use this.buildIndex to have Throwers do different things.\n// Throwers are vulnerable but deadly ranged units.\n\n\nvar enemy = this.getNearestEnemy();\nif (enemy && (enemy.type !== 'burl' || (enemy.pos.x > 38 && enemy.pos.y > 38))) {\n    this.attack(enemy);\n}\nelse {\n    if(this.pos.y > 50 && this.pos.x > 50 && this.getFriends().length < 10) {\n        if(this.buildIndex % 2)\n            this.move({x: 53, y: 75});\n        else\n            this.move({x: 75, y: 53});\n        return;\n    }\n\n    this.move({x: 10, y: 10});\n}\n\n"
         },
         "n-beam-tower": {
           "chooseAction": "// This code is shared by both your Beam Towers.\n// Don't let your towers die lest the humans claim 250 gold!\n// You probably don't need to change this basic strategy.\n\nvar enemy = this.getNearestEnemy();\nif (enemy && this.distance(enemy) < this.attackRange) {\n    this.say(\"Die, \" + enemy.id + \"!\");\n    this.attack(enemy);\n}"
         },
-        "programmable-thrower": {
-          "chooseAction": "// This code is shared across all your Throwers.\n// You can use this.buildIndex to have Throwers do different things.\n// Throwers are vulnerable but deadly ranged units.\n\n\nvar enemy = this.getNearestEnemy();\nif (enemy && (enemy.type !== 'burl' || (enemy.pos.x > 38 && enemy.pos.y > 38))) {\n    this.attack(enemy);\n}\nelse {\n    if(this.pos.y > 50 && this.pos.x > 50 && this.getFriends().length < 10) {\n        if(this.buildIndex % 2)\n            this.move({x: 53, y: 75});\n        else\n            this.move({x: 75, y: 53});\n        return;\n    }\n\n    this.move({x: 10, y: 10});\n}\n\n",
-          "hear": "// When the thrower hears a say() message, this hear() method will be called.\nif(speaker.team !== this.team) return;\n\n// You can add code to respond to the message here."
+        "programmable-shaman": {
+          "hear": "// When the shaman hears a say() message, this hear() method will be called.\nif(speaker.team !== this.team) return;\n\nif(message == \"MINE\" && this.canCast('shrink', speaker) && this.now() < 3) {\n    if(!this.shouldShrink)\n        this.shouldShrink = [];\n    this.shouldShrink.push(speaker);\n}\n\n\n// You can add code to respond to the message here.",
+          "chooseAction": "if(this.shouldShrink && this.shouldShrink.length) {\n    this.castShrink(this.shouldShrink.pop());\n    return;\n}\n\nvar enemy;\nvar enemies = this.getEnemies();\nfor (var i = 0; i < enemies.length; ++i) {\n    enemy = enemies[i];\n    if(enemy.type === 'arrow-tower' && this.distance(enemy) < 42 && this.canCast('slow', enemy)) {\n        this.castSlow(enemy);\n        return;\n    }\n    else if((enemy.type === 'arrow-tower' || enemy.type === 'base') && enemy.health < enemy.maxHealth && this.canCast('shrink', enemy)) {\n        this.castShrink(enemy);\n        return;\n    }\n}\nfor (i = 0; i < enemies.length; ++i) {\n    enemy = enemies[i];\n    if (this.distance(enemy) > 30) continue;\n    if (this.canCast('shrink', enemy) && enemy.health < enemy.maxHealth && enemy.type != 'archer' && enemy.type != 'burl') {\n        this.say(\"Shrink, vile \" + enemy.type + \" \" + enemy.id);\n        this.castShrink(enemy);\n        return;\n    }\n    if (this.canCast('slow', enemy) && enemy.type != 'soldier' && enemy.type != 'burl') {\n        this.say(\"Slooooow, vile \" + enemy.type + \" \" + enemy.id);\n        this.castSlow(enemy);\n        return;\n    }\n}\n\nenemy = this.getNearestEnemy();\nif (enemy && (enemy.type !== 'burl' || (enemy.pos.x > 38 && enemy.pos.y > 38)))\n    this.attack(enemy);\nelse {\n    if(this.pos.y > 50 && this.pos.x > 50 && this.getFriends().length < 10) {\n        if(this.buildIndex % 2)\n            this.move({x: 53, y: 75});\n        else\n            this.move({x: 75, y: 53});\n        return;\n    }\n    this.move({x: 10, y: 10});\n}\n"
         },
-        "programmable-munchkin": {
-          "chooseAction": "// This code is shared across all your Munchkins.\n// You can use this.buildIndex to have Munchkins do different things.\n// Munchkins are weak but cheap, fast melee units.\n\nthis.getEnemyMissiles();\nvar items;\nif(this.buildIndex === 0) {\n    items = this.getItems();\n    if(items.length) {\n        this.move(items[0].pos);\n        this.say(\"MINE\", {mission: \"coins\"});\n        return;\n    }\n}\nif(this.buildIndex === 2) {\n    items = this.getItems();\n    if(items.length) {\n        this.move(items[items.length - 1].pos);\n        this.say(\"MINE\", {mission: \"coins\"});\n        return;\n    }\n}\nvar enemies = this.getEnemies();\nvar nearestJuicyTarget = null;\nvar nearestJuicyTargetDistance = 9001;\nvar enemy;\nfor(var i = 0; i < enemies.length; ++i) {\n    enemy = enemies[i];\n    var d = this.distance(enemy);\n    if(enemy.type == 'soldier' && enemy.health > 15) continue;\n    if(enemy.type == 'burl' && enemy.health > 30) continue;\n    if(enemy.type == 'base' && enemy.health == enemy.maxHealth) continue;\n    if(d < nearestJuicyTargetDistance) {\n        nearestJuicyTarget = enemy;\n        nearestJuicyTargetDistance = d;\n    }\n}\nif(nearestJuicyTargetDistance < 15) {\n    this.attack(nearestJuicyTarget);\n    return;\n}\nenemy = this.getNearestEnemy();\nif (enemy && enemy.type !== 'burl') {\n    this.attack(enemy);\n}\nelse {\n    if(this.pos.y > 50 && this.pos.x > 50 && this.getFriends().length < 10) {\n        if(this.buildIndex % 2)\n            this.move({x: 53, y: 75});\n        else\n            this.move({x: 75, y: 53});\n        return;\n    }\n    this.move({x: 10, y: 10});\n}",
-          "hear": "// When the munchkin hears a say() message, this hear() method will be called.\nif(speaker.team !== this.team) return;\n\n// You can add code to respond to the message here."
+        "programmable-artillery": {
+          "chooseAction": "var __interceptThis=(function(){var G=this;return function($this,sandbox){if($this==G){return sandbox;}return $this;};})();\nreturn (function (__global) {\n    var tmp0, tmp1;\n    tmp1 = function () {\n        'use strict'; _aether.logCallStart(_aether._userInfo); var tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8, tmp9, tmp10, tmp11, tmp12, tmp13, tmp14, tmp15, tmp16, tmp17, tmp18, tmp19, tmp20, tmp21;  for(var __argIndexer = 0; __argIndexer < arguments.length; ++__argIndexer) arguments[__argIndexer] = _aether.createAPIClone(_aether, arguments[__argIndexer]);\n        tmp5 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n        tmp6 = 'now';\n        _aether.logStatementStart([{ofs: 509, row: 11, col: 4}, {ofs: 519, row: 11, col: 14}]); tmp3 = _aether.createAPIClone(_aether, tmp5[tmp6]());  _aether.logStatement([{ofs: 509, row: 11, col: 4}, {ofs: 519, row: 11, col: 14}], _aether._userInfo, false);\n        _aether.logStatementStart([{ofs: 522, row: 11, col: 17}, {ofs: 523, row: 11, col: 18}]); tmp4 = 5;  _aether.logStatement([{ofs: 522, row: 11, col: 17}, {ofs: 523, row: 11, col: 18}], _aether._userInfo, false);\n        _aether.logStatementStart([{ofs: 509, row: 11, col: 4}, {ofs: 523, row: 11, col: 18}]); tmp2 = tmp3 < tmp4;  _aether.logStatement([{ofs: 509, row: 11, col: 4}, {ofs: 523, row: 11, col: 18}], _aether._userInfo, false);\n        if (tmp2) {\n            tmp7 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n            tmp8 = 'say';\n            _aether.logStatementStart([{ofs: 540, row: 12, col: 13}, {ofs: 563, row: 12, col: 36}]); tmp9 = '***BOOM SHAKALAKA!***';  _aether.logStatement([{ofs: 540, row: 12, col: 13}, {ofs: 563, row: 12, col: 36}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 531, row: 12, col: 4}, {ofs: 564, row: 12, col: 37}]); tmp10 = _aether.createAPIClone(_aether, tmp7[tmp8](_aether.restoreAPIClone(_aether, tmp9)));  _aether.logStatement([{ofs: 531, row: 12, col: 4}, {ofs: 564, row: 12, col: 37}], _aether._userInfo, false);\n            tmp11 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n            tmp12 = 'attackXY';\n            _aether.logStatementStart([{ofs: 584, row: 13, col: 18}, {ofs: 586, row: 13, col: 20}]); tmp13 = 40;  _aether.logStatement([{ofs: 584, row: 13, col: 18}, {ofs: 586, row: 13, col: 20}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 588, row: 13, col: 22}, {ofs: 590, row: 13, col: 24}]); tmp14 = 40;  _aether.logStatement([{ofs: 588, row: 13, col: 22}, {ofs: 590, row: 13, col: 24}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 570, row: 13, col: 4}, {ofs: 591, row: 13, col: 25}]); tmp15 = _aether.createAPIClone(_aether, tmp11[tmp12](_aether.restoreAPIClone(_aether, tmp13), _aether.restoreAPIClone(_aether, tmp14)));  _aether.logStatement([{ofs: 570, row: 13, col: 4}, {ofs: 591, row: 13, col: 25}], _aether._userInfo, false);\n        } else {\n            tmp16 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n            tmp17 = 'move';\n            _aether.logStatementStart([{ofs: 620, row: 15, col: 18}, {ofs: 622, row: 15, col: 20}]); tmp19 = 41;  _aether.logStatement([{ofs: 620, row: 15, col: 18}, {ofs: 622, row: 15, col: 20}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 627, row: 15, col: 25}, {ofs: 629, row: 15, col: 27}]); tmp20 = 17;  _aether.logStatement([{ofs: 627, row: 15, col: 25}, {ofs: 629, row: 15, col: 27}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 616, row: 15, col: 14}, {ofs: 630, row: 15, col: 28}]); tmp18 = {\n                x: tmp19,\n                y: tmp20\n            };  _aether.logStatement([{ofs: 616, row: 15, col: 14}, {ofs: 630, row: 15, col: 28}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 606, row: 15, col: 4}, {ofs: 631, row: 15, col: 29}]); tmp21 = _aether.createAPIClone(_aether, tmp16[tmp17](_aether.restoreAPIClone(_aether, tmp18)));  _aether.logStatement([{ofs: 606, row: 15, col: 4}, {ofs: 631, row: 15, col: 29}], _aether._userInfo, false);\n        }\n        _aether.logCallEnd(); return;\n    };\n    tmp0 = 'chooseAction';\n    __global[tmp0] = tmp1;\n}(this));",
+          "hear": "var __interceptThis=(function(){var G=this;return function($this,sandbox){if($this==G){return sandbox;}return $this;};})();\nreturn (function (__global) {\n    var tmp0, tmp1;\n    tmp1 = function (speaker, message, data) {\n        'use strict'; _aether.logCallStart(_aether._userInfo); var tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8; speaker = _aether.createAPIClone(_aether, speaker); message = _aether.createAPIClone(_aether, message); data = _aether.createAPIClone(_aether, data); for(var __argIndexer = 0; __argIndexer < arguments.length; ++__argIndexer) arguments[__argIndexer] = _aether.createAPIClone(_aether, arguments[__argIndexer]);\n        tmp5 = speaker;\n        tmp6 = 'team';\n        _aether.logStatementStart([{ofs: 83, row: 1, col: 3}, {ofs: 95, row: 1, col: 15}]); tmp3 = tmp5[tmp6];  _aether.logStatement([{ofs: 83, row: 1, col: 3}, {ofs: 95, row: 1, col: 15}], _aether._userInfo, false);\n        tmp7 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n        tmp8 = 'team';\n        _aether.logStatementStart([{ofs: 100, row: 1, col: 20}, {ofs: 109, row: 1, col: 29}]); tmp4 = tmp7[tmp8];  _aether.logStatement([{ofs: 100, row: 1, col: 20}, {ofs: 109, row: 1, col: 29}], _aether._userInfo, false);\n        _aether.logStatementStart([{ofs: 83, row: 1, col: 3}, {ofs: 109, row: 1, col: 29}]); tmp2 = tmp3 !== tmp4;  _aether.logStatement([{ofs: 83, row: 1, col: 3}, {ofs: 109, row: 1, col: 29}], _aether._userInfo, false);\n        if (tmp2) {\n            _aether.logCallEnd(); return;\n        } else {\n            ;\n        }\n        _aether.logCallEnd(); return;\n    };\n    tmp0 = 'hear';\n    __global[tmp0] = tmp1;\n}(this));"
         },
-        "ogre-base": {
-          "chooseAction": "// This is the code for your base. Decide which unit to build each frame.\n// Units you build will go into the this.built array.\n// If you don't have enough gold, this.build() won't build anything.\n// You start with 100 gold and receive 2 gold per second.\n// Kill enemies, especially towers and brawlers, to earn more gold.\n// Destroy the enemy base within 90 seconds!\n// Check out the Guide just up and to the left for more info.\n\nvar type = 'munchkin';\nif(this.built.length % 10 === 3)\n    type = 'shaman';\nelse if(this.built.length % 6 === 1)\n    type = 'thrower';\n\n//this.say('Unit #' + this.built.length + ' will be a ' + type);\nthis.build(type);\n",
-          "hear": "// When the base hears a say() message, this hear() method will be called.\nif(speaker.team !== this.team) return;\n\n// You can add code to respond to the message here."
+        "programmable-soldier": {
+          "chooseAction": "var __interceptThis=(function(){var G=this;return function($this,sandbox){if($this==G){return sandbox;}return $this;};})();\nreturn (function (__global) {\n    var tmp0, tmp1;\n    tmp1 = function () {\n        'use strict'; _aether.logCallStart(_aether._userInfo); var enemy, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8, tmp9, tmp10, tmp11, tmp12, tmp13, tmp14;  for(var __argIndexer = 0; __argIndexer < arguments.length; ++__argIndexer) arguments[__argIndexer] = _aether.createAPIClone(_aether, arguments[__argIndexer]);\n        tmp2 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n        tmp3 = 'getNearestEnemy';\n        _aether.logStatementStart([{ofs: 172, row: 4, col: 0}, {ofs: 207, row: 4, col: 35}]); enemy = _aether.createAPIClone(_aether, tmp2[tmp3]());  _aether.logStatement([{ofs: 172, row: 4, col: 0}, {ofs: 207, row: 4, col: 35}], _aether._userInfo, false);\n        tmp4 = enemy;\n        if (tmp4) {\n            tmp5 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n            tmp6 = 'attack';\n            tmp7 = enemy;\n            _aether.logStatementStart([{ofs: 255, row: 7, col: 4}, {ofs: 273, row: 7, col: 22}]); tmp8 = _aether.createAPIClone(_aether, tmp5[tmp6](_aether.restoreAPIClone(_aether, tmp7)));  _aether.logStatement([{ofs: 255, row: 7, col: 4}, {ofs: 273, row: 7, col: 22}], _aether._userInfo, false);\n        } else {\n            tmp9 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n            tmp10 = 'move';\n            _aether.logStatementStart([{ofs: 311, row: 10, col: 11}, {ofs: 313, row: 10, col: 13}]); tmp12 = 40;  _aether.logStatement([{ofs: 311, row: 10, col: 11}, {ofs: 313, row: 10, col: 13}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 326, row: 11, col: 11}, {ofs: 328, row: 11, col: 13}]); tmp13 = 24;  _aether.logStatement([{ofs: 326, row: 11, col: 11}, {ofs: 328, row: 11, col: 13}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 298, row: 9, col: 14}, {ofs: 334, row: 12, col: 5}]); tmp11 = {\n                x: tmp12,\n                y: tmp13\n            };  _aether.logStatement([{ofs: 298, row: 9, col: 14}, {ofs: 334, row: 12, col: 5}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 288, row: 9, col: 4}, {ofs: 335, row: 12, col: 6}]); tmp14 = _aether.createAPIClone(_aether, tmp9[tmp10](_aether.restoreAPIClone(_aether, tmp11)));  _aether.logStatement([{ofs: 288, row: 9, col: 4}, {ofs: 335, row: 12, col: 6}], _aether._userInfo, false);\n        }\n        _aether.logCallEnd(); return;\n    };\n    tmp0 = 'chooseAction';\n    __global[tmp0] = tmp1;\n}(this));",
+          "hear": "var __interceptThis=(function(){var G=this;return function($this,sandbox){if($this==G){return sandbox;}return $this;};})();\nreturn (function (__global) {\n    var tmp0, tmp1;\n    tmp1 = function (speaker, message, data) {\n        'use strict'; _aether.logCallStart(_aether._userInfo); var tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8; speaker = _aether.createAPIClone(_aether, speaker); message = _aether.createAPIClone(_aether, message); data = _aether.createAPIClone(_aether, data); for(var __argIndexer = 0; __argIndexer < arguments.length; ++__argIndexer) arguments[__argIndexer] = _aether.createAPIClone(_aether, arguments[__argIndexer]);\n        tmp5 = speaker;\n        tmp6 = 'team';\n        _aether.logStatementStart([{ofs: 81, row: 1, col: 3}, {ofs: 93, row: 1, col: 15}]); tmp3 = tmp5[tmp6];  _aether.logStatement([{ofs: 81, row: 1, col: 3}, {ofs: 93, row: 1, col: 15}], _aether._userInfo, false);\n        tmp7 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n        tmp8 = 'team';\n        _aether.logStatementStart([{ofs: 98, row: 1, col: 20}, {ofs: 107, row: 1, col: 29}]); tmp4 = tmp7[tmp8];  _aether.logStatement([{ofs: 98, row: 1, col: 20}, {ofs: 107, row: 1, col: 29}], _aether._userInfo, false);\n        _aether.logStatementStart([{ofs: 81, row: 1, col: 3}, {ofs: 107, row: 1, col: 29}]); tmp2 = tmp3 !== tmp4;  _aether.logStatement([{ofs: 81, row: 1, col: 3}, {ofs: 107, row: 1, col: 29}], _aether._userInfo, false);\n        if (tmp2) {\n            _aether.logCallEnd(); return;\n        } else {\n            ;\n        }\n        _aether.logCallEnd(); return;\n    };\n    tmp0 = 'hear';\n    __global[tmp0] = tmp1;\n}(this));"
+        },
+        "s-arrow-tower": {
+          "chooseAction": "var __interceptThis=(function(){var G=this;return function($this,sandbox){if($this==G){return sandbox;}return $this;};})();\nreturn (function (__global) {\n    var tmp0, tmp1;\n    tmp1 = function () {\n        'use strict'; _aether.logCallStart(_aether._userInfo); var enemy, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8, tmp9, tmp10, tmp11, tmp12, tmp13, tmp14, tmp15, tmp16, tmp17, tmp18, tmp19, tmp20, tmp21, tmp22, tmp23, tmp24, tmp25, tmp26;  for(var __argIndexer = 0; __argIndexer < arguments.length; ++__argIndexer) arguments[__argIndexer] = _aether.createAPIClone(_aether, arguments[__argIndexer]);\n        tmp2 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n        tmp3 = 'getNearestEnemy';\n        _aether.logStatementStart([{ofs: 169, row: 4, col: 0}, {ofs: 204, row: 4, col: 35}]); enemy = _aether.createAPIClone(_aether, tmp2[tmp3]());  _aether.logStatement([{ofs: 169, row: 4, col: 0}, {ofs: 204, row: 4, col: 35}], _aether._userInfo, false);\n        tmp5 = enemy;\n        if (tmp5) {\n            tmp8 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n            tmp9 = 'distance';\n            tmp10 = enemy;\n            _aether.logStatementStart([{ofs: 219, row: 6, col: 13}, {ofs: 239, row: 6, col: 33}]); tmp6 = _aether.createAPIClone(_aether, tmp8[tmp9](_aether.restoreAPIClone(_aether, tmp10)));  _aether.logStatement([{ofs: 219, row: 6, col: 13}, {ofs: 239, row: 6, col: 33}], _aether._userInfo, false);\n            tmp11 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n            tmp12 = 'attackRange';\n            _aether.logStatementStart([{ofs: 242, row: 6, col: 36}, {ofs: 258, row: 6, col: 52}]); tmp7 = tmp11[tmp12];  _aether.logStatement([{ofs: 242, row: 6, col: 36}, {ofs: 258, row: 6, col: 52}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 219, row: 6, col: 13}, {ofs: 258, row: 6, col: 52}]); tmp4 = tmp6 < tmp7;  _aether.logStatement([{ofs: 219, row: 6, col: 13}, {ofs: 258, row: 6, col: 52}], _aether._userInfo, false);\n        } else {\n            _aether.logStatementStart([{ofs: 210, row: 6, col: 4}, {ofs: 258, row: 6, col: 52}]); tmp4 = tmp5;  _aether.logStatement([{ofs: 210, row: 6, col: 4}, {ofs: 258, row: 6, col: 52}], _aether._userInfo, false);\n        }\n        if (tmp4) {\n            tmp13 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n            tmp14 = 'say';\n            _aether.logStatementStart([{ofs: 275, row: 7, col: 13}, {ofs: 288, row: 7, col: 26}]); tmp18 = 'EAT DEATH, ';  _aether.logStatement([{ofs: 275, row: 7, col: 13}, {ofs: 288, row: 7, col: 26}], _aether._userInfo, false);\n            tmp20 = enemy;\n            tmp21 = 'id';\n            _aether.logStatementStart([{ofs: 291, row: 7, col: 29}, {ofs: 299, row: 7, col: 37}]); tmp19 = tmp20[tmp21];  _aether.logStatement([{ofs: 291, row: 7, col: 29}, {ofs: 299, row: 7, col: 37}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 275, row: 7, col: 13}, {ofs: 299, row: 7, col: 37}]); tmp16 = tmp18 + tmp19;  _aether.logStatement([{ofs: 275, row: 7, col: 13}, {ofs: 299, row: 7, col: 37}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 302, row: 7, col: 40}, {ofs: 305, row: 7, col: 43}]); tmp17 = '!';  _aether.logStatement([{ofs: 302, row: 7, col: 40}, {ofs: 305, row: 7, col: 43}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 275, row: 7, col: 13}, {ofs: 305, row: 7, col: 43}]); tmp15 = tmp16 + tmp17;  _aether.logStatement([{ofs: 275, row: 7, col: 13}, {ofs: 305, row: 7, col: 43}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 266, row: 7, col: 4}, {ofs: 306, row: 7, col: 44}]); tmp22 = _aether.createAPIClone(_aether, tmp13[tmp14](_aether.restoreAPIClone(_aether, tmp15)));  _aether.logStatement([{ofs: 266, row: 7, col: 4}, {ofs: 306, row: 7, col: 44}], _aether._userInfo, false);\n            tmp23 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n            tmp24 = 'attack';\n            tmp25 = enemy;\n            _aether.logStatementStart([{ofs: 312, row: 8, col: 4}, {ofs: 330, row: 8, col: 22}]); tmp26 = _aether.createAPIClone(_aether, tmp23[tmp24](_aether.restoreAPIClone(_aether, tmp25)));  _aether.logStatement([{ofs: 312, row: 8, col: 4}, {ofs: 330, row: 8, col: 22}], _aether._userInfo, false);\n        } else {\n            ;\n        }\n        _aether.logCallEnd(); return;\n    };\n    tmp0 = 'chooseAction';\n    __global[tmp0] = tmp1;\n}(this));"
+        },
+        "programmable-archer": {
+          "chooseAction": "var __interceptThis=(function(){var G=this;return function($this,sandbox){if($this==G){return sandbox;}return $this;};})();\nreturn (function (__global) {\n    var tmp0, tmp1;\n    tmp1 = function () {\n        'use strict'; _aether.logCallStart(_aether._userInfo); var tmp2, tmp3, tmp4, tmp48, tmp49, tmp50, tmp178, tmp179, tmp180, tmp273, tmp274, tmp275, tmp276, tmp277, tmp278, tmp279, tmp280, tmp281, tmp282, tmp283, tmp284, tmp285, tmp286, tmp287, tmp288, tmp289, tmp290, tmp291, tmp292, tmp293, tmp294, tmp295, tmp296, tmp297, tmp298, tmp299, tmp300, tmp301, tmp302, tmp303, tmp304, tmp305, tmp306, tmp307, tmp308, tmp309, tmp310, tmp311, tmp312, tmp313, tmp314, tmp315, tmp316, tmp317, tmp318, tmp319, tmp320, tmp321, tmp322, tmp323, tmp324, tmp325, tmp326, tmp327, tmp328, tmp329, tmp330, tmp331, tmp332, tmp333, tmp334, tmp335;  for(var __argIndexer = 0; __argIndexer < arguments.length; ++__argIndexer) arguments[__argIndexer] = _aether.createAPIClone(_aether, arguments[__argIndexer]);\n        tmp2 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n        tmp3 = 'getGold';\n        _aether.logStatementStart([{ofs: 326, row: 9, col: 0}, {ofs: 974, row: 29, col: 0}]); tmp4 = function (location, saying) {\n            var items, item, i, tmp5, tmp6, tmp7, tmp8, tmp9, tmp10, tmp11, tmp12, tmp13, tmp14, tmp15, tmp16, tmp17, tmp20, tmp21, tmp22, tmp23, tmp24, tmp25, tmp26, tmp27, tmp28, tmp29, tmp30, tmp31, tmp32, tmp33, tmp34, tmp35, tmp36, tmp37, tmp38, tmp39, tmp40, tmp41, tmp42, tmp43, tmp44, tmp45, tmp46, tmp47; location = _aether.createAPIClone(_aether, location); saying = _aether.createAPIClone(_aether, saying); for(var __argIndexer = 0; __argIndexer < arguments.length; ++__argIndexer) arguments[__argIndexer] = _aether.createAPIClone(_aether, arguments[__argIndexer]);\n            tmp5 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n            tmp6 = 'getItems';\n            _aether.logStatementStart([{ofs: 406, row: 11, col: 4}, {ofs: 430, row: 11, col: 28}]); items = _aether.createAPIClone(_aether, tmp5[tmp6]());  _aether.logStatement([{ofs: 406, row: 11, col: 4}, {ofs: 430, row: 11, col: 28}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 444, row: 12, col: 13}, {ofs: 445, row: 12, col: 14}]); i = 0;  _aether.logStatement([{ofs: 444, row: 12, col: 13}, {ofs: 445, row: 12, col: 14}], _aether._userInfo, false);\n            tmp8 = i;\n            tmp10 = items;\n            tmp11 = 'length';\n            _aether.logStatementStart([{ofs: 451, row: 12, col: 20}, {ofs: 463, row: 12, col: 32}]); tmp9 = tmp10[tmp11];  _aether.logStatement([{ofs: 451, row: 12, col: 20}, {ofs: 463, row: 12, col: 32}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 447, row: 12, col: 16}, {ofs: 463, row: 12, col: 32}]); tmp7 = tmp8 < tmp9;  _aether.logStatement([{ofs: 447, row: 12, col: 16}, {ofs: 463, row: 12, col: 32}], _aether._userInfo, false);\n            tmp18: {\n                while (tmp7) {\n                    tmp19: {\n                        tmp21 = i;\n                        _aether.logStatementStart([{ofs: 490, row: 13, col: 18}, {ofs: 491, row: 13, col: 19}]); tmp22 = 3;  _aether.logStatement([{ofs: 490, row: 13, col: 18}, {ofs: 491, row: 13, col: 19}], _aether._userInfo, false);\n                        _aether.logStatementStart([{ofs: 484, row: 13, col: 12}, {ofs: 491, row: 13, col: 19}]); tmp20 = tmp21 !== tmp22;  _aether.logStatement([{ofs: 484, row: 13, col: 12}, {ofs: 491, row: 13, col: 19}], _aether._userInfo, false);\n                        if (tmp20) {\n                            tmp23 = items;\n                            tmp24 = i;\n                            _aether.logStatementStart([{ofs: 507, row: 14, col: 12}, {ofs: 523, row: 14, col: 28}]); item = tmp23[tmp24];  _aether.logStatement([{ofs: 507, row: 14, col: 12}, {ofs: 523, row: 14, col: 28}], _aether._userInfo, false);\n                            tmp28 = location;\n                            _aether.logStatementStart([{ofs: 553, row: 15, col: 29}, {ofs: 559, row: 15, col: 35}]); tmp29 = 'left';  _aether.logStatement([{ofs: 553, row: 15, col: 29}, {ofs: 559, row: 15, col: 35}], _aether._userInfo, false);\n                            _aether.logStatementStart([{ofs: 541, row: 15, col: 17}, {ofs: 559, row: 15, col: 35}]); tmp27 = tmp28 == tmp29;  _aether.logStatement([{ofs: 541, row: 15, col: 17}, {ofs: 559, row: 15, col: 35}], _aether._userInfo, false);\n                            if (tmp27) {\n                                tmp32 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n                                tmp33 = 'distance';\n                                tmp34 = item;\n                                _aether.logStatementStart([{ofs: 563, row: 15, col: 39}, {ofs: 582, row: 15, col: 58}]); tmp30 = _aether.createAPIClone(_aether, tmp32[tmp33](_aether.restoreAPIClone(_aether, tmp34)));  _aether.logStatement([{ofs: 563, row: 15, col: 39}, {ofs: 582, row: 15, col: 58}], _aether._userInfo, false);\n                                _aether.logStatementStart([{ofs: 585, row: 15, col: 61}, {ofs: 587, row: 15, col: 63}]); tmp31 = 60;  _aether.logStatement([{ofs: 585, row: 15, col: 61}, {ofs: 587, row: 15, col: 63}], _aether._userInfo, false);\n                                _aether.logStatementStart([{ofs: 563, row: 15, col: 39}, {ofs: 587, row: 15, col: 63}]); tmp26 = tmp30 < tmp31;  _aether.logStatement([{ofs: 563, row: 15, col: 39}, {ofs: 587, row: 15, col: 63}], _aether._userInfo, false);\n                            } else {\n                                _aether.logStatementStart([{ofs: 541, row: 15, col: 17}, {ofs: 587, row: 15, col: 63}]); tmp26 = tmp27;  _aether.logStatement([{ofs: 541, row: 15, col: 17}, {ofs: 587, row: 15, col: 63}], _aether._userInfo, false);\n                            }\n                            if (tmp26) {\n                                _aether.logStatementStart([{ofs: 540, row: 15, col: 16}, {ofs: 611, row: 15, col: 87}]); tmp25 = tmp26;  _aether.logStatement([{ofs: 540, row: 15, col: 16}, {ofs: 611, row: 15, col: 87}], _aether._userInfo, false);\n                            } else {\n                                tmp35 = location;\n                                _aether.logStatementStart([{ofs: 604, row: 15, col: 80}, {ofs: 611, row: 15, col: 87}]); tmp36 = 'right';  _aether.logStatement([{ofs: 604, row: 15, col: 80}, {ofs: 611, row: 15, col: 87}], _aether._userInfo, false);\n                                _aether.logStatementStart([{ofs: 592, row: 15, col: 68}, {ofs: 611, row: 15, col: 87}]); tmp25 = tmp35 == tmp36;  _aether.logStatement([{ofs: 592, row: 15, col: 68}, {ofs: 611, row: 15, col: 87}], _aether._userInfo, false);\n                            }\n                            if (tmp25) {\n                                tmp37 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n                                tmp38 = 'move';\n                                tmp40 = item;\n                                tmp41 = 'pos';\n                                _aether.logStatementStart([{ofs: 641, row: 16, col: 26}, {ofs: 649, row: 16, col: 34}]); tmp39 = tmp40[tmp41];  _aether.logStatement([{ofs: 641, row: 16, col: 26}, {ofs: 649, row: 16, col: 34}], _aether._userInfo, false);\n                                _aether.logStatementStart([{ofs: 631, row: 16, col: 16}, {ofs: 650, row: 16, col: 35}]); tmp42 = _aether.createAPIClone(_aether, tmp37[tmp38](_aether.restoreAPIClone(_aether, tmp39)));  _aether.logStatement([{ofs: 631, row: 16, col: 16}, {ofs: 650, row: 16, col: 35}], _aether._userInfo, false);\n                                tmp43 = saying;\n                                if (tmp43) {\n                                    tmp44 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n                                    tmp45 = 'say';\n                                    tmp46 = saying;\n                                    _aether.logStatementStart([{ofs: 702, row: 18, col: 20}, {ofs: 718, row: 18, col: 36}]); tmp47 = _aether.createAPIClone(_aether, tmp44[tmp45](_aether.restoreAPIClone(_aether, tmp46)));  _aether.logStatement([{ofs: 702, row: 18, col: 20}, {ofs: 718, row: 18, col: 36}], _aether._userInfo, false);\n                                } else {\n                                    ;\n                                }\n                            } else {\n                                ;\n                            }\n                        } else {\n                            ;\n                        }\n                    }\n                    tmp16 = i;\n                    tmp17 = 1;\n                    i = tmp16 + tmp17;\n                    tmp12 = i;\n                    tmp14 = items;\n                    tmp15 = 'length';\n                    _aether.logStatementStart([{ofs: 451, row: 12, col: 20}, {ofs: 463, row: 12, col: 32}]); tmp13 = tmp14[tmp15];  _aether.logStatement([{ofs: 451, row: 12, col: 20}, {ofs: 463, row: 12, col: 32}], _aether._userInfo, false);\n                    _aether.logStatementStart([{ofs: 447, row: 12, col: 16}, {ofs: 463, row: 12, col: 32}]); tmp7 = tmp12 < tmp13;  _aether.logStatement([{ofs: 447, row: 12, col: 16}, {ofs: 463, row: 12, col: 32}], _aether._userInfo, false);\n                }\n            }\n            return;\n        };  _aether.logStatement([{ofs: 326, row: 9, col: 0}, {ofs: 974, row: 29, col: 0}], _aether._userInfo, false);\n        _aether.logStatementStart([{ofs: 326, row: 9, col: 0}, {ofs: 769, row: 23, col: 1}]); tmp2[tmp3] = tmp4;  _aether.logStatement([{ofs: 326, row: 9, col: 0}, {ofs: 769, row: 23, col: 1}], _aether._userInfo, false);\n        tmp48 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n        tmp49 = 'evade';\n        _aether.logStatementStart([{ofs: 974, row: 29, col: 0}, {ofs: 2278, row: 59, col: 0}]); tmp50 = function () {\n            var nearest, distance, maxrange, newx, newy, evadeLoc, tmp51, tmp52, tmp53, tmp54, tmp55, tmp56, tmp57, tmp58, tmp59, tmp60, tmp61, tmp62, tmp63, tmp64, tmp65, tmp66, tmp67, tmp68, tmp69, tmp70, tmp71, tmp72, tmp73, tmp74, tmp75, tmp76, tmp77, tmp78, tmp79, tmp80, tmp81, tmp82, tmp83, tmp84, tmp85, tmp86, tmp87, tmp88, tmp89, tmp90, tmp91, tmp92, tmp93, tmp94, tmp95, tmp96, tmp97, tmp98, tmp99, tmp100, tmp101, tmp102, tmp103, tmp104, tmp105, tmp106, tmp107, tmp108, tmp109, tmp110, tmp111, tmp112, tmp113, tmp114, tmp115, tmp116, tmp117, tmp118, tmp119, tmp120, tmp121, tmp122, tmp123, tmp124, tmp125, tmp126, tmp127, tmp128, tmp129, tmp130, tmp131, tmp132, tmp133, tmp134, tmp135, tmp136, tmp137, tmp138, tmp139, tmp140, tmp141, tmp142, tmp143, tmp144, tmp145, tmp146, tmp147, tmp148, tmp149, tmp150, tmp151, tmp152, tmp153, tmp154, tmp155, tmp156, tmp157, tmp158, tmp159, tmp160, tmp161, tmp162, tmp163, tmp164, tmp165, tmp166, tmp167, tmp168, tmp169, tmp170, tmp171, tmp172, tmp173, tmp174, tmp175, tmp176, tmp177;  for(var __argIndexer = 0; __argIndexer < arguments.length; ++__argIndexer) arguments[__argIndexer] = _aether.createAPIClone(_aether, arguments[__argIndexer]);\n            tmp51 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n            tmp52 = 'getNearestEnemy';\n            _aether.logStatementStart([{ofs: 1004, row: 30, col: 4}, {ofs: 1041, row: 30, col: 41}]); nearest = _aether.createAPIClone(_aether, tmp51[tmp52]());  _aether.logStatement([{ofs: 1004, row: 30, col: 4}, {ofs: 1041, row: 30, col: 41}], _aether._userInfo, false);\n            tmp53 = nearest;\n            if (tmp53) {\n                tmp54 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n                tmp55 = 'distance';\n                tmp56 = nearest;\n                _aether.logStatementStart([{ofs: 1069, row: 32, col: 8}, {ofs: 1107, row: 32, col: 46}]); distance = _aether.createAPIClone(_aether, tmp54[tmp55](_aether.restoreAPIClone(_aether, tmp56)));  _aether.logStatement([{ofs: 1069, row: 32, col: 8}, {ofs: 1107, row: 32, col: 46}], _aether._userInfo, false);\n                tmp57 = nearest;\n                tmp58 = 'attackRange';\n                _aether.logStatementStart([{ofs: 1116, row: 33, col: 8}, {ofs: 1151, row: 33, col: 43}]); maxrange = tmp57[tmp58];  _aether.logStatement([{ofs: 1116, row: 33, col: 8}, {ofs: 1151, row: 33, col: 43}], _aether._userInfo, false);\n                tmp60 = maxrange;\n                _aether.logStatementStart([{ofs: 1161, row: 34, col: 9}, {ofs: 1170, row: 34, col: 18}]); tmp59 = !tmp60;  _aether.logStatement([{ofs: 1161, row: 34, col: 9}, {ofs: 1170, row: 34, col: 18}], _aether._userInfo, false);\n                if (tmp59) {\n                    _aether.logStatementStart([{ofs: 1174, row: 34, col: 22}, {ofs: 1188, row: 34, col: 36}]); maxrange = 10;  _aether.logStatement([{ofs: 1174, row: 34, col: 22}, {ofs: 1188, row: 34, col: 36}], _aether._userInfo, false);\n                } else {\n                    ;\n                }\n                tmp64 = distance;\n                tmp66 = maxrange;\n                _aether.logStatementStart([{ofs: 1267, row: 36, col: 34}, {ofs: 1268, row: 36, col: 35}]); tmp67 = 3;  _aether.logStatement([{ofs: 1267, row: 36, col: 34}, {ofs: 1268, row: 36, col: 35}], _aether._userInfo, false);\n                _aether.logStatementStart([{ofs: 1256, row: 36, col: 23}, {ofs: 1268, row: 36, col: 35}]); tmp65 = tmp66 + tmp67;  _aether.logStatement([{ofs: 1256, row: 36, col: 23}, {ofs: 1268, row: 36, col: 35}], _aether._userInfo, false);\n                _aether.logStatementStart([{ofs: 1245, row: 36, col: 12}, {ofs: 1268, row: 36, col: 35}]); tmp63 = tmp64 < tmp65;  _aether.logStatement([{ofs: 1245, row: 36, col: 12}, {ofs: 1268, row: 36, col: 35}], _aether._userInfo, false);\n                if (tmp63) {\n                    tmp70 = nearest;\n                    tmp71 = 'type';\n                    _aether.logStatementStart([{ofs: 1272, row: 36, col: 39}, {ofs: 1284, row: 36, col: 51}]); tmp68 = tmp70[tmp71];  _aether.logStatement([{ofs: 1272, row: 36, col: 39}, {ofs: 1284, row: 36, col: 51}], _aether._userInfo, false);\n                    _aether.logStatementStart([{ofs: 1289, row: 36, col: 56}, {ofs: 1301, row: 36, col: 68}]); tmp69 = 'beam-tower';  _aether.logStatement([{ofs: 1289, row: 36, col: 56}, {ofs: 1301, row: 36, col: 68}], _aether._userInfo, false);\n                    _aether.logStatementStart([{ofs: 1272, row: 36, col: 39}, {ofs: 1301, row: 36, col: 68}]); tmp62 = tmp68 !== tmp69;  _aether.logStatement([{ofs: 1272, row: 36, col: 39}, {ofs: 1301, row: 36, col: 68}], _aether._userInfo, false);\n                } else {\n                    _aether.logStatementStart([{ofs: 1245, row: 36, col: 12}, {ofs: 1301, row: 36, col: 68}]); tmp62 = tmp63;  _aether.logStatement([{ofs: 1245, row: 36, col: 12}, {ofs: 1301, row: 36, col: 68}], _aether._userInfo, false);\n                }\n                if (tmp62) {\n                    tmp74 = nearest;\n                    tmp75 = 'type';\n                    _aether.logStatementStart([{ofs: 1305, row: 36, col: 72}, {ofs: 1317, row: 36, col: 84}]); tmp72 = tmp74[tmp75];  _aether.logStatement([{ofs: 1305, row: 36, col: 72}, {ofs: 1317, row: 36, col: 84}], _aether._userInfo, false);\n                    _aether.logStatementStart([{ofs: 1322, row: 36, col: 89}, {ofs: 1331, row: 36, col: 98}]); tmp73 = 'thrower';  _aether.logStatement([{ofs: 1322, row: 36, col: 89}, {ofs: 1331, row: 36, col: 98}], _aether._userInfo, false);\n                    _aether.logStatementStart([{ofs: 1305, row: 36, col: 72}, {ofs: 1331, row: 36, col: 98}]); tmp61 = tmp72 !== tmp73;  _aether.logStatement([{ofs: 1305, row: 36, col: 72}, {ofs: 1331, row: 36, col: 98}], _aether._userInfo, false);\n                } else {\n                    _aether.logStatementStart([{ofs: 1245, row: 36, col: 12}, {ofs: 1331, row: 36, col: 98}]); tmp61 = tmp62;  _aether.logStatement([{ofs: 1245, row: 36, col: 12}, {ofs: 1331, row: 36, col: 98}], _aether._userInfo, false);\n                }\n                if (tmp61) {\n                    tmp81 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n                    tmp82 = 'pos';\n                    _aether.logStatementStart([{ofs: 1351, row: 37, col: 16}, {ofs: 1359, row: 37, col: 24}]); tmp79 = tmp81[tmp82];  _aether.logStatement([{ofs: 1351, row: 37, col: 16}, {ofs: 1359, row: 37, col: 24}], _aether._userInfo, false);\n                    tmp80 = 'x';\n                    _aether.logStatementStart([{ofs: 1351, row: 37, col: 16}, {ofs: 1361, row: 37, col: 26}]); tmp77 = tmp79[tmp80];  _aether.logStatement([{ofs: 1351, row: 37, col: 16}, {ofs: 1361, row: 37, col: 26}], _aether._userInfo, false);\n                    tmp85 = nearest;\n                    tmp86 = 'pos';\n                    _aether.logStatementStart([{ofs: 1364, row: 37, col: 29}, {ofs: 1375, row: 37, col: 40}]); tmp83 = tmp85[tmp86];  _aether.logStatement([{ofs: 1364, row: 37, col: 29}, {ofs: 1375, row: 37, col: 40}], _aether._userInfo, false);\n                    tmp84 = 'x';\n                    _aether.logStatementStart([{ofs: 1364, row: 37, col: 29}, {ofs: 1377, row: 37, col: 42}]); tmp78 = tmp83[tmp84];  _aether.logStatement([{ofs: 1364, row: 37, col: 29}, {ofs: 1377, row: 37, col: 42}], _aether._userInfo, false);\n                    _aether.logStatementStart([{ofs: 1351, row: 37, col: 16}, {ofs: 1377, row: 37, col: 42}]); tmp76 = tmp77 < tmp78;  _aether.logStatement([{ofs: 1351, row: 37, col: 16}, {ofs: 1377, row: 37, col: 42}], _aether._userInfo, false);\n                    if (tmp76) {\n                        tmp91 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n                        tmp92 = 'pos';\n                        _aether.logStatementStart([{ofs: 1388, row: 37, col: 53}, {ofs: 1396, row: 37, col: 61}]); tmp89 = tmp91[tmp92];  _aether.logStatement([{ofs: 1388, row: 37, col: 53}, {ofs: 1396, row: 37, col: 61}], _aether._userInfo, false);\n                        tmp90 = 'x';\n                        _aether.logStatementStart([{ofs: 1388, row: 37, col: 53}, {ofs: 1398, row: 37, col: 63}]); tmp87 = tmp89[tmp90];  _aether.logStatement([{ofs: 1388, row: 37, col: 53}, {ofs: 1398, row: 37, col: 63}], _aether._userInfo, false);\n                        tmp93 = maxrange;\n                        _aether.logStatementStart([{ofs: 1413, row: 37, col: 78}, {ofs: 1414, row: 37, col: 79}]); tmp94 = 3;  _aether.logStatement([{ofs: 1413, row: 37, col: 78}, {ofs: 1414, row: 37, col: 79}], _aether._userInfo, false);\n                        _aether.logStatementStart([{ofs: 1402, row: 37, col: 67}, {ofs: 1414, row: 37, col: 79}]); tmp88 = tmp93 + tmp94;  _aether.logStatement([{ofs: 1402, row: 37, col: 67}, {ofs: 1414, row: 37, col: 79}], _aether._userInfo, false);\n                        _aether.logStatementStart([{ofs: 1381, row: 37, col: 46}, {ofs: 1416, row: 37, col: 81}]); newx = tmp87 - tmp88;  _aether.logStatement([{ofs: 1381, row: 37, col: 46}, {ofs: 1416, row: 37, col: 81}], _aether._userInfo, false);\n                    } else {\n                        ;\n                    }\n                    tmp100 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n                    tmp101 = 'pos';\n                    _aether.logStatementStart([{ofs: 1435, row: 38, col: 16}, {ofs: 1443, row: 38, col: 24}]); tmp98 = tmp100[tmp101];  _aether.logStatement([{ofs: 1435, row: 38, col: 16}, {ofs: 1443, row: 38, col: 24}], _aether._userInfo, false);\n                    tmp99 = 'x';\n                    _aether.logStatementStart([{ofs: 1435, row: 38, col: 16}, {ofs: 1445, row: 38, col: 26}]); tmp96 = tmp98[tmp99];  _aether.logStatement([{ofs: 1435, row: 38, col: 16}, {ofs: 1445, row: 38, col: 26}], _aether._userInfo, false);\n                    tmp104 = nearest;\n                    tmp105 = 'pos';\n                    _aether.logStatementStart([{ofs: 1448, row: 38, col: 29}, {ofs: 1459, row: 38, col: 40}]); tmp102 = tmp104[tmp105];  _aether.logStatement([{ofs: 1448, row: 38, col: 29}, {ofs: 1459, row: 38, col: 40}], _aether._userInfo, false);\n                    tmp103 = 'x';\n                    _aether.logStatementStart([{ofs: 1448, row: 38, col: 29}, {ofs: 1461, row: 38, col: 42}]); tmp97 = tmp102[tmp103];  _aether.logStatement([{ofs: 1448, row: 38, col: 29}, {ofs: 1461, row: 38, col: 42}], _aether._userInfo, false);\n                    _aether.logStatementStart([{ofs: 1435, row: 38, col: 16}, {ofs: 1461, row: 38, col: 42}]); tmp95 = tmp96 > tmp97;  _aether.logStatement([{ofs: 1435, row: 38, col: 16}, {ofs: 1461, row: 38, col: 42}], _aether._userInfo, false);\n                    if (tmp95) {\n                        tmp110 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n                        tmp111 = 'pos';\n                        _aether.logStatementStart([{ofs: 1472, row: 38, col: 53}, {ofs: 1480, row: 38, col: 61}]); tmp108 = tmp110[tmp111];  _aether.logStatement([{ofs: 1472, row: 38, col: 53}, {ofs: 1480, row: 38, col: 61}], _aether._userInfo, false);\n                        tmp109 = 'x';\n                        _aether.logStatementStart([{ofs: 1472, row: 38, col: 53}, {ofs: 1482, row: 38, col: 63}]); tmp106 = tmp108[tmp109];  _aether.logStatement([{ofs: 1472, row: 38, col: 53}, {ofs: 1482, row: 38, col: 63}], _aether._userInfo, false);\n                        tmp112 = maxrange;\n                        _aether.logStatementStart([{ofs: 1497, row: 38, col: 78}, {ofs: 1498, row: 38, col: 79}]); tmp113 = 3;  _aether.logStatement([{ofs: 1497, row: 38, col: 78}, {ofs: 1498, row: 38, col: 79}], _aether._userInfo, false);\n                        _aether.logStatementStart([{ofs: 1486, row: 38, col: 67}, {ofs: 1498, row: 38, col: 79}]); tmp107 = tmp112 + tmp113;  _aether.logStatement([{ofs: 1486, row: 38, col: 67}, {ofs: 1498, row: 38, col: 79}], _aether._userInfo, false);\n                        _aether.logStatementStart([{ofs: 1465, row: 38, col: 46}, {ofs: 1500, row: 38, col: 81}]); newx = tmp106 + tmp107;  _aether.logStatement([{ofs: 1465, row: 38, col: 46}, {ofs: 1500, row: 38, col: 81}], _aether._userInfo, false);\n                    } else {\n                        ;\n                    }\n                    tmp119 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n                    tmp120 = 'pos';\n                    _aether.logStatementStart([{ofs: 1519, row: 39, col: 16}, {ofs: 1527, row: 39, col: 24}]); tmp117 = tmp119[tmp120];  _aether.logStatement([{ofs: 1519, row: 39, col: 16}, {ofs: 1527, row: 39, col: 24}], _aether._userInfo, false);\n                    tmp118 = 'y';\n                    _aether.logStatementStart([{ofs: 1519, row: 39, col: 16}, {ofs: 1529, row: 39, col: 26}]); tmp115 = tmp117[tmp118];  _aether.logStatement([{ofs: 1519, row: 39, col: 16}, {ofs: 1529, row: 39, col: 26}], _aether._userInfo, false);\n                    tmp123 = nearest;\n                    tmp124 = 'pos';\n                    _aether.logStatementStart([{ofs: 1532, row: 39, col: 29}, {ofs: 1543, row: 39, col: 40}]); tmp121 = tmp123[tmp124];  _aether.logStatement([{ofs: 1532, row: 39, col: 29}, {ofs: 1543, row: 39, col: 40}], _aether._userInfo, false);\n                    tmp122 = 'y';\n                    _aether.logStatementStart([{ofs: 1532, row: 39, col: 29}, {ofs: 1545, row: 39, col: 42}]); tmp116 = tmp121[tmp122];  _aether.logStatement([{ofs: 1532, row: 39, col: 29}, {ofs: 1545, row: 39, col: 42}], _aether._userInfo, false);\n                    _aether.logStatementStart([{ofs: 1519, row: 39, col: 16}, {ofs: 1545, row: 39, col: 42}]); tmp114 = tmp115 < tmp116;  _aether.logStatement([{ofs: 1519, row: 39, col: 16}, {ofs: 1545, row: 39, col: 42}], _aether._userInfo, false);\n                    if (tmp114) {\n                        tmp129 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n                        tmp130 = 'pos';\n                        _aether.logStatementStart([{ofs: 1556, row: 39, col: 53}, {ofs: 1564, row: 39, col: 61}]); tmp127 = tmp129[tmp130];  _aether.logStatement([{ofs: 1556, row: 39, col: 53}, {ofs: 1564, row: 39, col: 61}], _aether._userInfo, false);\n                        tmp128 = 'y';\n                        _aether.logStatementStart([{ofs: 1556, row: 39, col: 53}, {ofs: 1566, row: 39, col: 63}]); tmp125 = tmp127[tmp128];  _aether.logStatement([{ofs: 1556, row: 39, col: 53}, {ofs: 1566, row: 39, col: 63}], _aether._userInfo, false);\n                        tmp131 = maxrange;\n                        _aether.logStatementStart([{ofs: 1581, row: 39, col: 78}, {ofs: 1582, row: 39, col: 79}]); tmp132 = 3;  _aether.logStatement([{ofs: 1581, row: 39, col: 78}, {ofs: 1582, row: 39, col: 79}], _aether._userInfo, false);\n                        _aether.logStatementStart([{ofs: 1570, row: 39, col: 67}, {ofs: 1582, row: 39, col: 79}]); tmp126 = tmp131 + tmp132;  _aether.logStatement([{ofs: 1570, row: 39, col: 67}, {ofs: 1582, row: 39, col: 79}], _aether._userInfo, false);\n                        _aether.logStatementStart([{ofs: 1549, row: 39, col: 46}, {ofs: 1584, row: 39, col: 81}]); newy = tmp125 - tmp126;  _aether.logStatement([{ofs: 1549, row: 39, col: 46}, {ofs: 1584, row: 39, col: 81}], _aether._userInfo, false);\n                    } else {\n                        ;\n                    }\n                    tmp138 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n                    tmp139 = 'pos';\n                    _aether.logStatementStart([{ofs: 1603, row: 40, col: 16}, {ofs: 1611, row: 40, col: 24}]); tmp136 = tmp138[tmp139];  _aether.logStatement([{ofs: 1603, row: 40, col: 16}, {ofs: 1611, row: 40, col: 24}], _aether._userInfo, false);\n                    tmp137 = 'y';\n                    _aether.logStatementStart([{ofs: 1603, row: 40, col: 16}, {ofs: 1613, row: 40, col: 26}]); tmp134 = tmp136[tmp137];  _aether.logStatement([{ofs: 1603, row: 40, col: 16}, {ofs: 1613, row: 40, col: 26}], _aether._userInfo, false);\n                    tmp142 = nearest;\n                    tmp143 = 'pos';\n                    _aether.logStatementStart([{ofs: 1616, row: 40, col: 29}, {ofs: 1627, row: 40, col: 40}]); tmp140 = tmp142[tmp143];  _aether.logStatement([{ofs: 1616, row: 40, col: 29}, {ofs: 1627, row: 40, col: 40}], _aether._userInfo, false);\n                    tmp141 = 'y';\n                    _aether.logStatementStart([{ofs: 1616, row: 40, col: 29}, {ofs: 1629, row: 40, col: 42}]); tmp135 = tmp140[tmp141];  _aether.logStatement([{ofs: 1616, row: 40, col: 29}, {ofs: 1629, row: 40, col: 42}], _aether._userInfo, false);\n                    _aether.logStatementStart([{ofs: 1603, row: 40, col: 16}, {ofs: 1629, row: 40, col: 42}]); tmp133 = tmp134 > tmp135;  _aether.logStatement([{ofs: 1603, row: 40, col: 16}, {ofs: 1629, row: 40, col: 42}], _aether._userInfo, false);\n                    if (tmp133) {\n                        tmp148 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n                        tmp149 = 'pos';\n                        _aether.logStatementStart([{ofs: 1640, row: 40, col: 53}, {ofs: 1648, row: 40, col: 61}]); tmp146 = tmp148[tmp149];  _aether.logStatement([{ofs: 1640, row: 40, col: 53}, {ofs: 1648, row: 40, col: 61}], _aether._userInfo, false);\n                        tmp147 = 'y';\n                        _aether.logStatementStart([{ofs: 1640, row: 40, col: 53}, {ofs: 1650, row: 40, col: 63}]); tmp144 = tmp146[tmp147];  _aether.logStatement([{ofs: 1640, row: 40, col: 53}, {ofs: 1650, row: 40, col: 63}], _aether._userInfo, false);\n                        tmp150 = maxrange;\n                        _aether.logStatementStart([{ofs: 1665, row: 40, col: 78}, {ofs: 1666, row: 40, col: 79}]); tmp151 = 3;  _aether.logStatement([{ofs: 1665, row: 40, col: 78}, {ofs: 1666, row: 40, col: 79}], _aether._userInfo, false);\n                        _aether.logStatementStart([{ofs: 1654, row: 40, col: 67}, {ofs: 1666, row: 40, col: 79}]); tmp145 = tmp150 + tmp151;  _aether.logStatement([{ofs: 1654, row: 40, col: 67}, {ofs: 1666, row: 40, col: 79}], _aether._userInfo, false);\n                        _aether.logStatementStart([{ofs: 1633, row: 40, col: 46}, {ofs: 1668, row: 40, col: 81}]); newy = tmp144 + tmp145;  _aether.logStatement([{ofs: 1633, row: 40, col: 46}, {ofs: 1668, row: 40, col: 81}], _aether._userInfo, false);\n                    } else {\n                        ;\n                    }\n                    tmp154 = 'Math';\n                    tmp155 = tmp154 in __global;\n                    if (tmp155) {\n                        tmp152 = __global[tmp154];\n                    } else { _aether.logStatementStart([{ofs: 1690, row: 41, col: 19}, {ofs: 1694, row: 41, col: 23}]);\n                        tmp156 = 'ReferenceError';\n                        tmp157 = __global[tmp156];\n                        tmp158 = new tmp157('ReferenceError: ' + (tmp154 + ' is not defined'));\n                        throw tmp158;\n                     _aether.logStatement([{ofs: 1690, row: 41, col: 19}, {ofs: 1694, row: 41, col: 23}], _aether._userInfo, false); }\n                    tmp153 = 'round';\n                    tmp159 = newx;\n                    _aether.logStatementStart([{ofs: 1683, row: 41, col: 12}, {ofs: 1707, row: 41, col: 36}]); newx = _aether.createAPIClone(_aether, tmp152[tmp153](_aether.restoreAPIClone(_aether, tmp159)));  _aether.logStatement([{ofs: 1683, row: 41, col: 12}, {ofs: 1707, row: 41, col: 36}], _aether._userInfo, false);\n                    tmp162 = 'Math';\n                    tmp163 = tmp162 in __global;\n                    if (tmp163) {\n                        tmp160 = __global[tmp162];\n                    } else { _aether.logStatementStart([{ofs: 1727, row: 42, col: 19}, {ofs: 1731, row: 42, col: 23}]);\n                        tmp164 = 'ReferenceError';\n                        tmp165 = __global[tmp164];\n                        tmp166 = new tmp165('ReferenceError: ' + (tmp162 + ' is not defined'));\n                        throw tmp166;\n                     _aether.logStatement([{ofs: 1727, row: 42, col: 19}, {ofs: 1731, row: 42, col: 23}], _aether._userInfo, false); }\n                    tmp161 = 'round';\n                    tmp167 = newy;\n                    _aether.logStatementStart([{ofs: 1720, row: 42, col: 12}, {ofs: 1744, row: 42, col: 36}]); newy = _aether.createAPIClone(_aether, tmp160[tmp161](_aether.restoreAPIClone(_aether, tmp167)));  _aether.logStatement([{ofs: 1720, row: 42, col: 12}, {ofs: 1744, row: 42, col: 36}], _aether._userInfo, false);\n                    tmp169 = newx;\n                    if (tmp169) {\n                        tmp168 = newy;\n                    } else {\n                        _aether.logStatementStart([{ofs: 1761, row: 43, col: 16}, {ofs: 1773, row: 43, col: 28}]); tmp168 = tmp169;  _aether.logStatement([{ofs: 1761, row: 43, col: 16}, {ofs: 1773, row: 43, col: 28}], _aether._userInfo, false);\n                    }\n                    if (tmp168) {\n                        tmp170 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n                        tmp171 = 'move';\n                        tmp173 = newx;\n                        tmp174 = newy;\n                        _aether.logStatementStart([{ofs: 1884, row: 45, col: 26}, {ofs: 1902, row: 45, col: 44}]); tmp172 = {\n                            x: tmp173,\n                            y: tmp174\n                        };  _aether.logStatement([{ofs: 1884, row: 45, col: 26}, {ofs: 1902, row: 45, col: 44}], _aether._userInfo, false);\n                        _aether.logStatementStart([{ofs: 1874, row: 45, col: 16}, {ofs: 1903, row: 45, col: 45}]); tmp175 = _aether.createAPIClone(_aether, tmp170[tmp171](_aether.restoreAPIClone(_aether, tmp172)));  _aether.logStatement([{ofs: 1874, row: 45, col: 16}, {ofs: 1903, row: 45, col: 45}], _aether._userInfo, false);\n                        _aether.logStatementStart([{ofs: 1928, row: 46, col: 23}, {ofs: 1937, row: 46, col: 32}]); tmp176 = 'evading';  _aether.logStatement([{ofs: 1928, row: 46, col: 23}, {ofs: 1937, row: 46, col: 32}], _aether._userInfo, false);\n                        return _aether.restoreAPIClone(_aether, tmp176);\n                    } else {\n                        ;\n                    }\n                } else {\n                    ;\n                }\n            } else {\n                ;\n            }\n            _aether.logStatementStart([{ofs: 1980, row: 50, col: 11}, {ofs: 1987, row: 50, col: 18}]); tmp177 = 'clear';  _aether.logStatement([{ofs: 1980, row: 50, col: 11}, {ofs: 1987, row: 50, col: 18}], _aether._userInfo, false);\n            return _aether.restoreAPIClone(_aether, tmp177);\n        };  _aether.logStatement([{ofs: 974, row: 29, col: 0}, {ofs: 2278, row: 59, col: 0}], _aether._userInfo, false);\n        _aether.logStatementStart([{ofs: 974, row: 29, col: 0}, {ofs: 1990, row: 51, col: 1}]); tmp48[tmp49] = tmp50;  _aether.logStatement([{ofs: 974, row: 29, col: 0}, {ofs: 1990, row: 51, col: 1}], _aether._userInfo, false);\n        tmp178 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n        tmp179 = 'attackLow';\n        _aether.logStatementStart([{ofs: 2278, row: 59, col: 0}, {ofs: 3395, row: 95, col: 0}]); tmp180 = function (attackLoc, saying) {\n            var lowHealth, enemies, enemy, e, evadeState, tmp181, tmp182, tmp183, tmp209, tmp210, tmp211, tmp212, tmp213, tmp214, tmp215, tmp216, tmp217, tmp218, tmp219, tmp220, tmp221, tmp222, tmp225, tmp226, tmp227, tmp228, tmp229, tmp230, tmp231, tmp232, tmp233, tmp234, tmp235, tmp236, tmp237, tmp238, tmp239, tmp240, tmp241, tmp242, tmp243, tmp244, tmp245, tmp246, tmp247, tmp248, tmp249, tmp250, tmp251, tmp252, tmp253, tmp254, tmp255, tmp256, tmp257, tmp258, tmp259, tmp260, tmp261, tmp262, tmp263, tmp264, tmp265, tmp266, tmp267, tmp268, tmp269, tmp270, tmp271, tmp272; attackLoc = _aether.createAPIClone(_aether, attackLoc); saying = _aether.createAPIClone(_aether, saying); for(var __argIndexer = 0; __argIndexer < arguments.length; ++__argIndexer) arguments[__argIndexer] = _aether.createAPIClone(_aether, arguments[__argIndexer]);\n            tmp181 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n            tmp182 = 'attackLowMove';\n            _aether.logStatementStart([{ofs: 2329, row: 60, col: 4}, {ofs: 2591, row: 70, col: 4}]); tmp183 = function () {\n                var tmp184, tmp185, tmp186, tmp187, tmp188, tmp189, tmp190, tmp191, tmp192, tmp193, tmp194, tmp195, tmp196, tmp197, tmp198, tmp199, tmp200, tmp201, tmp202, tmp203, tmp204, tmp205, tmp206, tmp207, tmp208;  for(var __argIndexer = 0; __argIndexer < arguments.length; ++__argIndexer) arguments[__argIndexer] = _aether.createAPIClone(_aether, arguments[__argIndexer]);\n                tmp188 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n                tmp189 = 'evade';\n                _aether.logStatementStart([{ofs: 2375, row: 61, col: 12}, {ofs: 2387, row: 61, col: 24}]); tmp186 = _aether.createAPIClone(_aether, tmp188[tmp189]());  _aether.logStatement([{ofs: 2375, row: 61, col: 12}, {ofs: 2387, row: 61, col: 24}], _aether._userInfo, false);\n                _aether.logStatementStart([{ofs: 2391, row: 61, col: 28}, {ofs: 2398, row: 61, col: 35}]); tmp187 = 'clear';  _aether.logStatement([{ofs: 2391, row: 61, col: 28}, {ofs: 2398, row: 61, col: 35}], _aether._userInfo, false);\n                _aether.logStatementStart([{ofs: 2375, row: 61, col: 12}, {ofs: 2398, row: 61, col: 35}]); tmp185 = tmp186 == tmp187;  _aether.logStatement([{ofs: 2375, row: 61, col: 12}, {ofs: 2398, row: 61, col: 35}], _aether._userInfo, false);\n                if (tmp185) {\n                    tmp192 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n                    tmp193 = 'now';\n                    _aether.logStatementStart([{ofs: 2402, row: 61, col: 39}, {ofs: 2412, row: 61, col: 49}]); tmp190 = _aether.createAPIClone(_aether, tmp192[tmp193]());  _aether.logStatement([{ofs: 2402, row: 61, col: 39}, {ofs: 2412, row: 61, col: 49}], _aether._userInfo, false);\n                    _aether.logStatementStart([{ofs: 2415, row: 61, col: 52}, {ofs: 2416, row: 61, col: 53}]); tmp191 = 4;  _aether.logStatement([{ofs: 2415, row: 61, col: 52}, {ofs: 2416, row: 61, col: 53}], _aether._userInfo, false);\n                    _aether.logStatementStart([{ofs: 2402, row: 61, col: 39}, {ofs: 2416, row: 61, col: 53}]); tmp184 = tmp190 > tmp191;  _aether.logStatement([{ofs: 2402, row: 61, col: 39}, {ofs: 2416, row: 61, col: 53}], _aether._userInfo, false);\n                } else {\n                    _aether.logStatementStart([{ofs: 2375, row: 61, col: 12}, {ofs: 2416, row: 61, col: 53}]); tmp184 = tmp185;  _aether.logStatement([{ofs: 2375, row: 61, col: 12}, {ofs: 2416, row: 61, col: 53}], _aether._userInfo, false);\n                }\n                if (tmp184) {\n                    tmp197 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n                    tmp198 = 'now';\n                    _aether.logStatementStart([{ofs: 2436, row: 62, col: 16}, {ofs: 2446, row: 62, col: 26}]); tmp195 = _aether.createAPIClone(_aether, tmp197[tmp198]());  _aether.logStatement([{ofs: 2436, row: 62, col: 16}, {ofs: 2446, row: 62, col: 26}], _aether._userInfo, false);\n                    _aether.logStatementStart([{ofs: 2449, row: 62, col: 29}, {ofs: 2451, row: 62, col: 31}]); tmp196 = 15;  _aether.logStatement([{ofs: 2449, row: 62, col: 29}, {ofs: 2451, row: 62, col: 31}], _aether._userInfo, false);\n                    _aether.logStatementStart([{ofs: 2436, row: 62, col: 16}, {ofs: 2451, row: 62, col: 31}]); tmp194 = tmp195 < tmp196;  _aether.logStatement([{ofs: 2436, row: 62, col: 16}, {ofs: 2451, row: 62, col: 31}], _aether._userInfo, false);\n                    if (tmp194) {\n                        tmp199 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n                        tmp200 = 'move';\n                        _aether.logStatementStart([{ofs: 2485, row: 63, col: 30}, {ofs: 2487, row: 63, col: 32}]); tmp202 = 68;  _aether.logStatement([{ofs: 2485, row: 63, col: 30}, {ofs: 2487, row: 63, col: 32}], _aether._userInfo, false);\n                        _aether.logStatementStart([{ofs: 2492, row: 63, col: 37}, {ofs: 2493, row: 63, col: 38}]); tmp203 = 8;  _aether.logStatement([{ofs: 2492, row: 63, col: 37}, {ofs: 2493, row: 63, col: 38}], _aether._userInfo, false);\n                        _aether.logStatementStart([{ofs: 2481, row: 63, col: 26}, {ofs: 2494, row: 63, col: 39}]); tmp201 = {\n                            x: tmp202,\n                            y: tmp203\n                        };  _aether.logStatement([{ofs: 2481, row: 63, col: 26}, {ofs: 2494, row: 63, col: 39}], _aether._userInfo, false);\n                        _aether.logStatementStart([{ofs: 2471, row: 63, col: 16}, {ofs: 2495, row: 63, col: 40}]); tmp204 = _aether.createAPIClone(_aether, tmp199[tmp200](_aether.restoreAPIClone(_aether, tmp201)));  _aether.logStatement([{ofs: 2471, row: 63, col: 16}, {ofs: 2495, row: 63, col: 40}], _aether._userInfo, false);\n                    } else {\n                        tmp205 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n                        tmp206 = 'move';\n                        tmp207 = attackLoc;\n                        _aether.logStatementStart([{ofs: 2534, row: 65, col: 16}, {ofs: 2554, row: 65, col: 36}]); tmp208 = _aether.createAPIClone(_aether, tmp205[tmp206](_aether.restoreAPIClone(_aether, tmp207)));  _aether.logStatement([{ofs: 2534, row: 65, col: 16}, {ofs: 2554, row: 65, col: 36}], _aether._userInfo, false);\n                    }\n                } else {\n                    ;\n                }\n                return;\n            };  _aether.logStatement([{ofs: 2329, row: 60, col: 4}, {ofs: 2591, row: 70, col: 4}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 2329, row: 60, col: 4}, {ofs: 2585, row: 68, col: 5}]); tmp181[tmp182] = tmp183;  _aether.logStatement([{ofs: 2329, row: 60, col: 4}, {ofs: 2585, row: 68, col: 5}], _aether._userInfo, false);\n            tmp209 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n            tmp210 = 'getEnemies';\n            _aether.logStatementStart([{ofs: 2657, row: 71, col: 4}, {ofs: 2685, row: 71, col: 32}]); enemies = _aether.createAPIClone(_aether, tmp209[tmp210]());  _aether.logStatement([{ofs: 2657, row: 71, col: 4}, {ofs: 2685, row: 71, col: 32}], _aether._userInfo, false);\n            tmp211 = enemies;\n            if (tmp211) {\n                _aether.logStatementStart([{ofs: 2713, row: 73, col: 8}, {ofs: 2734, row: 73, col: 29}]); lowHealth = 99999999;  _aether.logStatement([{ofs: 2713, row: 73, col: 8}, {ofs: 2734, row: 73, col: 29}], _aether._userInfo, false);\n                _aether.logStatementStart([{ofs: 2752, row: 74, col: 17}, {ofs: 2753, row: 74, col: 18}]); e = 0;  _aether.logStatement([{ofs: 2752, row: 74, col: 17}, {ofs: 2753, row: 74, col: 18}], _aether._userInfo, false);\n                tmp213 = e;\n                tmp215 = enemies;\n                tmp216 = 'length';\n                _aether.logStatementStart([{ofs: 2759, row: 74, col: 24}, {ofs: 2773, row: 74, col: 38}]); tmp214 = tmp215[tmp216];  _aether.logStatement([{ofs: 2759, row: 74, col: 24}, {ofs: 2773, row: 74, col: 38}], _aether._userInfo, false);\n                _aether.logStatementStart([{ofs: 2755, row: 74, col: 20}, {ofs: 2773, row: 74, col: 38}]); tmp212 = tmp213 < tmp214;  _aether.logStatement([{ofs: 2755, row: 74, col: 20}, {ofs: 2773, row: 74, col: 38}], _aether._userInfo, false);\n                tmp223: {\n                    while (tmp212) {\n                        tmp224: {\n                            tmp225 = enemies;\n                            tmp226 = e;\n                            _aether.logStatementStart([{ofs: 2794, row: 75, col: 12}, {ofs: 2813, row: 75, col: 31}]); enemy = tmp225[tmp226];  _aether.logStatement([{ofs: 2794, row: 75, col: 12}, {ofs: 2813, row: 75, col: 31}], _aether._userInfo, false);\n                            tmp231 = enemy;\n                            tmp232 = 'health';\n                            _aether.logStatementStart([{ofs: 2830, row: 76, col: 16}, {ofs: 2842, row: 76, col: 28}]); tmp229 = tmp231[tmp232];  _aether.logStatement([{ofs: 2830, row: 76, col: 16}, {ofs: 2842, row: 76, col: 28}], _aether._userInfo, false);\n                            _aether.logStatementStart([{ofs: 2845, row: 76, col: 31}, {ofs: 2846, row: 76, col: 32}]); tmp230 = 0;  _aether.logStatement([{ofs: 2845, row: 76, col: 31}, {ofs: 2846, row: 76, col: 32}], _aether._userInfo, false);\n                            _aether.logStatementStart([{ofs: 2830, row: 76, col: 16}, {ofs: 2846, row: 76, col: 32}]); tmp228 = tmp229 > tmp230;  _aether.logStatement([{ofs: 2830, row: 76, col: 16}, {ofs: 2846, row: 76, col: 32}], _aether._userInfo, false);\n                            if (tmp228) {\n                                tmp235 = enemy;\n                                tmp236 = 'health';\n                                _aether.logStatementStart([{ofs: 2850, row: 76, col: 36}, {ofs: 2862, row: 76, col: 48}]); tmp233 = tmp235[tmp236];  _aether.logStatement([{ofs: 2850, row: 76, col: 36}, {ofs: 2862, row: 76, col: 48}], _aether._userInfo, false);\n                                tmp234 = lowHealth;\n                                _aether.logStatementStart([{ofs: 2850, row: 76, col: 36}, {ofs: 2874, row: 76, col: 60}]); tmp227 = tmp233 < tmp234;  _aether.logStatement([{ofs: 2850, row: 76, col: 36}, {ofs: 2874, row: 76, col: 60}], _aether._userInfo, false);\n                            } else {\n                                _aether.logStatementStart([{ofs: 2830, row: 76, col: 16}, {ofs: 2874, row: 76, col: 60}]); tmp227 = tmp228;  _aether.logStatement([{ofs: 2830, row: 76, col: 16}, {ofs: 2874, row: 76, col: 60}], _aether._userInfo, false);\n                            }\n                            if (tmp227) {\n                                tmp237 = enemy;\n                                tmp238 = 'health';\n                                _aether.logStatementStart([{ofs: 2894, row: 77, col: 16}, {ofs: 2919, row: 77, col: 41}]); lowHealth = tmp237[tmp238];  _aether.logStatement([{ofs: 2894, row: 77, col: 16}, {ofs: 2919, row: 77, col: 41}], _aether._userInfo, false);\n                                tmp239 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n                                tmp240 = 'lowTarget';\n                                tmp241 = enemy;\n                                _aether.logStatementStart([{ofs: 2936, row: 78, col: 16}, {ofs: 2958, row: 78, col: 38}]); tmp239[tmp240] = tmp241;  _aether.logStatement([{ofs: 2936, row: 78, col: 16}, {ofs: 2958, row: 78, col: 38}], _aether._userInfo, false);\n                            } else {\n                                ;\n                            }\n                        }\n                        tmp221 = e;\n                        tmp222 = 1;\n                        e = tmp221 + tmp222;\n                        tmp217 = e;\n                        tmp219 = enemies;\n                        tmp220 = 'length';\n                        _aether.logStatementStart([{ofs: 2759, row: 74, col: 24}, {ofs: 2773, row: 74, col: 38}]); tmp218 = tmp219[tmp220];  _aether.logStatement([{ofs: 2759, row: 74, col: 24}, {ofs: 2773, row: 74, col: 38}], _aether._userInfo, false);\n                        _aether.logStatementStart([{ofs: 2755, row: 74, col: 20}, {ofs: 2773, row: 74, col: 38}]); tmp212 = tmp217 < tmp218;  _aether.logStatement([{ofs: 2755, row: 74, col: 20}, {ofs: 2773, row: 74, col: 38}], _aether._userInfo, false);\n                    }\n                }\n                tmp242 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n                tmp243 = 'evade';\n                _aether.logStatementStart([{ofs: 2992, row: 81, col: 8}, {ofs: 3018, row: 81, col: 34}]); evadeState = _aether.createAPIClone(_aether, tmp242[tmp243]());  _aether.logStatement([{ofs: 2992, row: 81, col: 8}, {ofs: 3018, row: 81, col: 34}], _aether._userInfo, false);\n                tmp247 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n                tmp248 = 'lowTarget';\n                _aether.logStatementStart([{ofs: 3031, row: 82, col: 12}, {ofs: 3045, row: 82, col: 26}]); tmp246 = tmp247[tmp248];  _aether.logStatement([{ofs: 3031, row: 82, col: 12}, {ofs: 3045, row: 82, col: 26}], _aether._userInfo, false);\n                if (tmp246) {\n                    tmp253 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n                    tmp254 = 'lowTarget';\n                    _aether.logStatementStart([{ofs: 3049, row: 82, col: 30}, {ofs: 3063, row: 82, col: 44}]); tmp251 = tmp253[tmp254];  _aether.logStatement([{ofs: 3049, row: 82, col: 30}, {ofs: 3063, row: 82, col: 44}], _aether._userInfo, false);\n                    tmp252 = 'health';\n                    _aether.logStatementStart([{ofs: 3049, row: 82, col: 30}, {ofs: 3070, row: 82, col: 51}]); tmp249 = tmp251[tmp252];  _aether.logStatement([{ofs: 3049, row: 82, col: 30}, {ofs: 3070, row: 82, col: 51}], _aether._userInfo, false);\n                    _aether.logStatementStart([{ofs: 3073, row: 82, col: 54}, {ofs: 3074, row: 82, col: 55}]); tmp250 = 0;  _aether.logStatement([{ofs: 3073, row: 82, col: 54}, {ofs: 3074, row: 82, col: 55}], _aether._userInfo, false);\n                    _aether.logStatementStart([{ofs: 3049, row: 82, col: 30}, {ofs: 3074, row: 82, col: 55}]); tmp245 = tmp249 > tmp250;  _aether.logStatement([{ofs: 3049, row: 82, col: 30}, {ofs: 3074, row: 82, col: 55}], _aether._userInfo, false);\n                } else {\n                    _aether.logStatementStart([{ofs: 3031, row: 82, col: 12}, {ofs: 3074, row: 82, col: 55}]); tmp245 = tmp246;  _aether.logStatement([{ofs: 3031, row: 82, col: 12}, {ofs: 3074, row: 82, col: 55}], _aether._userInfo, false);\n                }\n                if (tmp245) {\n                    tmp255 = evadeState;\n                    _aether.logStatementStart([{ofs: 3092, row: 82, col: 73}, {ofs: 3099, row: 82, col: 80}]); tmp256 = 'clear';  _aether.logStatement([{ofs: 3092, row: 82, col: 73}, {ofs: 3099, row: 82, col: 80}], _aether._userInfo, false);\n                    _aether.logStatementStart([{ofs: 3078, row: 82, col: 59}, {ofs: 3099, row: 82, col: 80}]); tmp244 = tmp255 == tmp256;  _aether.logStatement([{ofs: 3078, row: 82, col: 59}, {ofs: 3099, row: 82, col: 80}], _aether._userInfo, false);\n                } else {\n                    _aether.logStatementStart([{ofs: 3031, row: 82, col: 12}, {ofs: 3099, row: 82, col: 80}]); tmp244 = tmp245;  _aether.logStatement([{ofs: 3031, row: 82, col: 12}, {ofs: 3099, row: 82, col: 80}], _aether._userInfo, false);\n                }\n                if (tmp244) {\n                    tmp257 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n                    tmp258 = 'say';\n                    tmp259 = saying;\n                    _aether.logStatementStart([{ofs: 3115, row: 83, col: 12}, {ofs: 3131, row: 83, col: 28}]); tmp260 = _aether.createAPIClone(_aether, tmp257[tmp258](_aether.restoreAPIClone(_aether, tmp259)));  _aether.logStatement([{ofs: 3115, row: 83, col: 12}, {ofs: 3131, row: 83, col: 28}], _aether._userInfo, false);\n                    tmp261 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n                    tmp262 = 'attack';\n                    tmp264 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n                    tmp265 = 'lowTarget';\n                    _aether.logStatementStart([{ofs: 3157, row: 84, col: 24}, {ofs: 3171, row: 84, col: 38}]); tmp263 = tmp264[tmp265];  _aether.logStatement([{ofs: 3157, row: 84, col: 24}, {ofs: 3171, row: 84, col: 38}], _aether._userInfo, false);\n                    _aether.logStatementStart([{ofs: 3145, row: 84, col: 12}, {ofs: 3172, row: 84, col: 39}]); tmp266 = _aether.createAPIClone(_aether, tmp261[tmp262](_aether.restoreAPIClone(_aether, tmp263)));  _aether.logStatement([{ofs: 3145, row: 84, col: 12}, {ofs: 3172, row: 84, col: 39}], _aether._userInfo, false);\n                } else {\n                    tmp267 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n                    tmp268 = 'attackLowMove';\n                    _aether.logStatementStart([{ofs: 3203, row: 86, col: 12}, {ofs: 3223, row: 86, col: 32}]); tmp269 = _aether.createAPIClone(_aether, tmp267[tmp268]());  _aether.logStatement([{ofs: 3203, row: 86, col: 12}, {ofs: 3223, row: 86, col: 32}], _aether._userInfo, false);\n                }\n            } else {\n                tmp270 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n                tmp271 = 'attackLowMove';\n                _aether.logStatementStart([{ofs: 3256, row: 89, col: 8}, {ofs: 3276, row: 89, col: 28}]); tmp272 = _aether.createAPIClone(_aether, tmp270[tmp271]());  _aether.logStatement([{ofs: 3256, row: 89, col: 8}, {ofs: 3276, row: 89, col: 28}], _aether._userInfo, false);\n            }\n            return;\n        };  _aether.logStatement([{ofs: 2278, row: 59, col: 0}, {ofs: 3395, row: 95, col: 0}], _aether._userInfo, false);\n        _aether.logStatementStart([{ofs: 2278, row: 59, col: 0}, {ofs: 3285, row: 91, col: 1}]); tmp178[tmp179] = tmp180;  _aether.logStatement([{ofs: 2278, row: 59, col: 0}, {ofs: 3285, row: 91, col: 1}], _aether._userInfo, false);\n        tmp278 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n        tmp279 = 'buildIndex';\n        _aether.logStatementStart([{ofs: 3399, row: 95, col: 4}, {ofs: 3414, row: 95, col: 19}]); tmp276 = tmp278[tmp279];  _aether.logStatement([{ofs: 3399, row: 95, col: 4}, {ofs: 3414, row: 95, col: 19}], _aether._userInfo, false);\n        _aether.logStatementStart([{ofs: 3418, row: 95, col: 23}, {ofs: 3419, row: 95, col: 24}]); tmp277 = 1;  _aether.logStatement([{ofs: 3418, row: 95, col: 23}, {ofs: 3419, row: 95, col: 24}], _aether._userInfo, false);\n        _aether.logStatementStart([{ofs: 3399, row: 95, col: 4}, {ofs: 3419, row: 95, col: 24}]); tmp275 = tmp276 == tmp277;  _aether.logStatement([{ofs: 3399, row: 95, col: 4}, {ofs: 3419, row: 95, col: 24}], _aether._userInfo, false);\n        if (tmp275) {\n            tmp282 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n            tmp283 = 'now';\n            _aether.logStatementStart([{ofs: 3423, row: 95, col: 28}, {ofs: 3433, row: 95, col: 38}]); tmp280 = _aether.createAPIClone(_aether, tmp282[tmp283]());  _aether.logStatement([{ofs: 3423, row: 95, col: 28}, {ofs: 3433, row: 95, col: 38}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 3436, row: 95, col: 41}, {ofs: 3437, row: 95, col: 42}]); tmp281 = 9;  _aether.logStatement([{ofs: 3436, row: 95, col: 41}, {ofs: 3437, row: 95, col: 42}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 3423, row: 95, col: 28}, {ofs: 3437, row: 95, col: 42}]); tmp274 = tmp280 < tmp281;  _aether.logStatement([{ofs: 3423, row: 95, col: 28}, {ofs: 3437, row: 95, col: 42}], _aether._userInfo, false);\n        } else {\n            _aether.logStatementStart([{ofs: 3399, row: 95, col: 4}, {ofs: 3437, row: 95, col: 42}]); tmp274 = tmp275;  _aether.logStatement([{ofs: 3399, row: 95, col: 4}, {ofs: 3437, row: 95, col: 42}], _aether._userInfo, false);\n        }\n        if (tmp274) {\n            tmp288 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n            tmp289 = 'getItems';\n            _aether.logStatementStart([{ofs: 3441, row: 95, col: 46}, {ofs: 3456, row: 95, col: 61}]); tmp286 = _aether.createAPIClone(_aether, tmp288[tmp289]());  _aether.logStatement([{ofs: 3441, row: 95, col: 46}, {ofs: 3456, row: 95, col: 61}], _aether._userInfo, false);\n            tmp287 = 'length';\n            _aether.logStatementStart([{ofs: 3441, row: 95, col: 46}, {ofs: 3463, row: 95, col: 68}]); tmp284 = tmp286[tmp287];  _aether.logStatement([{ofs: 3441, row: 95, col: 46}, {ofs: 3463, row: 95, col: 68}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 3466, row: 95, col: 71}, {ofs: 3467, row: 95, col: 72}]); tmp285 = 0;  _aether.logStatement([{ofs: 3466, row: 95, col: 71}, {ofs: 3467, row: 95, col: 72}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 3441, row: 95, col: 46}, {ofs: 3467, row: 95, col: 72}]); tmp273 = tmp284 > tmp285;  _aether.logStatement([{ofs: 3441, row: 95, col: 46}, {ofs: 3467, row: 95, col: 72}], _aether._userInfo, false);\n        } else {\n            _aether.logStatementStart([{ofs: 3399, row: 95, col: 4}, {ofs: 3467, row: 95, col: 72}]); tmp273 = tmp274;  _aether.logStatement([{ofs: 3399, row: 95, col: 4}, {ofs: 3467, row: 95, col: 72}], _aether._userInfo, false);\n        }\n        if (tmp273) {\n            tmp290 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n            tmp291 = 'move';\n            _aether.logStatementStart([{ofs: 3489, row: 96, col: 18}, {ofs: 3491, row: 96, col: 20}]); tmp293 = 13;  _aether.logStatement([{ofs: 3489, row: 96, col: 18}, {ofs: 3491, row: 96, col: 20}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 3496, row: 96, col: 25}, {ofs: 3498, row: 96, col: 27}]); tmp294 = 15;  _aether.logStatement([{ofs: 3496, row: 96, col: 25}, {ofs: 3498, row: 96, col: 27}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 3485, row: 96, col: 14}, {ofs: 3499, row: 96, col: 28}]); tmp292 = {\n                x: tmp293,\n                y: tmp294\n            };  _aether.logStatement([{ofs: 3485, row: 96, col: 14}, {ofs: 3499, row: 96, col: 28}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 3475, row: 96, col: 4}, {ofs: 3500, row: 96, col: 29}]); tmp295 = _aether.createAPIClone(_aether, tmp290[tmp291](_aether.restoreAPIClone(_aether, tmp292)));  _aether.logStatement([{ofs: 3475, row: 96, col: 4}, {ofs: 3500, row: 96, col: 29}], _aether._userInfo, false);\n            tmp296 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n            tmp297 = 'getGold';\n            _aether.logStatementStart([{ofs: 3519, row: 97, col: 17}, {ofs: 3525, row: 97, col: 23}]); tmp298 = 'left';  _aether.logStatement([{ofs: 3519, row: 97, col: 17}, {ofs: 3525, row: 97, col: 23}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 3527, row: 97, col: 25}, {ofs: 3553, row: 97, col: 51}]); tmp299 = 'I\\'m feeling just golden!';  _aether.logStatement([{ofs: 3527, row: 97, col: 25}, {ofs: 3553, row: 97, col: 51}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 3506, row: 97, col: 4}, {ofs: 3554, row: 97, col: 52}]); tmp300 = _aether.createAPIClone(_aether, tmp296[tmp297](_aether.restoreAPIClone(_aether, tmp298), _aether.restoreAPIClone(_aether, tmp299)));  _aether.logStatement([{ofs: 3506, row: 97, col: 4}, {ofs: 3554, row: 97, col: 52}], _aether._userInfo, false);\n        } else {\n            tmp306 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n            tmp307 = 'buildIndex';\n            _aether.logStatementStart([{ofs: 3567, row: 98, col: 11}, {ofs: 3582, row: 98, col: 26}]); tmp304 = tmp306[tmp307];  _aether.logStatement([{ofs: 3567, row: 98, col: 11}, {ofs: 3582, row: 98, col: 26}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 3586, row: 98, col: 30}, {ofs: 3587, row: 98, col: 31}]); tmp305 = 0;  _aether.logStatement([{ofs: 3586, row: 98, col: 30}, {ofs: 3587, row: 98, col: 31}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 3567, row: 98, col: 11}, {ofs: 3587, row: 98, col: 31}]); tmp303 = tmp304 == tmp305;  _aether.logStatement([{ofs: 3567, row: 98, col: 11}, {ofs: 3587, row: 98, col: 31}], _aether._userInfo, false);\n            if (tmp303) {\n                tmp310 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n                tmp311 = 'now';\n                _aether.logStatementStart([{ofs: 3591, row: 98, col: 35}, {ofs: 3601, row: 98, col: 45}]); tmp308 = _aether.createAPIClone(_aether, tmp310[tmp311]());  _aether.logStatement([{ofs: 3591, row: 98, col: 35}, {ofs: 3601, row: 98, col: 45}], _aether._userInfo, false);\n                _aether.logStatementStart([{ofs: 3604, row: 98, col: 48}, {ofs: 3605, row: 98, col: 49}]); tmp309 = 9;  _aether.logStatement([{ofs: 3604, row: 98, col: 48}, {ofs: 3605, row: 98, col: 49}], _aether._userInfo, false);\n                _aether.logStatementStart([{ofs: 3591, row: 98, col: 35}, {ofs: 3605, row: 98, col: 49}]); tmp302 = tmp308 < tmp309;  _aether.logStatement([{ofs: 3591, row: 98, col: 35}, {ofs: 3605, row: 98, col: 49}], _aether._userInfo, false);\n            } else {\n                _aether.logStatementStart([{ofs: 3567, row: 98, col: 11}, {ofs: 3605, row: 98, col: 49}]); tmp302 = tmp303;  _aether.logStatement([{ofs: 3567, row: 98, col: 11}, {ofs: 3605, row: 98, col: 49}], _aether._userInfo, false);\n            }\n            if (tmp302) {\n                tmp316 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n                tmp317 = 'getItems';\n                _aether.logStatementStart([{ofs: 3609, row: 98, col: 53}, {ofs: 3624, row: 98, col: 68}]); tmp314 = _aether.createAPIClone(_aether, tmp316[tmp317]());  _aether.logStatement([{ofs: 3609, row: 98, col: 53}, {ofs: 3624, row: 98, col: 68}], _aether._userInfo, false);\n                tmp315 = 'length';\n                _aether.logStatementStart([{ofs: 3609, row: 98, col: 53}, {ofs: 3631, row: 98, col: 75}]); tmp312 = tmp314[tmp315];  _aether.logStatement([{ofs: 3609, row: 98, col: 53}, {ofs: 3631, row: 98, col: 75}], _aether._userInfo, false);\n                _aether.logStatementStart([{ofs: 3634, row: 98, col: 78}, {ofs: 3635, row: 98, col: 79}]); tmp313 = 0;  _aether.logStatement([{ofs: 3634, row: 98, col: 78}, {ofs: 3635, row: 98, col: 79}], _aether._userInfo, false);\n                _aether.logStatementStart([{ofs: 3609, row: 98, col: 53}, {ofs: 3635, row: 98, col: 79}]); tmp301 = tmp312 > tmp313;  _aether.logStatement([{ofs: 3609, row: 98, col: 53}, {ofs: 3635, row: 98, col: 79}], _aether._userInfo, false);\n            } else {\n                _aether.logStatementStart([{ofs: 3567, row: 98, col: 11}, {ofs: 3635, row: 98, col: 79}]); tmp301 = tmp302;  _aether.logStatement([{ofs: 3567, row: 98, col: 11}, {ofs: 3635, row: 98, col: 79}], _aether._userInfo, false);\n            }\n            if (tmp301) {\n                tmp318 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n                tmp319 = 'move';\n                _aether.logStatementStart([{ofs: 3657, row: 99, col: 18}, {ofs: 3659, row: 99, col: 20}]); tmp321 = 74;  _aether.logStatement([{ofs: 3657, row: 99, col: 18}, {ofs: 3659, row: 99, col: 20}], _aether._userInfo, false);\n                _aether.logStatementStart([{ofs: 3664, row: 99, col: 25}, {ofs: 3666, row: 99, col: 27}]); tmp322 = 30;  _aether.logStatement([{ofs: 3664, row: 99, col: 25}, {ofs: 3666, row: 99, col: 27}], _aether._userInfo, false);\n                _aether.logStatementStart([{ofs: 3653, row: 99, col: 14}, {ofs: 3667, row: 99, col: 28}]); tmp320 = {\n                    x: tmp321,\n                    y: tmp322\n                };  _aether.logStatement([{ofs: 3653, row: 99, col: 14}, {ofs: 3667, row: 99, col: 28}], _aether._userInfo, false);\n                _aether.logStatementStart([{ofs: 3643, row: 99, col: 4}, {ofs: 3668, row: 99, col: 29}]); tmp323 = _aether.createAPIClone(_aether, tmp318[tmp319](_aether.restoreAPIClone(_aether, tmp320)));  _aether.logStatement([{ofs: 3643, row: 99, col: 4}, {ofs: 3668, row: 99, col: 29}], _aether._userInfo, false);\n                tmp324 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n                tmp325 = 'getGold';\n                _aether.logStatementStart([{ofs: 3687, row: 100, col: 17}, {ofs: 3694, row: 100, col: 24}]); tmp326 = 'right';  _aether.logStatement([{ofs: 3687, row: 100, col: 17}, {ofs: 3694, row: 100, col: 24}], _aether._userInfo, false);\n                _aether.logStatementStart([{ofs: 3696, row: 100, col: 26}, {ofs: 3726, row: 100, col: 56}]); tmp327 = 'I\\'m feeling just golden too!';  _aether.logStatement([{ofs: 3696, row: 100, col: 26}, {ofs: 3726, row: 100, col: 56}], _aether._userInfo, false);\n                _aether.logStatementStart([{ofs: 3674, row: 100, col: 4}, {ofs: 3727, row: 100, col: 57}]); tmp328 = _aether.createAPIClone(_aether, tmp324[tmp325](_aether.restoreAPIClone(_aether, tmp326), _aether.restoreAPIClone(_aether, tmp327)));  _aether.logStatement([{ofs: 3674, row: 100, col: 4}, {ofs: 3727, row: 100, col: 57}], _aether._userInfo, false);\n            } else {\n                tmp329 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n                tmp330 = 'attackLow';\n                _aether.logStatementStart([{ofs: 3761, row: 102, col: 23}, {ofs: 3763, row: 102, col: 25}]); tmp333 = 70;  _aether.logStatement([{ofs: 3761, row: 102, col: 23}, {ofs: 3763, row: 102, col: 25}], _aether._userInfo, false);\n                _aether.logStatementStart([{ofs: 3768, row: 102, col: 30}, {ofs: 3770, row: 102, col: 32}]); tmp334 = 70;  _aether.logStatement([{ofs: 3768, row: 102, col: 30}, {ofs: 3770, row: 102, col: 32}], _aether._userInfo, false);\n                _aether.logStatementStart([{ofs: 3757, row: 102, col: 19}, {ofs: 3771, row: 102, col: 33}]); tmp331 = {\n                    x: tmp333,\n                    y: tmp334\n                };  _aether.logStatement([{ofs: 3757, row: 102, col: 19}, {ofs: 3771, row: 102, col: 33}], _aether._userInfo, false);\n                _aether.logStatementStart([{ofs: 3773, row: 102, col: 35}, {ofs: 3777, row: 102, col: 39}]); tmp332 = ':)';  _aether.logStatement([{ofs: 3773, row: 102, col: 35}, {ofs: 3777, row: 102, col: 39}], _aether._userInfo, false);\n                _aether.logStatementStart([{ofs: 3742, row: 102, col: 4}, {ofs: 3778, row: 102, col: 40}]); tmp335 = _aether.createAPIClone(_aether, tmp329[tmp330](_aether.restoreAPIClone(_aether, tmp331), _aether.restoreAPIClone(_aether, tmp332)));  _aether.logStatement([{ofs: 3742, row: 102, col: 4}, {ofs: 3778, row: 102, col: 40}], _aether._userInfo, false);\n            }\n        }\n        _aether.logCallEnd(); return;\n    };\n    tmp0 = 'chooseAction';\n    __global[tmp0] = tmp1;\n}(this));",
+          "hear": "var __interceptThis=(function(){var G=this;return function($this,sandbox){if($this==G){return sandbox;}return $this;};})();\nreturn (function (__global) {\n    var tmp0, tmp1;\n    tmp1 = function (speaker, message, data) {\n        'use strict'; _aether.logCallStart(_aether._userInfo); var tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8; speaker = _aether.createAPIClone(_aether, speaker); message = _aether.createAPIClone(_aether, message); data = _aether.createAPIClone(_aether, data); for(var __argIndexer = 0; __argIndexer < arguments.length; ++__argIndexer) arguments[__argIndexer] = _aether.createAPIClone(_aether, arguments[__argIndexer]);\n        tmp5 = speaker;\n        tmp6 = 'team';\n        _aether.logStatementStart([{ofs: 80, row: 1, col: 3}, {ofs: 92, row: 1, col: 15}]); tmp3 = tmp5[tmp6];  _aether.logStatement([{ofs: 80, row: 1, col: 3}, {ofs: 92, row: 1, col: 15}], _aether._userInfo, false);\n        tmp7 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n        tmp8 = 'team';\n        _aether.logStatementStart([{ofs: 97, row: 1, col: 20}, {ofs: 106, row: 1, col: 29}]); tmp4 = tmp7[tmp8];  _aether.logStatement([{ofs: 97, row: 1, col: 20}, {ofs: 106, row: 1, col: 29}], _aether._userInfo, false);\n        _aether.logStatementStart([{ofs: 80, row: 1, col: 3}, {ofs: 106, row: 1, col: 29}]); tmp2 = tmp3 !== tmp4;  _aether.logStatement([{ofs: 80, row: 1, col: 3}, {ofs: 106, row: 1, col: 29}], _aether._userInfo, false);\n        if (tmp2) {\n            _aether.logCallEnd(); return;\n        } else {\n            ;\n        }\n        _aether.logCallEnd(); return;\n    };\n    tmp0 = 'hear';\n    __global[tmp0] = tmp1;\n}(this));"
+        },
+        "human-base": {
+          "chooseAction": "var __interceptThis=(function(){var G=this;return function($this,sandbox){if($this==G){return sandbox;}return $this;};})();\nreturn (function (__global) {\n    var tmp0, tmp1;\n    tmp1 = function () {\n        'use strict'; _aether.logCallStart(_aether._userInfo); var type, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8, tmp9, tmp10, tmp11, tmp12, tmp13, tmp14, tmp15, tmp16, tmp17, tmp18, tmp19, tmp20, tmp21, tmp22, tmp23, tmp24, tmp25, tmp26, tmp27, tmp28, tmp29, tmp30, tmp31, tmp32, tmp33, tmp34, tmp35, tmp36, tmp37, tmp38, tmp39, tmp40, tmp41, tmp42, tmp43, tmp44, tmp45, tmp46, tmp47, tmp48;  for(var __argIndexer = 0; __argIndexer < arguments.length; ++__argIndexer) arguments[__argIndexer] = _aether.createAPIClone(_aether, arguments[__argIndexer]);\n        tmp5 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n        tmp6 = 'cannonNum';\n        _aether.logStatementStart([{ofs: 266, row: 7, col: 5}, {ofs: 280, row: 7, col: 19}]); tmp4 = tmp5[tmp6];  _aether.logStatement([{ofs: 266, row: 7, col: 5}, {ofs: 280, row: 7, col: 19}], _aether._userInfo, false);\n        _aether.logStatementStart([{ofs: 265, row: 7, col: 4}, {ofs: 280, row: 7, col: 19}]); tmp3 = !tmp4;  _aether.logStatement([{ofs: 265, row: 7, col: 4}, {ofs: 280, row: 7, col: 19}], _aether._userInfo, false);\n        if (tmp3) {\n            tmp8 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n            tmp9 = 'goldRushNum';\n            _aether.logStatementStart([{ofs: 285, row: 7, col: 24}, {ofs: 301, row: 7, col: 40}]); tmp7 = tmp8[tmp9];  _aether.logStatement([{ofs: 285, row: 7, col: 24}, {ofs: 301, row: 7, col: 40}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 284, row: 7, col: 23}, {ofs: 301, row: 7, col: 40}]); tmp2 = !tmp7;  _aether.logStatement([{ofs: 284, row: 7, col: 23}, {ofs: 301, row: 7, col: 40}], _aether._userInfo, false);\n        } else {\n            _aether.logStatementStart([{ofs: 265, row: 7, col: 4}, {ofs: 301, row: 7, col: 40}]); tmp2 = tmp3;  _aether.logStatement([{ofs: 265, row: 7, col: 4}, {ofs: 301, row: 7, col: 40}], _aether._userInfo, false);\n        }\n        if (tmp2) {\n            tmp10 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n            tmp11 = 'cannonNum';\n            _aether.logStatementStart([{ofs: 309, row: 8, col: 4}, {ofs: 328, row: 8, col: 23}]); tmp12 = 0;  _aether.logStatement([{ofs: 309, row: 8, col: 4}, {ofs: 328, row: 8, col: 23}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 309, row: 8, col: 4}, {ofs: 327, row: 8, col: 22}]); tmp10[tmp11] = tmp12;  _aether.logStatement([{ofs: 309, row: 8, col: 4}, {ofs: 327, row: 8, col: 22}], _aether._userInfo, false);\n            tmp13 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n            tmp14 = 'goldRushNum';\n            _aether.logStatementStart([{ofs: 333, row: 9, col: 4}, {ofs: 354, row: 9, col: 25}]); tmp15 = 0;  _aether.logStatement([{ofs: 333, row: 9, col: 4}, {ofs: 354, row: 9, col: 25}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 333, row: 9, col: 4}, {ofs: 353, row: 9, col: 24}]); tmp13[tmp14] = tmp15;  _aether.logStatement([{ofs: 333, row: 9, col: 4}, {ofs: 353, row: 9, col: 24}], _aether._userInfo, false);\n        } else {\n            ;\n        }\n        _aether.logStatementStart([{ofs: 426, row: 14, col: 0}, {ofs: 446, row: 14, col: 20}]); type = 'archer';  _aether.logStatement([{ofs: 426, row: 14, col: 0}, {ofs: 446, row: 14, col: 20}], _aether._userInfo, false);\n        tmp19 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n        tmp20 = 'goldRushNum';\n        _aether.logStatementStart([{ofs: 659, row: 24, col: 3}, {ofs: 675, row: 24, col: 19}]); tmp17 = tmp19[tmp20];  _aether.logStatement([{ofs: 659, row: 24, col: 3}, {ofs: 675, row: 24, col: 19}], _aether._userInfo, false);\n        _aether.logStatementStart([{ofs: 678, row: 24, col: 22}, {ofs: 679, row: 24, col: 23}]); tmp18 = 3;  _aether.logStatement([{ofs: 678, row: 24, col: 22}, {ofs: 679, row: 24, col: 23}], _aether._userInfo, false);\n        _aether.logStatementStart([{ofs: 659, row: 24, col: 3}, {ofs: 679, row: 24, col: 23}]); tmp16 = tmp17 < tmp18;  _aether.logStatement([{ofs: 659, row: 24, col: 3}, {ofs: 679, row: 24, col: 23}], _aether._userInfo, false);\n        if (tmp16) {\n            _aether.logStatementStart([{ofs: 687, row: 25, col: 4}, {ofs: 703, row: 25, col: 20}]); type = 'archer';  _aether.logStatement([{ofs: 687, row: 25, col: 4}, {ofs: 703, row: 25, col: 20}], _aether._userInfo, false);\n            tmp21 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n            tmp22 = 'goldRushNum';\n            tmp26 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n            tmp27 = 'goldRushNum';\n            _aether.logStatementStart([{ofs: 727, row: 26, col: 23}, {ofs: 743, row: 26, col: 39}]); tmp24 = tmp26[tmp27];  _aether.logStatement([{ofs: 727, row: 26, col: 23}, {ofs: 743, row: 26, col: 39}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 746, row: 26, col: 42}, {ofs: 747, row: 26, col: 43}]); tmp25 = 1;  _aether.logStatement([{ofs: 746, row: 26, col: 42}, {ofs: 747, row: 26, col: 43}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 708, row: 26, col: 4}, {ofs: 748, row: 26, col: 44}]); tmp23 = tmp24 + tmp25;  _aether.logStatement([{ofs: 708, row: 26, col: 4}, {ofs: 748, row: 26, col: 44}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 708, row: 26, col: 4}, {ofs: 747, row: 26, col: 43}]); tmp21[tmp22] = tmp23;  _aether.logStatement([{ofs: 708, row: 26, col: 4}, {ofs: 747, row: 26, col: 43}], _aether._userInfo, false);\n        } else {\n            ;\n        }\n        tmp32 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n        tmp33 = 'cannonNum';\n        _aether.logStatementStart([{ofs: 814, row: 31, col: 3}, {ofs: 828, row: 31, col: 17}]); tmp30 = tmp32[tmp33];  _aether.logStatement([{ofs: 814, row: 31, col: 3}, {ofs: 828, row: 31, col: 17}], _aether._userInfo, false);\n        _aether.logStatementStart([{ofs: 831, row: 31, col: 20}, {ofs: 832, row: 31, col: 21}]); tmp31 = 1;  _aether.logStatement([{ofs: 831, row: 31, col: 20}, {ofs: 832, row: 31, col: 21}], _aether._userInfo, false);\n        _aether.logStatementStart([{ofs: 814, row: 31, col: 3}, {ofs: 832, row: 31, col: 21}]); tmp29 = tmp30 < tmp31;  _aether.logStatement([{ofs: 814, row: 31, col: 3}, {ofs: 832, row: 31, col: 21}], _aether._userInfo, false);\n        if (tmp29) {\n            tmp36 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n            tmp37 = 'goldRushNum';\n            _aether.logStatementStart([{ofs: 836, row: 31, col: 25}, {ofs: 852, row: 31, col: 41}]); tmp34 = tmp36[tmp37];  _aether.logStatement([{ofs: 836, row: 31, col: 25}, {ofs: 852, row: 31, col: 41}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 857, row: 31, col: 46}, {ofs: 858, row: 31, col: 47}]); tmp35 = 3;  _aether.logStatement([{ofs: 857, row: 31, col: 46}, {ofs: 858, row: 31, col: 47}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 836, row: 31, col: 25}, {ofs: 858, row: 31, col: 47}]); tmp28 = tmp34 === tmp35;  _aether.logStatement([{ofs: 836, row: 31, col: 25}, {ofs: 858, row: 31, col: 47}], _aether._userInfo, false);\n        } else {\n            _aether.logStatementStart([{ofs: 814, row: 31, col: 3}, {ofs: 858, row: 31, col: 47}]); tmp28 = tmp29;  _aether.logStatement([{ofs: 814, row: 31, col: 3}, {ofs: 858, row: 31, col: 47}], _aether._userInfo, false);\n        }\n        if (tmp28) {\n            _aether.logStatementStart([{ofs: 871, row: 32, col: 8}, {ofs: 890, row: 32, col: 27}]); type = 'artillery';  _aether.logStatement([{ofs: 871, row: 32, col: 8}, {ofs: 890, row: 32, col: 27}], _aether._userInfo, false);\n            tmp38 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n            tmp39 = 'cannonNum';\n            tmp43 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n            tmp44 = 'cannonNum';\n            _aether.logStatementStart([{ofs: 916, row: 33, col: 25}, {ofs: 930, row: 33, col: 39}]); tmp41 = tmp43[tmp44];  _aether.logStatement([{ofs: 916, row: 33, col: 25}, {ofs: 930, row: 33, col: 39}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 933, row: 33, col: 42}, {ofs: 934, row: 33, col: 43}]); tmp42 = 1;  _aether.logStatement([{ofs: 933, row: 33, col: 42}, {ofs: 934, row: 33, col: 43}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 899, row: 33, col: 8}, {ofs: 935, row: 33, col: 44}]); tmp40 = tmp41 + tmp42;  _aether.logStatement([{ofs: 899, row: 33, col: 8}, {ofs: 935, row: 33, col: 44}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 899, row: 33, col: 8}, {ofs: 934, row: 33, col: 43}]); tmp38[tmp39] = tmp40;  _aether.logStatement([{ofs: 899, row: 33, col: 8}, {ofs: 934, row: 33, col: 43}], _aether._userInfo, false);\n        } else {\n            ;\n        }\n        tmp45 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n        tmp46 = 'build';\n        tmp47 = type;\n        _aether.logStatementStart([{ofs: 1047, row: 38, col: 0}, {ofs: 1063, row: 38, col: 16}]); tmp48 = _aether.createAPIClone(_aether, tmp45[tmp46](_aether.restoreAPIClone(_aether, tmp47)));  _aether.logStatement([{ofs: 1047, row: 38, col: 0}, {ofs: 1063, row: 38, col: 16}], _aether._userInfo, false);\n        _aether.logCallEnd(); return;\n    };\n    tmp0 = 'chooseAction';\n    __global[tmp0] = tmp1;\n}(this));",
+          "hear": "var __interceptThis=(function(){var G=this;return function($this,sandbox){if($this==G){return sandbox;}return $this;};})();\nreturn (function (__global) {\n    var tmp0, tmp1;\n    tmp1 = function (speaker, message, data) {\n        'use strict'; _aether.logCallStart(_aether._userInfo); var tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8; speaker = _aether.createAPIClone(_aether, speaker); message = _aether.createAPIClone(_aether, message); data = _aether.createAPIClone(_aether, data); for(var __argIndexer = 0; __argIndexer < arguments.length; ++__argIndexer) arguments[__argIndexer] = _aether.createAPIClone(_aether, arguments[__argIndexer]);\n        tmp5 = speaker;\n        tmp6 = 'team';\n        _aether.logStatementStart([{ofs: 78, row: 1, col: 3}, {ofs: 90, row: 1, col: 15}]); tmp3 = tmp5[tmp6];  _aether.logStatement([{ofs: 78, row: 1, col: 3}, {ofs: 90, row: 1, col: 15}], _aether._userInfo, false);\n        tmp7 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n        tmp8 = 'team';\n        _aether.logStatementStart([{ofs: 95, row: 1, col: 20}, {ofs: 104, row: 1, col: 29}]); tmp4 = tmp7[tmp8];  _aether.logStatement([{ofs: 95, row: 1, col: 20}, {ofs: 104, row: 1, col: 29}], _aether._userInfo, false);\n        _aether.logStatementStart([{ofs: 78, row: 1, col: 3}, {ofs: 104, row: 1, col: 29}]); tmp2 = tmp3 !== tmp4;  _aether.logStatement([{ofs: 78, row: 1, col: 3}, {ofs: 104, row: 1, col: 29}], _aether._userInfo, false);\n        if (tmp2) {\n            _aether.logCallEnd(); return;\n        } else {\n            ;\n        }\n        _aether.logCallEnd(); return;\n    };\n    tmp0 = 'hear';\n    __global[tmp0] = tmp1;\n}(this));"
         }
       },
       "submittedCodeLanguage": "javascript",
-      "playtime": 107,
+      "playtime": 178,
       "codeLanguage": "javascript"
     },
     {
       "_id": "5317ad4909098828ed071f4d",
+      "level": {
+        "original": "53173f76c269d400000543c2",
+        "majorVersion": 0
+      },
       "team": "humans",
       "levelID": "dungeon-arena",
       "levelName": "Dungeon Arena",
@@ -511,18 +644,34 @@ responses =
           "chooseAction": "var enemies = this.getEnemies();\nvar enemy = this.getNearest(enemies);\nif (!this.getCooldown('warcry')) {\n    this.warcry();\n}\nelse if (enemy) {\n    this.attack(enemy);\n}\nelse {\n    this.move({x: 10, y: 30});\n}\n"
         },
         "tharin-1": {
-          "chooseAction": "..."
+          "chooseAction": "var __interceptThis=(function(){var G=this;return function($this,sandbox){if($this==G){return sandbox;}return $this;};})();\nreturn (function (__global) {\n    var tmp0, tmp1;\n    tmp1 = function () {\n        _aether.logCallStart(this._aetherUserInfo); var enemies, enemy, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8, tmp9, tmp10, tmp11, tmp12, tmp13, tmp14, tmp15, tmp16, tmp17, tmp18, tmp19, tmp20, tmp21, tmp22, tmp23, tmp24, tmp25, tmp26;\n        tmp2 = 'use strict';\n        tmp3 = __interceptThis(this, __global);\n        tmp4 = 'getEnemies';\n        _aether.logStatementStart([{ofs: 0, row: 0, col: 0}, {ofs: 32, row: 0, col: 32}]); enemies = tmp3[tmp4](); _aether.vars['enemies'] = typeof enemies == 'undefined' ? undefined : enemies; _aether.vars['enemy'] = typeof enemy == 'undefined' ? undefined : enemy; _aether.vars['chooseAction'] = typeof chooseAction == 'undefined' ? undefined : chooseAction; _aether.logStatement([{ofs: 0, row: 0, col: 0}, {ofs: 32, row: 0, col: 32}], \"var enemies = this.getEnemies();\", this._aetherUserInfo);\n        tmp5 = __interceptThis(this, __global);\n        tmp6 = 'getNearest';\n        tmp7 = enemies;\n        _aether.logStatementStart([{ofs: 33, row: 1, col: 0}, {ofs: 70, row: 1, col: 37}]); enemy = tmp5[tmp6](tmp7); _aether.vars['enemies'] = typeof enemies == 'undefined' ? undefined : enemies; _aether.vars['enemy'] = typeof enemy == 'undefined' ? undefined : enemy; _aether.vars['chooseAction'] = typeof chooseAction == 'undefined' ? undefined : chooseAction; _aether.logStatement([{ofs: 33, row: 1, col: 0}, {ofs: 70, row: 1, col: 37}], \"var enemy = this.getNearest(enemies);\", this._aetherUserInfo);\n        tmp10 = __interceptThis(this, __global);\n        tmp11 = 'getCooldown';\n        _aether.logStatementStart([{ofs: 93, row: 2, col: 22}, {ofs: 101, row: 2, col: 30}]); tmp12 = 'warcry'; _aether.vars['enemies'] = typeof enemies == 'undefined' ? undefined : enemies; _aether.vars['enemy'] = typeof enemy == 'undefined' ? undefined : enemy; _aether.vars['chooseAction'] = typeof chooseAction == 'undefined' ? undefined : chooseAction; _aether.logStatement([{ofs: 93, row: 2, col: 22}, {ofs: 101, row: 2, col: 30}], \"'warcry'\", this._aetherUserInfo);\n        _aether.logStatementStart([{ofs: 76, row: 2, col: 5}, {ofs: 102, row: 2, col: 31}]); tmp9 = tmp10[tmp11](tmp12); _aether.vars['enemies'] = typeof enemies == 'undefined' ? undefined : enemies; _aether.vars['enemy'] = typeof enemy == 'undefined' ? undefined : enemy; _aether.vars['chooseAction'] = typeof chooseAction == 'undefined' ? undefined : chooseAction; _aether.logStatement([{ofs: 76, row: 2, col: 5}, {ofs: 102, row: 2, col: 31}], \"this.getCooldown('warcry')\", this._aetherUserInfo);\n        _aether.logStatementStart([{ofs: 75, row: 2, col: 4}, {ofs: 102, row: 2, col: 31}]); tmp8 = !tmp9; _aether.vars['enemies'] = typeof enemies == 'undefined' ? undefined : enemies; _aether.vars['enemy'] = typeof enemy == 'undefined' ? undefined : enemy; _aether.vars['chooseAction'] = typeof chooseAction == 'undefined' ? undefined : chooseAction; _aether.logStatement([{ofs: 75, row: 2, col: 4}, {ofs: 102, row: 2, col: 31}], \"!this.getCooldown('warcry')\", this._aetherUserInfo);\n        if (tmp8) {\n            tmp13 = __interceptThis(this, __global);\n            tmp14 = 'warcry';\n            _aether.logStatementStart([{ofs: 110, row: 3, col: 4}, {ofs: 123, row: 3, col: 17}]); tmp15 = tmp13[tmp14](); _aether.vars['enemies'] = typeof enemies == 'undefined' ? undefined : enemies; _aether.vars['enemy'] = typeof enemy == 'undefined' ? undefined : enemy; _aether.vars['chooseAction'] = typeof chooseAction == 'undefined' ? undefined : chooseAction; _aether.logStatement([{ofs: 110, row: 3, col: 4}, {ofs: 123, row: 3, col: 17}], \"this.warcry()\", this._aetherUserInfo);\n        } else {\n            tmp16 = enemy;\n            if (tmp16) {\n                tmp17 = __interceptThis(this, __global);\n                tmp18 = 'attack';\n                tmp19 = enemy;\n                _aether.logStatementStart([{ofs: 149, row: 6, col: 4}, {ofs: 167, row: 6, col: 22}]); tmp20 = tmp17[tmp18](tmp19); _aether.vars['enemies'] = typeof enemies == 'undefined' ? undefined : enemies; _aether.vars['enemy'] = typeof enemy == 'undefined' ? undefined : enemy; _aether.vars['chooseAction'] = typeof chooseAction == 'undefined' ? undefined : chooseAction; _aether.logStatement([{ofs: 149, row: 6, col: 4}, {ofs: 167, row: 6, col: 22}], \"this.attack(enemy)\", this._aetherUserInfo);\n            } else {\n                tmp21 = __interceptThis(this, __global);\n                tmp22 = 'move';\n                _aether.logStatementStart([{ofs: 196, row: 9, col: 18}, {ofs: 198, row: 9, col: 20}]); tmp24 = 10; _aether.vars['enemies'] = typeof enemies == 'undefined' ? undefined : enemies; _aether.vars['enemy'] = typeof enemy == 'undefined' ? undefined : enemy; _aether.vars['chooseAction'] = typeof chooseAction == 'undefined' ? undefined : chooseAction; _aether.logStatement([{ofs: 196, row: 9, col: 18}, {ofs: 198, row: 9, col: 20}], \"10\", this._aetherUserInfo);\n                _aether.logStatementStart([{ofs: 203, row: 9, col: 25}, {ofs: 205, row: 9, col: 27}]); tmp25 = 30; _aether.vars['enemies'] = typeof enemies == 'undefined' ? undefined : enemies; _aether.vars['enemy'] = typeof enemy == 'undefined' ? undefined : enemy; _aether.vars['chooseAction'] = typeof chooseAction == 'undefined' ? undefined : chooseAction; _aether.logStatement([{ofs: 203, row: 9, col: 25}, {ofs: 205, row: 9, col: 27}], \"30\", this._aetherUserInfo);\n                _aether.logStatementStart([{ofs: 192, row: 9, col: 14}, {ofs: 206, row: 9, col: 28}]); tmp23 = {\n                    x: tmp24,\n                    y: tmp25\n                }; _aether.vars['enemies'] = typeof enemies == 'undefined' ? undefined : enemies; _aether.vars['enemy'] = typeof enemy == 'undefined' ? undefined : enemy; _aether.vars['chooseAction'] = typeof chooseAction == 'undefined' ? undefined : chooseAction; _aether.logStatement([{ofs: 192, row: 9, col: 14}, {ofs: 206, row: 9, col: 28}], \"{x: 10, y: 30}\", this._aetherUserInfo);\n                _aether.logStatementStart([{ofs: 182, row: 9, col: 4}, {ofs: 207, row: 9, col: 29}]); tmp26 = tmp21[tmp22](tmp23); _aether.vars['enemies'] = typeof enemies == 'undefined' ? undefined : enemies; _aether.vars['enemy'] = typeof enemy == 'undefined' ? undefined : enemy; _aether.vars['chooseAction'] = typeof chooseAction == 'undefined' ? undefined : chooseAction; _aether.logStatement([{ofs: 182, row: 9, col: 4}, {ofs: 207, row: 9, col: 29}], \"this.move({x: 10, y: 30})\", this._aetherUserInfo);\n            }\n        }\n        _aether.logCallEnd(); return;\n    };\n    tmp0 = 'chooseAction';\n    __global[tmp0] = tmp1;\n}(this));"
         },
         "programmable-tharin": {
           "chooseAction": "/*this.getFriends();\nthis.attack(this.getEnemies()[0]);\nreturn;\n*/\n \n\n/* TODO:\n   If they fully base race us, we actually do want to produce archers since they DPS faster\n   The effective DPS on soldiers is better if they attack us\n   but worse if they straight race us\n\n   //not sure if this is good but...\n   if they're attacking our base with a small number of units\n   we should make archers and get them to defend\n*/\n/*\nreturn;\n// Tharin is a melee fighter with shield, warcry, and terrify skills.\n// this.shield() lets him take one-third damage while defending.\n// this.warcry() gives allies within 10m 30% haste for 5s, every 10s.\n// this.terrify() sends foes within 30m fleeing for 5s, once per match.\nvar friends = this.getFriends();\nvar enemies = this.getEnemies();\nif (enemies.length === 0) return;  // Chill if all enemies are dead.\nvar enemy = this.getNearest(enemies);\nvar furthestFriendX = 30;\nfor (var i = 0; i < friends.length; ++i) {\n    var friend = friends[i];\n    furthestFriendX = Math.max(friend.pos.x, furthestFriendX);\n}  \nif (!this.getCooldown('warcry') && friends.length > 5) {\n    this.warcry();\n}  \nelse if ((this.now() > 15 || this.health < 150) && !this.getCooldown('terrify')) {\n    this.terrify();\n}\nelse if (this.health < 75 && this.pos.x > furthestFriendX - 5) {\n    this.move({x: 10, y: 27});\n}\nelse if (this.pos.x > furthestFriendX - 1 && this.now() < 50) {\n    this.shield();\n}\nelse {\n    this.attack(enemy);\n}\nthis.say(\"Defend!\", {targetPos: {x: 30, y: Infinity}});\n\n// You can also command your troops with this.say():\n//this.say(\"Defend!\", {targetPos: {x: 30, y: 30}}));\n//this.say(\"Attack!\", {target: enemy});\n//this.say(\"Move!\", {targetPos: {x: 40, y: 40});\n\n// You can store state on this across frames:\n//this.lastHealth = this.health;\n*/"
         }
       },
+      "teamSpells": {
+        "ogres": [
+          "programmable-brawler/chooseAction",
+          "programmable-shaman/chooseAction",
+          "ogre-base/chooseAction"
+        ],
+        "humans": [
+          "programmable-librarian/chooseAction",
+          "programmable-tharin/chooseAction",
+          "human-base/chooseAction"
+        ]
+      },
       "submittedCodeLanguage": "javascript",
-      "playtime": 9634,
+      "playtime": 9753,
       "codeLanguage": "javascript"
     },
     {
       "_id": "53361c80948ad7a777a10d9c",
+      "level": {
+        "original": "533353722a61b7ca6832840c",
+        "majorVersion": 0
+      },
       "team": "ogres",
       "levelID": "gold-rush",
       "levelName": "Gold Rush",
@@ -534,7 +683,18 @@ responses =
           "chooseAction": "var items = this.getItems();\nvar enemy = this.getNearestEnemy();\n\nvar c = new Vector(60, 40);\n//this.say(Math.round(c.x) + \", \" + Math.round(c.y));\nvar bestItem = null;\nvar bestValue = 0;\nvar canJump = !this.getCooldown('jump');\nvar i, item, d1, d2, d3, value;\nfor (i = 0; i < items.length; ++i) {\n    item = items[i];\n    d1 = this.distance(item) * (canJump ? 0.5 : 1);\n    d2 = c.distance(item.pos);\n    value = item.bountyGold / (d1 + d2 / 5);\n    if (value > bestValue) {\n        bestItem = item;\n        bestValue = value;\n    }\n} \n\nMath.random(); Math.random(); Math.random();\nvar secondBestItem = null;\nvar secondBestValue = 0;\nfor (i = 0; i < items.length; ++i) {\n    if (item == bestItem) continue;\n    item = items[i];\n    d1 = this.distance(item);\n    d2 = c.distance(item.pos);\n    d3 = item.pos.distance(bestItem);\n    value = item.bountyGold / (d1 + d2 / 5 + d3);\n    if (value > secondBestValue) {\n        secondBestItem = item;\n        secondBestValue = value;\n    }\n}\n\nif (!canJump && secondBestItem && this.distance(secondBestItem) < this.distance(bestItem))\n    bestItem = secondBestItem;  // Pick it up on the way.\nif (bestItem) {\n    if(canJump && this.distance(bestItem) > 30)\n        this.jumpTo(bestItem);\n    else\n        this.move(bestItem.pos);\n}"
         }
       },
-      "totalScore": 40.77678387026546,
+      "teamSpells": {
+        "common": [
+          "coin-generator-9000/chooseAction"
+        ],
+        "humans": [
+          "tharin/chooseAction"
+        ],
+        "ogres": [
+          "mak-fod/chooseAction"
+        ]
+      },
+      "totalScore": 40.73558595296533,
       "submitted": true,
       "submittedCodeLanguage": "javascript",
       "playtime": 1014,
@@ -542,6 +702,10 @@ responses =
     },
     {
       "_id": "531920069f44be00001a7aef",
+      "level": {
+        "original": "53173f76c269d400000543c2",
+        "majorVersion": 0
+      },
       "team": "ogres",
       "levelID": "dungeon-arena",
       "levelName": "Dungeon Arena",
@@ -549,13 +713,13 @@ responses =
       "totalScore": 26.50666470188054,
       "code": {
         "human-base": {
-          "chooseAction": "..."
+          "chooseAction": "var __interceptThis=(function(){var G=this;return function($this,sandbox){if($this==G){return sandbox;}return $this;};})();\nreturn (function (__global) {\n    var tmp0, tmp1;\n    tmp1 = function () {\n        'use strict'; _aether.logCallStart(_aether._userInfo); var hero, count, ranged, i, tmp2, tmp3, tmp4, tmp45, tmp46, tmp47, tmp88, tmp89, tmp90, tmp140, tmp141, tmp142, tmp143, tmp144, tmp145, tmp146, tmp147, tmp148, tmp149, tmp150, tmp151, tmp152, tmp153, tmp154, tmp155, tmp156, tmp157, tmp158, tmp159, tmp160, tmp161, tmp162, tmp163, tmp164, tmp165, tmp166, tmp167, tmp168, tmp169, tmp170, tmp171, tmp172, tmp173, tmp174, tmp175, tmp176, tmp177, tmp178, tmp179, tmp180, tmp181, tmp182, tmp183, tmp184, tmp185, tmp186, tmp187, tmp188, tmp189, tmp190, tmp191, tmp192, tmp193, tmp194, tmp195, tmp196, tmp197, tmp198, tmp199, tmp200, tmp201, tmp202, tmp203, tmp204, tmp205, tmp206, tmp207, tmp208, tmp209, tmp210, tmp211, tmp212, tmp213, tmp214, tmp215, tmp216, tmp217, tmp218, tmp219, tmp220, tmp221, tmp222, tmp223, tmp224, tmp225, tmp226, tmp227, tmp228, tmp229, tmp230, tmp231, tmp232, tmp233, tmp234, tmp235, tmp236, tmp237, tmp238, tmp239, tmp240, tmp241, tmp242, tmp243, tmp244, tmp245, tmp246, tmp247, tmp248, tmp249, tmp250, tmp251, tmp252, tmp253, tmp254, tmp255, tmp256, tmp257, tmp258, tmp259, tmp260, tmp261, tmp262, tmp263, tmp264, tmp265, tmp266, tmp267, tmp268, tmp269, tmp270, tmp271, tmp272, tmp273, tmp274, tmp275, tmp276, tmp277, tmp278, tmp279, tmp280, tmp281, tmp282, tmp283, tmp284, tmp285, tmp286, tmp287, tmp288, tmp289, tmp290, tmp291, tmp292, tmp293, tmp294, tmp295, tmp296, tmp297, tmp298, tmp299, tmp300, tmp301, tmp302, tmp303, tmp304, tmp305, tmp306, tmp307, tmp308, tmp309, tmp310, tmp311, tmp312, tmp313, tmp314, tmp315, tmp316, tmp317, tmp318, tmp319, tmp320, tmp321, tmp322, tmp323, tmp324, tmp325, tmp326, tmp327, tmp328, tmp329, tmp330, tmp331, tmp332, tmp333, tmp334, tmp335, tmp336, tmp337, tmp338, tmp339, tmp340, tmp341, tmp342, tmp343, tmp344, tmp345, tmp346, tmp347, tmp348, tmp349, tmp350, tmp351, tmp352, tmp353, tmp354, tmp355, tmp356, tmp357, tmp358, tmp359, tmp360, tmp361, tmp362, tmp363, tmp364, tmp365, tmp366, tmp367, tmp368, tmp369, tmp370, tmp371, tmp372, tmp373, tmp374, tmp375, tmp376, tmp377, tmp378, tmp379, tmp380, tmp381, tmp382, tmp383, tmp384, tmp385, tmp386, tmp387, tmp388, tmp389, tmp390, tmp391, tmp392, tmp393, tmp394, tmp395, tmp396, tmp397, tmp398, tmp399, tmp400, tmp401, tmp402, tmp403, tmp404, tmp405, tmp406, tmp407, tmp408, tmp409, tmp410, tmp411, tmp412, tmp413, tmp414, tmp415, tmp416, tmp417, tmp418, tmp419, tmp420, tmp421, tmp422, tmp423, tmp424, tmp425, tmp426, tmp427, tmp428, tmp429, tmp430, tmp431, tmp434, tmp435, tmp436, tmp437, tmp438, tmp439, tmp440, tmp441, tmp442, tmp443, tmp444, tmp445, tmp446, tmp447, tmp448, tmp449, tmp450, tmp451, tmp452, tmp453, tmp454, tmp455, tmp456, tmp457, tmp458, tmp459, tmp460, tmp461, tmp462, tmp463, tmp464, tmp465, tmp466, tmp467, tmp468, tmp469, tmp470, tmp471, tmp472, tmp473, tmp474, tmp475, tmp476, tmp477, tmp478, tmp479, tmp480, tmp481, tmp482, tmp483, tmp484, tmp485;  for(var __argIndexer = 0; __argIndexer < arguments.length; ++__argIndexer) arguments[__argIndexer] = _aether.createAPIClone(_aether, arguments[__argIndexer]);\n        tmp2 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n        tmp3 = 'getEnemyHero';\n        _aether.logStatementStart([{ofs: 222, row: 4, col: 0}, {ofs: 489, row: 11, col: 2}]); tmp4 = function () {\n            var i, tmp5, tmp6, tmp7, tmp8, tmp9, tmp10, tmp11, tmp12, tmp13, tmp14, tmp15, tmp16, tmp17, tmp18, tmp19, tmp22, tmp23, tmp24, tmp25, tmp26, tmp27, tmp28, tmp29, tmp30, tmp31, tmp32, tmp33, tmp34, tmp35, tmp36, tmp37, tmp38, tmp39, tmp40, tmp41, tmp42, tmp43, tmp44;  for(var __argIndexer = 0; __argIndexer < arguments.length; ++__argIndexer) arguments[__argIndexer] = _aether.createAPIClone(_aether, arguments[__argIndexer]);\n            _aether.logStatementStart([{ofs: 305, row: 6, col: 9}, {ofs: 314, row: 6, col: 18}]); i = 0;  _aether.logStatement([{ofs: 305, row: 6, col: 9}, {ofs: 314, row: 6, col: 18}], _aether._userInfo, false);\n            tmp6 = i;\n            tmp10 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n            tmp11 = 'enemies';\n            _aether.logStatementStart([{ofs: 320, row: 6, col: 24}, {ofs: 332, row: 6, col: 36}]); tmp8 = tmp10[tmp11];  _aether.logStatement([{ofs: 320, row: 6, col: 24}, {ofs: 332, row: 6, col: 36}], _aether._userInfo, false);\n            tmp9 = 'length';\n            _aether.logStatementStart([{ofs: 320, row: 6, col: 24}, {ofs: 339, row: 6, col: 43}]); tmp7 = tmp8[tmp9];  _aether.logStatement([{ofs: 320, row: 6, col: 24}, {ofs: 339, row: 6, col: 43}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 316, row: 6, col: 20}, {ofs: 339, row: 6, col: 43}]); tmp5 = tmp6 < tmp7;  _aether.logStatement([{ofs: 316, row: 6, col: 20}, {ofs: 339, row: 6, col: 43}], _aether._userInfo, false);\n            tmp20: {\n                while (tmp5) {\n                    tmp21: {\n                        tmp30 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n                        tmp31 = 'enemies';\n                        _aether.logStatementStart([{ofs: 360, row: 7, col: 12}, {ofs: 372, row: 7, col: 24}]); tmp28 = tmp30[tmp31];  _aether.logStatement([{ofs: 360, row: 7, col: 12}, {ofs: 372, row: 7, col: 24}], _aether._userInfo, false);\n                        tmp29 = i;\n                        _aether.logStatementStart([{ofs: 360, row: 7, col: 12}, {ofs: 375, row: 7, col: 27}]); tmp26 = tmp28[tmp29];  _aether.logStatement([{ofs: 360, row: 7, col: 12}, {ofs: 375, row: 7, col: 27}], _aether._userInfo, false);\n                        tmp27 = 'type';\n                        _aether.logStatementStart([{ofs: 360, row: 7, col: 12}, {ofs: 380, row: 7, col: 32}]); tmp24 = tmp26[tmp27];  _aether.logStatement([{ofs: 360, row: 7, col: 12}, {ofs: 380, row: 7, col: 32}], _aether._userInfo, false);\n                        _aether.logStatementStart([{ofs: 385, row: 7, col: 37}, {ofs: 394, row: 7, col: 46}]); tmp25 = 'brawler';  _aether.logStatement([{ofs: 385, row: 7, col: 37}, {ofs: 394, row: 7, col: 46}], _aether._userInfo, false);\n                        _aether.logStatementStart([{ofs: 360, row: 7, col: 12}, {ofs: 394, row: 7, col: 46}]); tmp23 = tmp24 === tmp25;  _aether.logStatement([{ofs: 360, row: 7, col: 12}, {ofs: 394, row: 7, col: 46}], _aether._userInfo, false);\n                        if (tmp23) {\n                            _aether.logStatementStart([{ofs: 360, row: 7, col: 12}, {ofs: 431, row: 7, col: 83}]); tmp22 = tmp23;  _aether.logStatement([{ofs: 360, row: 7, col: 12}, {ofs: 431, row: 7, col: 83}], _aether._userInfo, false);\n                        } else {\n                            tmp38 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n                            tmp39 = 'enemies';\n                            _aether.logStatementStart([{ofs: 398, row: 7, col: 50}, {ofs: 410, row: 7, col: 62}]); tmp36 = tmp38[tmp39];  _aether.logStatement([{ofs: 398, row: 7, col: 50}, {ofs: 410, row: 7, col: 62}], _aether._userInfo, false);\n                            tmp37 = i;\n                            _aether.logStatementStart([{ofs: 398, row: 7, col: 50}, {ofs: 413, row: 7, col: 65}]); tmp34 = tmp36[tmp37];  _aether.logStatement([{ofs: 398, row: 7, col: 50}, {ofs: 413, row: 7, col: 65}], _aether._userInfo, false);\n                            tmp35 = 'type';\n                            _aether.logStatementStart([{ofs: 398, row: 7, col: 50}, {ofs: 418, row: 7, col: 70}]); tmp32 = tmp34[tmp35];  _aether.logStatement([{ofs: 398, row: 7, col: 50}, {ofs: 418, row: 7, col: 70}], _aether._userInfo, false);\n                            _aether.logStatementStart([{ofs: 423, row: 7, col: 75}, {ofs: 431, row: 7, col: 83}]); tmp33 = 'shaman';  _aether.logStatement([{ofs: 423, row: 7, col: 75}, {ofs: 431, row: 7, col: 83}], _aether._userInfo, false);\n                            _aether.logStatementStart([{ofs: 398, row: 7, col: 50}, {ofs: 431, row: 7, col: 83}]); tmp22 = tmp32 === tmp33;  _aether.logStatement([{ofs: 398, row: 7, col: 50}, {ofs: 431, row: 7, col: 83}], _aether._userInfo, false);\n                        }\n                        if (tmp22) {\n                            tmp43 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n                            tmp44 = 'enemies';\n                            _aether.logStatementStart([{ofs: 454, row: 8, col: 19}, {ofs: 466, row: 8, col: 31}]); tmp41 = tmp43[tmp44];  _aether.logStatement([{ofs: 454, row: 8, col: 19}, {ofs: 466, row: 8, col: 31}], _aether._userInfo, false);\n                            tmp42 = i;\n                            _aether.logStatementStart([{ofs: 454, row: 8, col: 19}, {ofs: 469, row: 8, col: 34}]); tmp40 = tmp41[tmp42];  _aether.logStatement([{ofs: 454, row: 8, col: 19}, {ofs: 469, row: 8, col: 34}], _aether._userInfo, false);\n                            return _aether.restoreAPIClone(_aether, tmp40);\n                        } else {\n                            ;\n                        }\n                    }\n                    tmp18 = i;\n                    tmp19 = 1;\n                    i = tmp18 + tmp19;\n                    tmp12 = i;\n                    tmp16 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n                    tmp17 = 'enemies';\n                    _aether.logStatementStart([{ofs: 320, row: 6, col: 24}, {ofs: 332, row: 6, col: 36}]); tmp14 = tmp16[tmp17];  _aether.logStatement([{ofs: 320, row: 6, col: 24}, {ofs: 332, row: 6, col: 36}], _aether._userInfo, false);\n                    tmp15 = 'length';\n                    _aether.logStatementStart([{ofs: 320, row: 6, col: 24}, {ofs: 339, row: 6, col: 43}]); tmp13 = tmp14[tmp15];  _aether.logStatement([{ofs: 320, row: 6, col: 24}, {ofs: 339, row: 6, col: 43}], _aether._userInfo, false);\n                    _aether.logStatementStart([{ofs: 316, row: 6, col: 20}, {ofs: 339, row: 6, col: 43}]); tmp5 = tmp12 < tmp13;  _aether.logStatement([{ofs: 316, row: 6, col: 20}, {ofs: 339, row: 6, col: 43}], _aether._userInfo, false);\n                }\n            }\n            return;\n        };  _aether.logStatement([{ofs: 222, row: 4, col: 0}, {ofs: 489, row: 11, col: 2}], _aether._userInfo, false);\n        _aether.logStatementStart([{ofs: 222, row: 4, col: 0}, {ofs: 488, row: 11, col: 1}]); tmp2[tmp3] = tmp4;  _aether.logStatement([{ofs: 222, row: 4, col: 0}, {ofs: 488, row: 11, col: 1}], _aether._userInfo, false);\n        tmp45 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n        tmp46 = 'getMyHero';\n        _aether.logStatementStart([{ofs: 491, row: 13, col: 0}, {ofs: 757, row: 20, col: 2}]); tmp47 = function () {\n            var i, tmp48, tmp49, tmp50, tmp51, tmp52, tmp53, tmp54, tmp55, tmp56, tmp57, tmp58, tmp59, tmp60, tmp61, tmp62, tmp65, tmp66, tmp67, tmp68, tmp69, tmp70, tmp71, tmp72, tmp73, tmp74, tmp75, tmp76, tmp77, tmp78, tmp79, tmp80, tmp81, tmp82, tmp83, tmp84, tmp85, tmp86, tmp87;  for(var __argIndexer = 0; __argIndexer < arguments.length; ++__argIndexer) arguments[__argIndexer] = _aether.createAPIClone(_aether, arguments[__argIndexer]);\n            _aether.logStatementStart([{ofs: 571, row: 15, col: 9}, {ofs: 580, row: 15, col: 18}]); i = 0;  _aether.logStatement([{ofs: 571, row: 15, col: 9}, {ofs: 580, row: 15, col: 18}], _aether._userInfo, false);\n            tmp49 = i;\n            tmp53 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n            tmp54 = 'friends';\n            _aether.logStatementStart([{ofs: 586, row: 15, col: 24}, {ofs: 598, row: 15, col: 36}]); tmp51 = tmp53[tmp54];  _aether.logStatement([{ofs: 586, row: 15, col: 24}, {ofs: 598, row: 15, col: 36}], _aether._userInfo, false);\n            tmp52 = 'length';\n            _aether.logStatementStart([{ofs: 586, row: 15, col: 24}, {ofs: 605, row: 15, col: 43}]); tmp50 = tmp51[tmp52];  _aether.logStatement([{ofs: 586, row: 15, col: 24}, {ofs: 605, row: 15, col: 43}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 582, row: 15, col: 20}, {ofs: 605, row: 15, col: 43}]); tmp48 = tmp49 < tmp50;  _aether.logStatement([{ofs: 582, row: 15, col: 20}, {ofs: 605, row: 15, col: 43}], _aether._userInfo, false);\n            tmp63: {\n                while (tmp48) {\n                    tmp64: {\n                        tmp73 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n                        tmp74 = 'friends';\n                        _aether.logStatementStart([{ofs: 626, row: 16, col: 12}, {ofs: 638, row: 16, col: 24}]); tmp71 = tmp73[tmp74];  _aether.logStatement([{ofs: 626, row: 16, col: 12}, {ofs: 638, row: 16, col: 24}], _aether._userInfo, false);\n                        tmp72 = i;\n                        _aether.logStatementStart([{ofs: 626, row: 16, col: 12}, {ofs: 641, row: 16, col: 27}]); tmp69 = tmp71[tmp72];  _aether.logStatement([{ofs: 626, row: 16, col: 12}, {ofs: 641, row: 16, col: 27}], _aether._userInfo, false);\n                        tmp70 = 'type';\n                        _aether.logStatementStart([{ofs: 626, row: 16, col: 12}, {ofs: 646, row: 16, col: 32}]); tmp67 = tmp69[tmp70];  _aether.logStatement([{ofs: 626, row: 16, col: 12}, {ofs: 646, row: 16, col: 32}], _aether._userInfo, false);\n                        _aether.logStatementStart([{ofs: 651, row: 16, col: 37}, {ofs: 659, row: 16, col: 45}]); tmp68 = 'knight';  _aether.logStatement([{ofs: 651, row: 16, col: 37}, {ofs: 659, row: 16, col: 45}], _aether._userInfo, false);\n                        _aether.logStatementStart([{ofs: 626, row: 16, col: 12}, {ofs: 659, row: 16, col: 45}]); tmp66 = tmp67 === tmp68;  _aether.logStatement([{ofs: 626, row: 16, col: 12}, {ofs: 659, row: 16, col: 45}], _aether._userInfo, false);\n                        if (tmp66) {\n                            _aether.logStatementStart([{ofs: 626, row: 16, col: 12}, {ofs: 699, row: 16, col: 85}]); tmp65 = tmp66;  _aether.logStatement([{ofs: 626, row: 16, col: 12}, {ofs: 699, row: 16, col: 85}], _aether._userInfo, false);\n                        } else {\n                            tmp81 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n                            tmp82 = 'friends';\n                            _aether.logStatementStart([{ofs: 663, row: 16, col: 49}, {ofs: 675, row: 16, col: 61}]); tmp79 = tmp81[tmp82];  _aether.logStatement([{ofs: 663, row: 16, col: 49}, {ofs: 675, row: 16, col: 61}], _aether._userInfo, false);\n                            tmp80 = i;\n                            _aether.logStatementStart([{ofs: 663, row: 16, col: 49}, {ofs: 678, row: 16, col: 64}]); tmp77 = tmp79[tmp80];  _aether.logStatement([{ofs: 663, row: 16, col: 49}, {ofs: 678, row: 16, col: 64}], _aether._userInfo, false);\n                            tmp78 = 'type';\n                            _aether.logStatementStart([{ofs: 663, row: 16, col: 49}, {ofs: 683, row: 16, col: 69}]); tmp75 = tmp77[tmp78];  _aether.logStatement([{ofs: 663, row: 16, col: 49}, {ofs: 683, row: 16, col: 69}], _aether._userInfo, false);\n                            _aether.logStatementStart([{ofs: 688, row: 16, col: 74}, {ofs: 699, row: 16, col: 85}]); tmp76 = 'librarian';  _aether.logStatement([{ofs: 688, row: 16, col: 74}, {ofs: 699, row: 16, col: 85}], _aether._userInfo, false);\n                            _aether.logStatementStart([{ofs: 663, row: 16, col: 49}, {ofs: 699, row: 16, col: 85}]); tmp65 = tmp75 === tmp76;  _aether.logStatement([{ofs: 663, row: 16, col: 49}, {ofs: 699, row: 16, col: 85}], _aether._userInfo, false);\n                        }\n                        if (tmp65) {\n                            tmp86 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n                            tmp87 = 'friends';\n                            _aether.logStatementStart([{ofs: 722, row: 17, col: 19}, {ofs: 734, row: 17, col: 31}]); tmp84 = tmp86[tmp87];  _aether.logStatement([{ofs: 722, row: 17, col: 19}, {ofs: 734, row: 17, col: 31}], _aether._userInfo, false);\n                            tmp85 = i;\n                            _aether.logStatementStart([{ofs: 722, row: 17, col: 19}, {ofs: 737, row: 17, col: 34}]); tmp83 = tmp84[tmp85];  _aether.logStatement([{ofs: 722, row: 17, col: 19}, {ofs: 737, row: 17, col: 34}], _aether._userInfo, false);\n                            return _aether.restoreAPIClone(_aether, tmp83);\n                        } else {\n                            ;\n                        }\n                    }\n                    tmp61 = i;\n                    tmp62 = 1;\n                    i = tmp61 + tmp62;\n                    tmp55 = i;\n                    tmp59 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n                    tmp60 = 'friends';\n                    _aether.logStatementStart([{ofs: 586, row: 15, col: 24}, {ofs: 598, row: 15, col: 36}]); tmp57 = tmp59[tmp60];  _aether.logStatement([{ofs: 586, row: 15, col: 24}, {ofs: 598, row: 15, col: 36}], _aether._userInfo, false);\n                    tmp58 = 'length';\n                    _aether.logStatementStart([{ofs: 586, row: 15, col: 24}, {ofs: 605, row: 15, col: 43}]); tmp56 = tmp57[tmp58];  _aether.logStatement([{ofs: 586, row: 15, col: 24}, {ofs: 605, row: 15, col: 43}], _aether._userInfo, false);\n                    _aether.logStatementStart([{ofs: 582, row: 15, col: 20}, {ofs: 605, row: 15, col: 43}]); tmp48 = tmp55 < tmp56;  _aether.logStatement([{ofs: 582, row: 15, col: 20}, {ofs: 605, row: 15, col: 43}], _aether._userInfo, false);\n                }\n            }\n            return;\n        };  _aether.logStatement([{ofs: 491, row: 13, col: 0}, {ofs: 757, row: 20, col: 2}], _aether._userInfo, false);\n        _aether.logStatementStart([{ofs: 491, row: 13, col: 0}, {ofs: 756, row: 20, col: 1}]); tmp45[tmp46] = tmp47;  _aether.logStatement([{ofs: 491, row: 13, col: 0}, {ofs: 756, row: 20, col: 1}], _aether._userInfo, false);\n        tmp88 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n        tmp89 = 'doesEnemyHaveMix';\n        _aether.logStatementStart([{ofs: 759, row: 22, col: 0}, {ofs: 1200, row: 39, col: 2}]); tmp90 = function () {\n            var ranged, melee, i, tmp91, tmp92, tmp93, tmp94, tmp95, tmp96, tmp97, tmp98, tmp99, tmp100, tmp101, tmp102, tmp103, tmp104, tmp105, tmp108, tmp109, tmp110, tmp111, tmp112, tmp113, tmp114, tmp115, tmp116, tmp117, tmp118, tmp119, tmp120, tmp121, tmp122, tmp123, tmp124, tmp125, tmp126, tmp127, tmp128, tmp129, tmp130, tmp131, tmp132, tmp133, tmp134, tmp135, tmp136, tmp137, tmp138, tmp139;  for(var __argIndexer = 0; __argIndexer < arguments.length; ++__argIndexer) arguments[__argIndexer] = _aether.createAPIClone(_aether, arguments[__argIndexer]);\n            _aether.logStatementStart([{ofs: 849, row: 24, col: 4}, {ofs: 864, row: 24, col: 19}]); ranged = 0;  _aether.logStatement([{ofs: 849, row: 24, col: 4}, {ofs: 864, row: 24, col: 19}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 869, row: 25, col: 4}, {ofs: 883, row: 25, col: 18}]); melee = 0;  _aether.logStatement([{ofs: 869, row: 25, col: 4}, {ofs: 883, row: 25, col: 18}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 892, row: 26, col: 8}, {ofs: 901, row: 26, col: 17}]); i = 2;  _aether.logStatement([{ofs: 892, row: 26, col: 8}, {ofs: 901, row: 26, col: 17}], _aether._userInfo, false);\n            tmp92 = i;\n            tmp96 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n            tmp97 = 'enemies';\n            _aether.logStatementStart([{ofs: 907, row: 26, col: 23}, {ofs: 919, row: 26, col: 35}]); tmp94 = tmp96[tmp97];  _aether.logStatement([{ofs: 907, row: 26, col: 23}, {ofs: 919, row: 26, col: 35}], _aether._userInfo, false);\n            tmp95 = 'length';\n            _aether.logStatementStart([{ofs: 907, row: 26, col: 23}, {ofs: 926, row: 26, col: 42}]); tmp93 = tmp94[tmp95];  _aether.logStatement([{ofs: 907, row: 26, col: 23}, {ofs: 926, row: 26, col: 42}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 903, row: 26, col: 19}, {ofs: 926, row: 26, col: 42}]); tmp91 = tmp92 < tmp93;  _aether.logStatement([{ofs: 903, row: 26, col: 19}, {ofs: 926, row: 26, col: 42}], _aether._userInfo, false);\n            tmp106: {\n                while (tmp91) {\n                    tmp107: {\n                        tmp115 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n                        tmp116 = 'enemies';\n                        _aether.logStatementStart([{ofs: 946, row: 27, col: 11}, {ofs: 958, row: 27, col: 23}]); tmp113 = tmp115[tmp116];  _aether.logStatement([{ofs: 946, row: 27, col: 11}, {ofs: 958, row: 27, col: 23}], _aether._userInfo, false);\n                        tmp114 = i;\n                        _aether.logStatementStart([{ofs: 946, row: 27, col: 11}, {ofs: 961, row: 27, col: 26}]); tmp111 = tmp113[tmp114];  _aether.logStatement([{ofs: 946, row: 27, col: 11}, {ofs: 961, row: 27, col: 26}], _aether._userInfo, false);\n                        tmp112 = 'type';\n                        _aether.logStatementStart([{ofs: 946, row: 27, col: 11}, {ofs: 966, row: 27, col: 31}]); tmp109 = tmp111[tmp112];  _aether.logStatement([{ofs: 946, row: 27, col: 11}, {ofs: 966, row: 27, col: 31}], _aether._userInfo, false);\n                        _aether.logStatementStart([{ofs: 971, row: 27, col: 36}, {ofs: 980, row: 27, col: 45}]); tmp110 = 'thrower';  _aether.logStatement([{ofs: 971, row: 27, col: 36}, {ofs: 980, row: 27, col: 45}], _aether._userInfo, false);\n                        _aether.logStatementStart([{ofs: 946, row: 27, col: 11}, {ofs: 980, row: 27, col: 45}]); tmp108 = tmp109 === tmp110;  _aether.logStatement([{ofs: 946, row: 27, col: 11}, {ofs: 980, row: 27, col: 45}], _aether._userInfo, false);\n                        if (tmp108) {\n                            _aether.logStatementStart([{ofs: 996, row: 28, col: 12}, {ofs: 1008, row: 28, col: 24}]); tmp117 = 1;  _aether.logStatement([{ofs: 996, row: 28, col: 12}, {ofs: 1008, row: 28, col: 24}], _aether._userInfo, false);\n                            tmp118 = ranged;\n                            tmp119 = tmp117;\n                            ranged = tmp118 + tmp119;\n                        } else {\n                            tmp127 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n                            tmp128 = 'enemies';\n                            _aether.logStatementStart([{ofs: 1035, row: 30, col: 16}, {ofs: 1047, row: 30, col: 28}]); tmp125 = tmp127[tmp128];  _aether.logStatement([{ofs: 1035, row: 30, col: 16}, {ofs: 1047, row: 30, col: 28}], _aether._userInfo, false);\n                            tmp126 = i;\n                            _aether.logStatementStart([{ofs: 1035, row: 30, col: 16}, {ofs: 1050, row: 30, col: 31}]); tmp123 = tmp125[tmp126];  _aether.logStatement([{ofs: 1035, row: 30, col: 16}, {ofs: 1050, row: 30, col: 31}], _aether._userInfo, false);\n                            tmp124 = 'type';\n                            _aether.logStatementStart([{ofs: 1035, row: 30, col: 16}, {ofs: 1055, row: 30, col: 36}]); tmp121 = tmp123[tmp124];  _aether.logStatement([{ofs: 1035, row: 30, col: 16}, {ofs: 1055, row: 30, col: 36}], _aether._userInfo, false);\n                            _aether.logStatementStart([{ofs: 1060, row: 30, col: 41}, {ofs: 1070, row: 30, col: 51}]); tmp122 = 'munchkin';  _aether.logStatement([{ofs: 1060, row: 30, col: 41}, {ofs: 1070, row: 30, col: 51}], _aether._userInfo, false);\n                            _aether.logStatementStart([{ofs: 1035, row: 30, col: 16}, {ofs: 1070, row: 30, col: 51}]); tmp120 = tmp121 === tmp122;  _aether.logStatement([{ofs: 1035, row: 30, col: 16}, {ofs: 1070, row: 30, col: 51}], _aether._userInfo, false);\n                            if (tmp120) {\n                                _aether.logStatementStart([{ofs: 1086, row: 31, col: 12}, {ofs: 1097, row: 31, col: 23}]); tmp129 = 1;  _aether.logStatement([{ofs: 1086, row: 31, col: 12}, {ofs: 1097, row: 31, col: 23}], _aether._userInfo, false);\n                                tmp130 = melee;\n                                tmp131 = tmp129;\n                                melee = tmp130 + tmp131;\n                            } else {\n                                ;\n                            }\n                        }\n                    }\n                    tmp104 = i;\n                    tmp105 = 1;\n                    i = tmp104 + tmp105;\n                    tmp98 = i;\n                    tmp102 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n                    tmp103 = 'enemies';\n                    _aether.logStatementStart([{ofs: 907, row: 26, col: 23}, {ofs: 919, row: 26, col: 35}]); tmp100 = tmp102[tmp103];  _aether.logStatement([{ofs: 907, row: 26, col: 23}, {ofs: 919, row: 26, col: 35}], _aether._userInfo, false);\n                    tmp101 = 'length';\n                    _aether.logStatementStart([{ofs: 907, row: 26, col: 23}, {ofs: 926, row: 26, col: 42}]); tmp99 = tmp100[tmp101];  _aether.logStatement([{ofs: 907, row: 26, col: 23}, {ofs: 926, row: 26, col: 42}], _aether._userInfo, false);\n                    _aether.logStatementStart([{ofs: 903, row: 26, col: 19}, {ofs: 926, row: 26, col: 42}]); tmp91 = tmp98 < tmp99;  _aether.logStatement([{ofs: 903, row: 26, col: 19}, {ofs: 926, row: 26, col: 42}], _aether._userInfo, false);\n                }\n            }\n            tmp134 = ranged;\n            _aether.logStatementStart([{ofs: 1130, row: 34, col: 16}, {ofs: 1131, row: 34, col: 17}]); tmp135 = 0;  _aether.logStatement([{ofs: 1130, row: 34, col: 16}, {ofs: 1131, row: 34, col: 17}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 1121, row: 34, col: 7}, {ofs: 1131, row: 34, col: 17}]); tmp133 = tmp134 > tmp135;  _aether.logStatement([{ofs: 1121, row: 34, col: 7}, {ofs: 1131, row: 34, col: 17}], _aether._userInfo, false);\n            if (tmp133) {\n                tmp136 = melee;\n                _aether.logStatementStart([{ofs: 1143, row: 34, col: 29}, {ofs: 1144, row: 34, col: 30}]); tmp137 = 0;  _aether.logStatement([{ofs: 1143, row: 34, col: 29}, {ofs: 1144, row: 34, col: 30}], _aether._userInfo, false);\n                _aether.logStatementStart([{ofs: 1135, row: 34, col: 21}, {ofs: 1144, row: 34, col: 30}]); tmp132 = tmp136 > tmp137;  _aether.logStatement([{ofs: 1135, row: 34, col: 21}, {ofs: 1144, row: 34, col: 30}], _aether._userInfo, false);\n            } else {\n                _aether.logStatementStart([{ofs: 1121, row: 34, col: 7}, {ofs: 1144, row: 34, col: 30}]); tmp132 = tmp133;  _aether.logStatement([{ofs: 1121, row: 34, col: 7}, {ofs: 1144, row: 34, col: 30}], _aether._userInfo, false);\n            }\n            if (tmp132) {\n                _aether.logStatementStart([{ofs: 1163, row: 35, col: 15}, {ofs: 1167, row: 35, col: 19}]); tmp138 = true;  _aether.logStatement([{ofs: 1163, row: 35, col: 15}, {ofs: 1167, row: 35, col: 19}], _aether._userInfo, false);\n                return _aether.restoreAPIClone(_aether, tmp138);\n            } else {\n                ;\n            }\n            _aether.logStatementStart([{ofs: 1191, row: 38, col: 11}, {ofs: 1196, row: 38, col: 16}]); tmp139 = false;  _aether.logStatement([{ofs: 1191, row: 38, col: 11}, {ofs: 1196, row: 38, col: 16}], _aether._userInfo, false);\n            return _aether.restoreAPIClone(_aether, tmp139);\n        };  _aether.logStatement([{ofs: 759, row: 22, col: 0}, {ofs: 1200, row: 39, col: 2}], _aether._userInfo, false);\n        _aether.logStatementStart([{ofs: 759, row: 22, col: 0}, {ofs: 1199, row: 39, col: 1}]); tmp88[tmp89] = tmp90;  _aether.logStatement([{ofs: 759, row: 22, col: 0}, {ofs: 1199, row: 39, col: 1}], _aether._userInfo, false);\n        tmp140 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n        tmp141 = 'enemies';\n        tmp143 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n        tmp144 = 'getEnemies';\n        _aether.logStatementStart([{ofs: 1202, row: 41, col: 0}, {ofs: 1235, row: 41, col: 33}]); tmp142 = _aether.createAPIClone(_aether, tmp143[tmp144]());  _aether.logStatement([{ofs: 1202, row: 41, col: 0}, {ofs: 1235, row: 41, col: 33}], _aether._userInfo, false);\n        _aether.logStatementStart([{ofs: 1202, row: 41, col: 0}, {ofs: 1234, row: 41, col: 32}]); tmp140[tmp141] = tmp142;  _aether.logStatement([{ofs: 1202, row: 41, col: 0}, {ofs: 1234, row: 41, col: 32}], _aether._userInfo, false);\n        tmp145 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n        tmp146 = 'friends';\n        tmp148 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n        tmp149 = 'getFriends';\n        _aether.logStatementStart([{ofs: 1236, row: 42, col: 0}, {ofs: 1269, row: 42, col: 33}]); tmp147 = _aether.createAPIClone(_aether, tmp148[tmp149]());  _aether.logStatement([{ofs: 1236, row: 42, col: 0}, {ofs: 1269, row: 42, col: 33}], _aether._userInfo, false);\n        _aether.logStatementStart([{ofs: 1236, row: 42, col: 0}, {ofs: 1268, row: 42, col: 32}]); tmp145[tmp146] = tmp147;  _aether.logStatement([{ofs: 1236, row: 42, col: 0}, {ofs: 1268, row: 42, col: 32}], _aether._userInfo, false);\n        tmp150 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n        tmp151 = 'myHero';\n        tmp153 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n        tmp154 = 'getMyHero';\n        _aether.logStatementStart([{ofs: 1270, row: 43, col: 0}, {ofs: 1301, row: 43, col: 31}]); tmp152 = _aether.createAPIClone(_aether, tmp153[tmp154]());  _aether.logStatement([{ofs: 1270, row: 43, col: 0}, {ofs: 1301, row: 43, col: 31}], _aether._userInfo, false);\n        _aether.logStatementStart([{ofs: 1270, row: 43, col: 0}, {ofs: 1300, row: 43, col: 30}]); tmp150[tmp151] = tmp152;  _aether.logStatement([{ofs: 1270, row: 43, col: 0}, {ofs: 1300, row: 43, col: 30}], _aether._userInfo, false);\n        tmp155 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n        tmp156 = 'enemyHero';\n        tmp158 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n        tmp159 = 'getEnemyHero';\n        _aether.logStatementStart([{ofs: 1302, row: 44, col: 0}, {ofs: 1339, row: 44, col: 37}]); tmp157 = _aether.createAPIClone(_aether, tmp158[tmp159]());  _aether.logStatement([{ofs: 1302, row: 44, col: 0}, {ofs: 1339, row: 44, col: 37}], _aether._userInfo, false);\n        _aether.logStatementStart([{ofs: 1302, row: 44, col: 0}, {ofs: 1338, row: 44, col: 36}]); tmp155[tmp156] = tmp157;  _aether.logStatement([{ofs: 1302, row: 44, col: 0}, {ofs: 1338, row: 44, col: 36}], _aether._userInfo, false);\n        _aether.logStatementStart([{ofs: 1400, row: 47, col: 0}, {ofs: 1416, row: 47, col: 16}]); hero = 'tharin';  _aether.logStatement([{ofs: 1400, row: 47, col: 0}, {ofs: 1416, row: 47, col: 16}], _aether._userInfo, false);\n        tmp161 = hero;\n        if (tmp161) {\n            tmp163 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n            tmp164 = 'builtHero';\n            _aether.logStatementStart([{ofs: 1526, row: 50, col: 13}, {ofs: 1540, row: 50, col: 27}]); tmp162 = tmp163[tmp164];  _aether.logStatement([{ofs: 1526, row: 50, col: 13}, {ofs: 1540, row: 50, col: 27}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 1525, row: 50, col: 12}, {ofs: 1540, row: 50, col: 27}]); tmp160 = !tmp162;  _aether.logStatement([{ofs: 1525, row: 50, col: 12}, {ofs: 1540, row: 50, col: 27}], _aether._userInfo, false);\n        } else {\n            _aether.logStatementStart([{ofs: 1517, row: 50, col: 4}, {ofs: 1540, row: 50, col: 27}]); tmp160 = tmp161;  _aether.logStatement([{ofs: 1517, row: 50, col: 4}, {ofs: 1540, row: 50, col: 27}], _aether._userInfo, false);\n        }\n        if (tmp160) {\n            tmp165 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n            tmp166 = 'builtHero';\n            tmp168 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n            tmp169 = 'build';\n            tmp170 = hero;\n            _aether.logStatementStart([{ofs: 1548, row: 51, col: 4}, {ofs: 1582, row: 51, col: 38}]); tmp167 = _aether.createAPIClone(_aether, tmp168[tmp169](_aether.restoreAPIClone(_aether, tmp170)));  _aether.logStatement([{ofs: 1548, row: 51, col: 4}, {ofs: 1582, row: 51, col: 38}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 1548, row: 51, col: 4}, {ofs: 1581, row: 51, col: 37}]); tmp165[tmp166] = tmp167;  _aether.logStatement([{ofs: 1548, row: 51, col: 4}, {ofs: 1581, row: 51, col: 37}], _aether._userInfo, false);\n            _aether.logCallEnd(); return;\n        } else {\n            ;\n        }\n        tmp174 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n        tmp175 = 'myHero';\n        _aether.logStatementStart([{ofs: 2493, row: 76, col: 3}, {ofs: 2504, row: 76, col: 14}]); tmp173 = tmp174[tmp175];  _aether.logStatement([{ofs: 2493, row: 76, col: 3}, {ofs: 2504, row: 76, col: 14}], _aether._userInfo, false);\n        if (tmp173) {\n            tmp178 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n            tmp179 = 'myHero';\n            _aether.logStatementStart([{ofs: 2508, row: 76, col: 18}, {ofs: 2519, row: 76, col: 29}]); tmp176 = tmp178[tmp179];  _aether.logStatement([{ofs: 2508, row: 76, col: 18}, {ofs: 2519, row: 76, col: 29}], _aether._userInfo, false);\n            tmp177 = 'notHeroFirst';\n            _aether.logStatementStart([{ofs: 2508, row: 76, col: 18}, {ofs: 2532, row: 76, col: 42}]); tmp172 = tmp176[tmp177];  _aether.logStatement([{ofs: 2508, row: 76, col: 18}, {ofs: 2532, row: 76, col: 42}], _aether._userInfo, false);\n        } else {\n            _aether.logStatementStart([{ofs: 2493, row: 76, col: 3}, {ofs: 2532, row: 76, col: 42}]); tmp172 = tmp173;  _aether.logStatement([{ofs: 2493, row: 76, col: 3}, {ofs: 2532, row: 76, col: 42}], _aether._userInfo, false);\n        }\n        if (tmp172) {\n            tmp182 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n            tmp183 = 'myHero';\n            _aether.logStatementStart([{ofs: 2536, row: 76, col: 46}, {ofs: 2547, row: 76, col: 57}]); tmp180 = tmp182[tmp183];  _aether.logStatement([{ofs: 2536, row: 76, col: 46}, {ofs: 2547, row: 76, col: 57}], _aether._userInfo, false);\n            tmp181 = 'notHeroSecond';\n            _aether.logStatementStart([{ofs: 2536, row: 76, col: 46}, {ofs: 2561, row: 76, col: 71}]); tmp171 = tmp180[tmp181];  _aether.logStatement([{ofs: 2536, row: 76, col: 46}, {ofs: 2561, row: 76, col: 71}], _aether._userInfo, false);\n        } else {\n            _aether.logStatementStart([{ofs: 2493, row: 76, col: 3}, {ofs: 2561, row: 76, col: 71}]); tmp171 = tmp172;  _aether.logStatement([{ofs: 2493, row: 76, col: 3}, {ofs: 2561, row: 76, col: 71}], _aether._userInfo, false);\n        }\n        if (tmp171) {\n            tmp184 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n            tmp185 = 'build';\n            _aether.logStatementStart([{ofs: 2580, row: 77, col: 15}, {ofs: 2588, row: 77, col: 23}]); tmp186 = 'archer';  _aether.logStatement([{ofs: 2580, row: 77, col: 15}, {ofs: 2588, row: 77, col: 23}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 2569, row: 77, col: 4}, {ofs: 2589, row: 77, col: 24}]); tmp187 = _aether.createAPIClone(_aether, tmp184[tmp185](_aether.restoreAPIClone(_aether, tmp186)));  _aether.logStatement([{ofs: 2569, row: 77, col: 4}, {ofs: 2589, row: 77, col: 24}], _aether._userInfo, false);\n            _aether.logCallEnd(); return;\n        } else {\n            tmp192 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n            tmp193 = 'myHero';\n            _aether.logStatementStart([{ofs: 2753, row: 83, col: 8}, {ofs: 2764, row: 83, col: 19}]); tmp191 = tmp192[tmp193];  _aether.logStatement([{ofs: 2753, row: 83, col: 8}, {ofs: 2764, row: 83, col: 19}], _aether._userInfo, false);\n            if (tmp191) {\n                tmp196 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n                tmp197 = 'myHero';\n                _aether.logStatementStart([{ofs: 2768, row: 83, col: 23}, {ofs: 2779, row: 83, col: 34}]); tmp194 = tmp196[tmp197];  _aether.logStatement([{ofs: 2768, row: 83, col: 23}, {ofs: 2779, row: 83, col: 34}], _aether._userInfo, false);\n                tmp195 = 'notHeroFirst';\n                _aether.logStatementStart([{ofs: 2768, row: 83, col: 23}, {ofs: 2792, row: 83, col: 47}]); tmp190 = tmp194[tmp195];  _aether.logStatement([{ofs: 2768, row: 83, col: 23}, {ofs: 2792, row: 83, col: 47}], _aether._userInfo, false);\n            } else {\n                _aether.logStatementStart([{ofs: 2753, row: 83, col: 8}, {ofs: 2792, row: 83, col: 47}]); tmp190 = tmp191;  _aether.logStatement([{ofs: 2753, row: 83, col: 8}, {ofs: 2792, row: 83, col: 47}], _aether._userInfo, false);\n            }\n            if (tmp190) {\n                tmp200 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n                tmp201 = 'myHero';\n                _aether.logStatementStart([{ofs: 2796, row: 83, col: 51}, {ofs: 2807, row: 83, col: 62}]); tmp198 = tmp200[tmp201];  _aether.logStatement([{ofs: 2796, row: 83, col: 51}, {ofs: 2807, row: 83, col: 62}], _aether._userInfo, false);\n                tmp199 = 'terrifyCooldown';\n                _aether.logStatementStart([{ofs: 2796, row: 83, col: 51}, {ofs: 2823, row: 83, col: 78}]); tmp189 = tmp198[tmp199];  _aether.logStatement([{ofs: 2796, row: 83, col: 51}, {ofs: 2823, row: 83, col: 78}], _aether._userInfo, false);\n            } else {\n                _aether.logStatementStart([{ofs: 2753, row: 83, col: 8}, {ofs: 2823, row: 83, col: 78}]); tmp189 = tmp190;  _aether.logStatement([{ofs: 2753, row: 83, col: 8}, {ofs: 2823, row: 83, col: 78}], _aether._userInfo, false);\n            }\n            if (tmp189) {\n                tmp208 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n                tmp209 = 'myHero';\n                _aether.logStatementStart([{ofs: 2828, row: 83, col: 83}, {ofs: 2839, row: 83, col: 94}]); tmp206 = tmp208[tmp209];  _aether.logStatement([{ofs: 2828, row: 83, col: 83}, {ofs: 2839, row: 83, col: 94}], _aether._userInfo, false);\n                tmp207 = 'terrifyUnitCount';\n                _aether.logStatementStart([{ofs: 2828, row: 83, col: 83}, {ofs: 2856, row: 83, col: 111}]); tmp204 = tmp206[tmp207];  _aether.logStatement([{ofs: 2828, row: 83, col: 83}, {ofs: 2856, row: 83, col: 111}], _aether._userInfo, false);\n                _aether.logStatementStart([{ofs: 2860, row: 83, col: 115}, {ofs: 2861, row: 83, col: 116}]); tmp205 = 5;  _aether.logStatement([{ofs: 2860, row: 83, col: 115}, {ofs: 2861, row: 83, col: 116}], _aether._userInfo, false);\n                _aether.logStatementStart([{ofs: 2828, row: 83, col: 83}, {ofs: 2861, row: 83, col: 116}]); tmp203 = tmp204 != tmp205;  _aether.logStatement([{ofs: 2828, row: 83, col: 83}, {ofs: 2861, row: 83, col: 116}], _aether._userInfo, false);\n                if (tmp203) {\n                    tmp214 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n                    tmp215 = 'myHero';\n                    _aether.logStatementStart([{ofs: 2865, row: 83, col: 120}, {ofs: 2876, row: 83, col: 131}]); tmp212 = tmp214[tmp215];  _aether.logStatement([{ofs: 2865, row: 83, col: 120}, {ofs: 2876, row: 83, col: 131}], _aether._userInfo, false);\n                    tmp213 = 'terrifyTargets';\n                    _aether.logStatementStart([{ofs: 2865, row: 83, col: 120}, {ofs: 2891, row: 83, col: 146}]); tmp210 = tmp212[tmp213];  _aether.logStatement([{ofs: 2865, row: 83, col: 120}, {ofs: 2891, row: 83, col: 146}], _aether._userInfo, false);\n                    _aether.logStatementStart([{ofs: 2895, row: 83, col: 150}, {ofs: 2896, row: 83, col: 151}]); tmp211 = 4;  _aether.logStatement([{ofs: 2895, row: 83, col: 150}, {ofs: 2896, row: 83, col: 151}], _aether._userInfo, false);\n                    _aether.logStatementStart([{ofs: 2865, row: 83, col: 120}, {ofs: 2896, row: 83, col: 151}]); tmp202 = tmp210 != tmp211;  _aether.logStatement([{ofs: 2865, row: 83, col: 120}, {ofs: 2896, row: 83, col: 151}], _aether._userInfo, false);\n                } else {\n                    _aether.logStatementStart([{ofs: 2828, row: 83, col: 83}, {ofs: 2896, row: 83, col: 151}]); tmp202 = tmp203;  _aether.logStatement([{ofs: 2828, row: 83, col: 83}, {ofs: 2896, row: 83, col: 151}], _aether._userInfo, false);\n                }\n                if (tmp202) {\n                    tmp220 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n                    tmp221 = 'myHero';\n                    _aether.logStatementStart([{ofs: 2900, row: 83, col: 155}, {ofs: 2911, row: 83, col: 166}]); tmp218 = tmp220[tmp221];  _aether.logStatement([{ofs: 2900, row: 83, col: 155}, {ofs: 2911, row: 83, col: 166}], _aether._userInfo, false);\n                    tmp219 = 'terrifyTargets';\n                    _aether.logStatementStart([{ofs: 2900, row: 83, col: 155}, {ofs: 2926, row: 83, col: 181}]); tmp216 = tmp218[tmp219];  _aether.logStatement([{ofs: 2900, row: 83, col: 155}, {ofs: 2926, row: 83, col: 181}], _aether._userInfo, false);\n                    _aether.logStatementStart([{ofs: 2930, row: 83, col: 185}, {ofs: 2931, row: 83, col: 186}]); tmp217 = 1;  _aether.logStatement([{ofs: 2930, row: 83, col: 185}, {ofs: 2931, row: 83, col: 186}], _aether._userInfo, false);\n                    _aether.logStatementStart([{ofs: 2900, row: 83, col: 155}, {ofs: 2931, row: 83, col: 186}]); tmp188 = tmp216 != tmp217;  _aether.logStatement([{ofs: 2900, row: 83, col: 155}, {ofs: 2931, row: 83, col: 186}], _aether._userInfo, false);\n                } else {\n                    _aether.logStatementStart([{ofs: 2828, row: 83, col: 83}, {ofs: 2931, row: 83, col: 186}]); tmp188 = tmp202;  _aether.logStatement([{ofs: 2828, row: 83, col: 83}, {ofs: 2931, row: 83, col: 186}], _aether._userInfo, false);\n                }\n            } else {\n                _aether.logStatementStart([{ofs: 2753, row: 83, col: 8}, {ofs: 2932, row: 83, col: 187}]); tmp188 = tmp189;  _aether.logStatement([{ofs: 2753, row: 83, col: 8}, {ofs: 2932, row: 83, col: 187}], _aether._userInfo, false);\n            }\n            if (tmp188) {\n                tmp222 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n                tmp223 = 'noArcher';\n                _aether.logStatementStart([{ofs: 2940, row: 84, col: 4}, {ofs: 2961, row: 84, col: 25}]); tmp224 = true;  _aether.logStatement([{ofs: 2940, row: 84, col: 4}, {ofs: 2961, row: 84, col: 25}], _aether._userInfo, false);\n                _aether.logStatementStart([{ofs: 2940, row: 84, col: 4}, {ofs: 2960, row: 84, col: 24}]); tmp222[tmp223] = tmp224;  _aether.logStatement([{ofs: 2940, row: 84, col: 4}, {ofs: 2960, row: 84, col: 24}], _aether._userInfo, false);\n                tmp225 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n                tmp226 = 'build';\n                _aether.logStatementStart([{ofs: 2977, row: 85, col: 15}, {ofs: 2986, row: 85, col: 24}]); tmp227 = 'soldier';  _aether.logStatement([{ofs: 2977, row: 85, col: 15}, {ofs: 2986, row: 85, col: 24}], _aether._userInfo, false);\n                _aether.logStatementStart([{ofs: 2966, row: 85, col: 4}, {ofs: 2987, row: 85, col: 25}]); tmp228 = _aether.createAPIClone(_aether, tmp225[tmp226](_aether.restoreAPIClone(_aether, tmp227)));  _aether.logStatement([{ofs: 2966, row: 85, col: 4}, {ofs: 2987, row: 85, col: 25}], _aether._userInfo, false);\n                _aether.logCallEnd(); return;\n            } else {\n                ;\n            }\n        }\n        tmp231 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n        tmp232 = 'myHero';\n        _aether.logStatementStart([{ofs: 3203, row: 94, col: 7}, {ofs: 3214, row: 94, col: 18}]); tmp230 = tmp231[tmp232];  _aether.logStatement([{ofs: 3203, row: 94, col: 7}, {ofs: 3214, row: 94, col: 18}], _aether._userInfo, false);\n        if (tmp230) {\n            tmp235 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n            tmp236 = 'myHero';\n            _aether.logStatementStart([{ofs: 3218, row: 94, col: 22}, {ofs: 3229, row: 94, col: 33}]); tmp233 = tmp235[tmp236];  _aether.logStatement([{ofs: 3218, row: 94, col: 22}, {ofs: 3229, row: 94, col: 33}], _aether._userInfo, false);\n            tmp234 = 'midJump';\n            _aether.logStatementStart([{ofs: 3218, row: 94, col: 22}, {ofs: 3237, row: 94, col: 41}]); tmp229 = tmp233[tmp234];  _aether.logStatement([{ofs: 3218, row: 94, col: 22}, {ofs: 3237, row: 94, col: 41}], _aether._userInfo, false);\n        } else {\n            _aether.logStatementStart([{ofs: 3203, row: 94, col: 7}, {ofs: 3237, row: 94, col: 41}]); tmp229 = tmp230;  _aether.logStatement([{ofs: 3203, row: 94, col: 7}, {ofs: 3237, row: 94, col: 41}], _aether._userInfo, false);\n        }\n        if (tmp229) {\n            tmp237 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n            tmp238 = 'build';\n            _aether.logStatementStart([{ofs: 3260, row: 95, col: 19}, {ofs: 3269, row: 95, col: 28}]); tmp239 = 'soldier';  _aether.logStatement([{ofs: 3260, row: 95, col: 19}, {ofs: 3269, row: 95, col: 28}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 3249, row: 95, col: 8}, {ofs: 3270, row: 95, col: 29}]); tmp240 = _aether.createAPIClone(_aether, tmp237[tmp238](_aether.restoreAPIClone(_aether, tmp239)));  _aether.logStatement([{ofs: 3249, row: 95, col: 8}, {ofs: 3270, row: 95, col: 29}], _aether._userInfo, false);\n            _aether.logCallEnd(); return;\n        } else {\n            ;\n        }\n        tmp246 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n        tmp247 = 'myHero';\n        _aether.logStatementStart([{ofs: 3302, row: 99, col: 7}, {ofs: 3313, row: 99, col: 18}]); tmp245 = tmp246[tmp247];  _aether.logStatement([{ofs: 3302, row: 99, col: 7}, {ofs: 3313, row: 99, col: 18}], _aether._userInfo, false);\n        if (tmp245) {\n            tmp250 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n            tmp251 = 'myHero';\n            _aether.logStatementStart([{ofs: 3317, row: 99, col: 22}, {ofs: 3328, row: 99, col: 33}]); tmp248 = tmp250[tmp251];  _aether.logStatement([{ofs: 3317, row: 99, col: 22}, {ofs: 3328, row: 99, col: 33}], _aether._userInfo, false);\n            tmp249 = 'earlyJump';\n            _aether.logStatementStart([{ofs: 3317, row: 99, col: 22}, {ofs: 3338, row: 99, col: 43}]); tmp244 = tmp248[tmp249];  _aether.logStatement([{ofs: 3317, row: 99, col: 22}, {ofs: 3338, row: 99, col: 43}], _aether._userInfo, false);\n        } else {\n            _aether.logStatementStart([{ofs: 3302, row: 99, col: 7}, {ofs: 3338, row: 99, col: 43}]); tmp244 = tmp245;  _aether.logStatement([{ofs: 3302, row: 99, col: 7}, {ofs: 3338, row: 99, col: 43}], _aether._userInfo, false);\n        }\n        if (tmp244) {\n            tmp254 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n            tmp255 = 'myHero';\n            _aether.logStatementStart([{ofs: 3342, row: 99, col: 47}, {ofs: 3353, row: 99, col: 58}]); tmp252 = tmp254[tmp255];  _aether.logStatement([{ofs: 3342, row: 99, col: 47}, {ofs: 3353, row: 99, col: 58}], _aether._userInfo, false);\n            tmp253 = 'terrifyCooldown';\n            _aether.logStatementStart([{ofs: 3342, row: 99, col: 47}, {ofs: 3369, row: 99, col: 74}]); tmp243 = tmp252[tmp253];  _aether.logStatement([{ofs: 3342, row: 99, col: 47}, {ofs: 3369, row: 99, col: 74}], _aether._userInfo, false);\n        } else {\n            _aether.logStatementStart([{ofs: 3302, row: 99, col: 7}, {ofs: 3369, row: 99, col: 74}]); tmp243 = tmp244;  _aether.logStatement([{ofs: 3302, row: 99, col: 7}, {ofs: 3369, row: 99, col: 74}], _aether._userInfo, false);\n        }\n        if (tmp243) {\n            tmp260 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n            tmp261 = 'myHero';\n            _aether.logStatementStart([{ofs: 3373, row: 99, col: 78}, {ofs: 3384, row: 99, col: 89}]); tmp258 = tmp260[tmp261];  _aether.logStatement([{ofs: 3373, row: 99, col: 78}, {ofs: 3384, row: 99, col: 89}], _aether._userInfo, false);\n            tmp259 = 'terrifyTargets';\n            _aether.logStatementStart([{ofs: 3373, row: 99, col: 78}, {ofs: 3399, row: 99, col: 104}]); tmp256 = tmp258[tmp259];  _aether.logStatement([{ofs: 3373, row: 99, col: 78}, {ofs: 3399, row: 99, col: 104}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 3404, row: 99, col: 109}, {ofs: 3405, row: 99, col: 110}]); tmp257 = 4;  _aether.logStatement([{ofs: 3404, row: 99, col: 109}, {ofs: 3405, row: 99, col: 110}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 3373, row: 99, col: 78}, {ofs: 3405, row: 99, col: 110}]); tmp242 = tmp256 === tmp257;  _aether.logStatement([{ofs: 3373, row: 99, col: 78}, {ofs: 3405, row: 99, col: 110}], _aether._userInfo, false);\n        } else {\n            _aether.logStatementStart([{ofs: 3302, row: 99, col: 7}, {ofs: 3405, row: 99, col: 110}]); tmp242 = tmp243;  _aether.logStatement([{ofs: 3302, row: 99, col: 7}, {ofs: 3405, row: 99, col: 110}], _aether._userInfo, false);\n        }\n        if (tmp242) {\n            tmp266 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n            tmp267 = 'myHero';\n            _aether.logStatementStart([{ofs: 3409, row: 99, col: 114}, {ofs: 3420, row: 99, col: 125}]); tmp264 = tmp266[tmp267];  _aether.logStatement([{ofs: 3409, row: 99, col: 114}, {ofs: 3420, row: 99, col: 125}], _aether._userInfo, false);\n            tmp265 = 'terrifyUnitCount';\n            _aether.logStatementStart([{ofs: 3409, row: 99, col: 114}, {ofs: 3437, row: 99, col: 142}]); tmp262 = tmp264[tmp265];  _aether.logStatement([{ofs: 3409, row: 99, col: 114}, {ofs: 3437, row: 99, col: 142}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 3442, row: 99, col: 147}, {ofs: 3443, row: 99, col: 148}]); tmp263 = 3;  _aether.logStatement([{ofs: 3442, row: 99, col: 147}, {ofs: 3443, row: 99, col: 148}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 3409, row: 99, col: 114}, {ofs: 3443, row: 99, col: 148}]); tmp241 = tmp262 === tmp263;  _aether.logStatement([{ofs: 3409, row: 99, col: 114}, {ofs: 3443, row: 99, col: 148}], _aether._userInfo, false);\n        } else {\n            _aether.logStatementStart([{ofs: 3302, row: 99, col: 7}, {ofs: 3443, row: 99, col: 148}]); tmp241 = tmp242;  _aether.logStatement([{ofs: 3302, row: 99, col: 7}, {ofs: 3443, row: 99, col: 148}], _aether._userInfo, false);\n        }\n        if (tmp241) {\n            tmp268 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n            tmp269 = 'build';\n            _aether.logStatementStart([{ofs: 3466, row: 100, col: 19}, {ofs: 3475, row: 100, col: 28}]); tmp270 = 'soldier';  _aether.logStatement([{ofs: 3466, row: 100, col: 19}, {ofs: 3475, row: 100, col: 28}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 3455, row: 100, col: 8}, {ofs: 3476, row: 100, col: 29}]); tmp271 = _aether.createAPIClone(_aether, tmp268[tmp269](_aether.restoreAPIClone(_aether, tmp270)));  _aether.logStatement([{ofs: 3455, row: 100, col: 8}, {ofs: 3476, row: 100, col: 29}], _aether._userInfo, false);\n            _aether.logCallEnd(); return;\n        } else {\n            ;\n        }\n        tmp280 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n        tmp281 = 'noArcher';\n        _aether.logStatementStart([{ofs: 3509, row: 104, col: 8}, {ofs: 3522, row: 104, col: 21}]); tmp279 = tmp280[tmp281];  _aether.logStatement([{ofs: 3509, row: 104, col: 8}, {ofs: 3522, row: 104, col: 21}], _aether._userInfo, false);\n        _aether.logStatementStart([{ofs: 3508, row: 104, col: 7}, {ofs: 3522, row: 104, col: 21}]); tmp278 = !tmp279;  _aether.logStatement([{ofs: 3508, row: 104, col: 7}, {ofs: 3522, row: 104, col: 21}], _aether._userInfo, false);\n        if (tmp278) {\n            tmp282 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n            tmp283 = 'myHero';\n            _aether.logStatementStart([{ofs: 3526, row: 104, col: 25}, {ofs: 3537, row: 104, col: 36}]); tmp277 = tmp282[tmp283];  _aether.logStatement([{ofs: 3526, row: 104, col: 25}, {ofs: 3537, row: 104, col: 36}], _aether._userInfo, false);\n        } else {\n            _aether.logStatementStart([{ofs: 3508, row: 104, col: 7}, {ofs: 3537, row: 104, col: 36}]); tmp277 = tmp278;  _aether.logStatement([{ofs: 3508, row: 104, col: 7}, {ofs: 3537, row: 104, col: 36}], _aether._userInfo, false);\n        }\n        if (tmp277) {\n            tmp286 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n            tmp287 = 'myHero';\n            _aether.logStatementStart([{ofs: 3541, row: 104, col: 40}, {ofs: 3552, row: 104, col: 51}]); tmp284 = tmp286[tmp287];  _aether.logStatement([{ofs: 3541, row: 104, col: 40}, {ofs: 3552, row: 104, col: 51}], _aether._userInfo, false);\n            tmp285 = 'terrifyCooldown';\n            _aether.logStatementStart([{ofs: 3541, row: 104, col: 40}, {ofs: 3568, row: 104, col: 67}]); tmp276 = tmp284[tmp285];  _aether.logStatement([{ofs: 3541, row: 104, col: 40}, {ofs: 3568, row: 104, col: 67}], _aether._userInfo, false);\n        } else {\n            _aether.logStatementStart([{ofs: 3508, row: 104, col: 7}, {ofs: 3568, row: 104, col: 67}]); tmp276 = tmp277;  _aether.logStatement([{ofs: 3508, row: 104, col: 7}, {ofs: 3568, row: 104, col: 67}], _aether._userInfo, false);\n        }\n        if (tmp276) {\n            tmp290 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n            tmp291 = 'myHero';\n            _aether.logStatementStart([{ofs: 3572, row: 104, col: 71}, {ofs: 3583, row: 104, col: 82}]); tmp288 = tmp290[tmp291];  _aether.logStatement([{ofs: 3572, row: 104, col: 71}, {ofs: 3583, row: 104, col: 82}], _aether._userInfo, false);\n            tmp289 = 'earlyJump';\n            _aether.logStatementStart([{ofs: 3572, row: 104, col: 71}, {ofs: 3593, row: 104, col: 92}]); tmp275 = tmp288[tmp289];  _aether.logStatement([{ofs: 3572, row: 104, col: 71}, {ofs: 3593, row: 104, col: 92}], _aether._userInfo, false);\n        } else {\n            _aether.logStatementStart([{ofs: 3508, row: 104, col: 7}, {ofs: 3593, row: 104, col: 92}]); tmp275 = tmp276;  _aether.logStatement([{ofs: 3508, row: 104, col: 7}, {ofs: 3593, row: 104, col: 92}], _aether._userInfo, false);\n        }\n        if (tmp275) {\n            tmp296 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n            tmp297 = 'enemies';\n            _aether.logStatementStart([{ofs: 3597, row: 104, col: 96}, {ofs: 3609, row: 104, col: 108}]); tmp294 = tmp296[tmp297];  _aether.logStatement([{ofs: 3597, row: 104, col: 96}, {ofs: 3609, row: 104, col: 108}], _aether._userInfo, false);\n            tmp295 = 'length';\n            _aether.logStatementStart([{ofs: 3597, row: 104, col: 96}, {ofs: 3616, row: 104, col: 115}]); tmp292 = tmp294[tmp295];  _aether.logStatement([{ofs: 3597, row: 104, col: 96}, {ofs: 3616, row: 104, col: 115}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 3621, row: 104, col: 120}, {ofs: 3622, row: 104, col: 121}]); tmp293 = 4;  _aether.logStatement([{ofs: 3621, row: 104, col: 120}, {ofs: 3622, row: 104, col: 121}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 3597, row: 104, col: 96}, {ofs: 3622, row: 104, col: 121}]); tmp274 = tmp292 === tmp293;  _aether.logStatement([{ofs: 3597, row: 104, col: 96}, {ofs: 3622, row: 104, col: 121}], _aether._userInfo, false);\n        } else {\n            _aether.logStatementStart([{ofs: 3508, row: 104, col: 7}, {ofs: 3622, row: 104, col: 121}]); tmp274 = tmp275;  _aether.logStatement([{ofs: 3508, row: 104, col: 7}, {ofs: 3622, row: 104, col: 121}], _aether._userInfo, false);\n        }\n        if (tmp274) {\n            tmp302 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n            tmp303 = 'myHero';\n            _aether.logStatementStart([{ofs: 3626, row: 104, col: 125}, {ofs: 3637, row: 104, col: 136}]); tmp300 = tmp302[tmp303];  _aether.logStatement([{ofs: 3626, row: 104, col: 125}, {ofs: 3637, row: 104, col: 136}], _aether._userInfo, false);\n            tmp301 = 'terrifyTargets';\n            _aether.logStatementStart([{ofs: 3626, row: 104, col: 125}, {ofs: 3652, row: 104, col: 151}]); tmp298 = tmp300[tmp301];  _aether.logStatement([{ofs: 3626, row: 104, col: 125}, {ofs: 3652, row: 104, col: 151}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 3657, row: 104, col: 156}, {ofs: 3658, row: 104, col: 157}]); tmp299 = 1;  _aether.logStatement([{ofs: 3657, row: 104, col: 156}, {ofs: 3658, row: 104, col: 157}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 3626, row: 104, col: 125}, {ofs: 3658, row: 104, col: 157}]); tmp273 = tmp298 === tmp299;  _aether.logStatement([{ofs: 3626, row: 104, col: 125}, {ofs: 3658, row: 104, col: 157}], _aether._userInfo, false);\n        } else {\n            _aether.logStatementStart([{ofs: 3508, row: 104, col: 7}, {ofs: 3658, row: 104, col: 157}]); tmp273 = tmp274;  _aether.logStatement([{ofs: 3508, row: 104, col: 7}, {ofs: 3658, row: 104, col: 157}], _aether._userInfo, false);\n        }\n        if (tmp273) {\n            tmp304 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n            tmp305 = 'doesEnemyHaveMix';\n            _aether.logStatementStart([{ofs: 3662, row: 104, col: 161}, {ofs: 3685, row: 104, col: 184}]); tmp272 = _aether.createAPIClone(_aether, tmp304[tmp305]());  _aether.logStatement([{ofs: 3662, row: 104, col: 161}, {ofs: 3685, row: 104, col: 184}], _aether._userInfo, false);\n        } else {\n            _aether.logStatementStart([{ofs: 3508, row: 104, col: 7}, {ofs: 3685, row: 104, col: 184}]); tmp272 = tmp273;  _aether.logStatement([{ofs: 3508, row: 104, col: 7}, {ofs: 3685, row: 104, col: 184}], _aether._userInfo, false);\n        }\n        if (tmp272) {\n            tmp306 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n            tmp307 = 'noArcher';\n            _aether.logStatementStart([{ofs: 3697, row: 105, col: 8}, {ofs: 3718, row: 105, col: 29}]); tmp308 = true;  _aether.logStatement([{ofs: 3697, row: 105, col: 8}, {ofs: 3718, row: 105, col: 29}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 3697, row: 105, col: 8}, {ofs: 3717, row: 105, col: 28}]); tmp306[tmp307] = tmp308;  _aether.logStatement([{ofs: 3697, row: 105, col: 8}, {ofs: 3717, row: 105, col: 28}], _aether._userInfo, false);\n        } else {\n            ;\n        }\n        tmp313 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n        tmp314 = 'myHero';\n        _aether.logStatementStart([{ofs: 3733, row: 108, col: 7}, {ofs: 3744, row: 108, col: 18}]); tmp312 = tmp313[tmp314];  _aether.logStatement([{ofs: 3733, row: 108, col: 7}, {ofs: 3744, row: 108, col: 18}], _aether._userInfo, false);\n        if (tmp312) {\n            tmp317 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n            tmp318 = 'myHero';\n            _aether.logStatementStart([{ofs: 3748, row: 108, col: 22}, {ofs: 3759, row: 108, col: 33}]); tmp315 = tmp317[tmp318];  _aether.logStatement([{ofs: 3748, row: 108, col: 22}, {ofs: 3759, row: 108, col: 33}], _aether._userInfo, false);\n            tmp316 = 'terrifyCooldown';\n            _aether.logStatementStart([{ofs: 3748, row: 108, col: 22}, {ofs: 3775, row: 108, col: 49}]); tmp311 = tmp315[tmp316];  _aether.logStatement([{ofs: 3748, row: 108, col: 22}, {ofs: 3775, row: 108, col: 49}], _aether._userInfo, false);\n        } else {\n            _aether.logStatementStart([{ofs: 3733, row: 108, col: 7}, {ofs: 3775, row: 108, col: 49}]); tmp311 = tmp312;  _aether.logStatement([{ofs: 3733, row: 108, col: 7}, {ofs: 3775, row: 108, col: 49}], _aether._userInfo, false);\n        }\n        if (tmp311) {\n            tmp323 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n            tmp324 = 'myHero';\n            _aether.logStatementStart([{ofs: 3779, row: 108, col: 53}, {ofs: 3790, row: 108, col: 64}]); tmp321 = tmp323[tmp324];  _aether.logStatement([{ofs: 3779, row: 108, col: 53}, {ofs: 3790, row: 108, col: 64}], _aether._userInfo, false);\n            tmp322 = 'terrifyTargets';\n            _aether.logStatementStart([{ofs: 3779, row: 108, col: 53}, {ofs: 3805, row: 108, col: 79}]); tmp319 = tmp321[tmp322];  _aether.logStatement([{ofs: 3779, row: 108, col: 53}, {ofs: 3805, row: 108, col: 79}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 3809, row: 108, col: 83}, {ofs: 3810, row: 108, col: 84}]); tmp320 = 2;  _aether.logStatement([{ofs: 3809, row: 108, col: 83}, {ofs: 3810, row: 108, col: 84}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 3779, row: 108, col: 53}, {ofs: 3810, row: 108, col: 84}]); tmp310 = tmp319 != tmp320;  _aether.logStatement([{ofs: 3779, row: 108, col: 53}, {ofs: 3810, row: 108, col: 84}], _aether._userInfo, false);\n        } else {\n            _aether.logStatementStart([{ofs: 3733, row: 108, col: 7}, {ofs: 3810, row: 108, col: 84}]); tmp310 = tmp311;  _aether.logStatement([{ofs: 3733, row: 108, col: 7}, {ofs: 3810, row: 108, col: 84}], _aether._userInfo, false);\n        }\n        if (tmp310) {\n            tmp326 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n            tmp327 = 'noArcher';\n            _aether.logStatementStart([{ofs: 3815, row: 108, col: 89}, {ofs: 3828, row: 108, col: 102}]); tmp325 = tmp326[tmp327];  _aether.logStatement([{ofs: 3815, row: 108, col: 89}, {ofs: 3828, row: 108, col: 102}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 3814, row: 108, col: 88}, {ofs: 3828, row: 108, col: 102}]); tmp309 = !tmp325;  _aether.logStatement([{ofs: 3814, row: 108, col: 88}, {ofs: 3828, row: 108, col: 102}], _aether._userInfo, false);\n        } else {\n            _aether.logStatementStart([{ofs: 3733, row: 108, col: 7}, {ofs: 3828, row: 108, col: 102}]); tmp309 = tmp310;  _aether.logStatement([{ofs: 3733, row: 108, col: 7}, {ofs: 3828, row: 108, col: 102}], _aether._userInfo, false);\n        }\n        if (tmp309) {\n            tmp328 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n            tmp329 = 'build';\n            _aether.logStatementStart([{ofs: 3851, row: 109, col: 19}, {ofs: 3859, row: 109, col: 27}]); tmp330 = 'archer';  _aether.logStatement([{ofs: 3851, row: 109, col: 19}, {ofs: 3859, row: 109, col: 27}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 3840, row: 109, col: 8}, {ofs: 3860, row: 109, col: 28}]); tmp331 = _aether.createAPIClone(_aether, tmp328[tmp329](_aether.restoreAPIClone(_aether, tmp330)));  _aether.logStatement([{ofs: 3840, row: 109, col: 8}, {ofs: 3860, row: 109, col: 28}], _aether._userInfo, false);\n            _aether.logCallEnd(); return;\n        } else {\n            ;\n        }\n        tmp337 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n        tmp338 = 'myHero';\n        _aether.logStatementStart([{ofs: 3893, row: 114, col: 7}, {ofs: 3904, row: 114, col: 18}]); tmp336 = tmp337[tmp338];  _aether.logStatement([{ofs: 3893, row: 114, col: 7}, {ofs: 3904, row: 114, col: 18}], _aether._userInfo, false);\n        if (tmp336) {\n            tmp341 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n            tmp342 = 'myHero';\n            _aether.logStatementStart([{ofs: 3908, row: 114, col: 22}, {ofs: 3919, row: 114, col: 33}]); tmp339 = tmp341[tmp342];  _aether.logStatement([{ofs: 3908, row: 114, col: 22}, {ofs: 3919, row: 114, col: 33}], _aether._userInfo, false);\n            tmp340 = 'earlyJump';\n            _aether.logStatementStart([{ofs: 3908, row: 114, col: 22}, {ofs: 3929, row: 114, col: 43}]); tmp335 = tmp339[tmp340];  _aether.logStatement([{ofs: 3908, row: 114, col: 22}, {ofs: 3929, row: 114, col: 43}], _aether._userInfo, false);\n        } else {\n            _aether.logStatementStart([{ofs: 3893, row: 114, col: 7}, {ofs: 3929, row: 114, col: 43}]); tmp335 = tmp336;  _aether.logStatement([{ofs: 3893, row: 114, col: 7}, {ofs: 3929, row: 114, col: 43}], _aether._userInfo, false);\n        }\n        if (tmp335) {\n            tmp345 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n            tmp346 = 'now';\n            _aether.logStatementStart([{ofs: 3933, row: 114, col: 47}, {ofs: 3943, row: 114, col: 57}]); tmp343 = _aether.createAPIClone(_aether, tmp345[tmp346]());  _aether.logStatement([{ofs: 3933, row: 114, col: 47}, {ofs: 3943, row: 114, col: 57}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 3947, row: 114, col: 61}, {ofs: 3948, row: 114, col: 62}]); tmp344 = 5;  _aether.logStatement([{ofs: 3947, row: 114, col: 61}, {ofs: 3948, row: 114, col: 62}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 3933, row: 114, col: 47}, {ofs: 3948, row: 114, col: 62}]); tmp334 = tmp343 >= tmp344;  _aether.logStatement([{ofs: 3933, row: 114, col: 47}, {ofs: 3948, row: 114, col: 62}], _aether._userInfo, false);\n        } else {\n            _aether.logStatementStart([{ofs: 3893, row: 114, col: 7}, {ofs: 3948, row: 114, col: 62}]); tmp334 = tmp335;  _aether.logStatement([{ofs: 3893, row: 114, col: 7}, {ofs: 3948, row: 114, col: 62}], _aether._userInfo, false);\n        }\n        if (tmp334) {\n            tmp351 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n            tmp352 = 'myHero';\n            _aether.logStatementStart([{ofs: 3952, row: 114, col: 66}, {ofs: 3963, row: 114, col: 77}]); tmp349 = tmp351[tmp352];  _aether.logStatement([{ofs: 3952, row: 114, col: 66}, {ofs: 3963, row: 114, col: 77}], _aether._userInfo, false);\n            tmp350 = 'terrifyTargets';\n            _aether.logStatementStart([{ofs: 3952, row: 114, col: 66}, {ofs: 3978, row: 114, col: 92}]); tmp347 = tmp349[tmp350];  _aether.logStatement([{ofs: 3952, row: 114, col: 66}, {ofs: 3978, row: 114, col: 92}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 3982, row: 114, col: 96}, {ofs: 3983, row: 114, col: 97}]); tmp348 = 2;  _aether.logStatement([{ofs: 3982, row: 114, col: 96}, {ofs: 3983, row: 114, col: 97}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 3952, row: 114, col: 66}, {ofs: 3983, row: 114, col: 97}]); tmp333 = tmp347 != tmp348;  _aether.logStatement([{ofs: 3952, row: 114, col: 66}, {ofs: 3983, row: 114, col: 97}], _aether._userInfo, false);\n        } else {\n            _aether.logStatementStart([{ofs: 3893, row: 114, col: 7}, {ofs: 3983, row: 114, col: 97}]); tmp333 = tmp334;  _aether.logStatement([{ofs: 3893, row: 114, col: 7}, {ofs: 3983, row: 114, col: 97}], _aether._userInfo, false);\n        }\n        if (tmp333) {\n            tmp354 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n            tmp355 = 'noArcher';\n            _aether.logStatementStart([{ofs: 3988, row: 114, col: 102}, {ofs: 4001, row: 114, col: 115}]); tmp353 = tmp354[tmp355];  _aether.logStatement([{ofs: 3988, row: 114, col: 102}, {ofs: 4001, row: 114, col: 115}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 3987, row: 114, col: 101}, {ofs: 4001, row: 114, col: 115}]); tmp332 = !tmp353;  _aether.logStatement([{ofs: 3987, row: 114, col: 101}, {ofs: 4001, row: 114, col: 115}], _aether._userInfo, false);\n        } else {\n            _aether.logStatementStart([{ofs: 3893, row: 114, col: 7}, {ofs: 4001, row: 114, col: 115}]); tmp332 = tmp333;  _aether.logStatement([{ofs: 3893, row: 114, col: 7}, {ofs: 4001, row: 114, col: 115}], _aether._userInfo, false);\n        }\n        if (tmp332) {\n            tmp356 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n            tmp357 = 'build';\n            _aether.logStatementStart([{ofs: 4025, row: 115, col: 19}, {ofs: 4033, row: 115, col: 27}]); tmp358 = 'archer';  _aether.logStatement([{ofs: 4025, row: 115, col: 19}, {ofs: 4033, row: 115, col: 27}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 4014, row: 115, col: 8}, {ofs: 4034, row: 115, col: 28}]); tmp359 = _aether.createAPIClone(_aether, tmp356[tmp357](_aether.restoreAPIClone(_aether, tmp358)));  _aether.logStatement([{ofs: 4014, row: 115, col: 8}, {ofs: 4034, row: 115, col: 28}], _aether._userInfo, false);\n            _aether.logCallEnd(); return;\n        } else {\n            ;\n        }\n        tmp363 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n        tmp364 = 'archers';\n        _aether.logStatementStart([{ofs: 4293, row: 124, col: 8}, {ofs: 4305, row: 124, col: 20}]); tmp362 = tmp363[tmp364];  _aether.logStatement([{ofs: 4293, row: 124, col: 8}, {ofs: 4305, row: 124, col: 20}], _aether._userInfo, false);\n        if (tmp362) {\n            tmp369 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n            tmp370 = 'friends';\n            _aether.logStatementStart([{ofs: 4309, row: 124, col: 24}, {ofs: 4321, row: 124, col: 36}]); tmp367 = tmp369[tmp370];  _aether.logStatement([{ofs: 4309, row: 124, col: 24}, {ofs: 4321, row: 124, col: 36}], _aether._userInfo, false);\n            tmp368 = 'length';\n            _aether.logStatementStart([{ofs: 4309, row: 124, col: 24}, {ofs: 4328, row: 124, col: 43}]); tmp365 = tmp367[tmp368];  _aether.logStatement([{ofs: 4309, row: 124, col: 24}, {ofs: 4328, row: 124, col: 43}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 4332, row: 124, col: 47}, {ofs: 4333, row: 124, col: 48}]); tmp366 = 5;  _aether.logStatement([{ofs: 4332, row: 124, col: 47}, {ofs: 4333, row: 124, col: 48}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 4309, row: 124, col: 24}, {ofs: 4333, row: 124, col: 48}]); tmp361 = tmp365 >= tmp366;  _aether.logStatement([{ofs: 4309, row: 124, col: 24}, {ofs: 4333, row: 124, col: 48}], _aether._userInfo, false);\n        } else {\n            _aether.logStatementStart([{ofs: 4293, row: 124, col: 8}, {ofs: 4333, row: 124, col: 48}]); tmp361 = tmp362;  _aether.logStatement([{ofs: 4293, row: 124, col: 8}, {ofs: 4333, row: 124, col: 48}], _aether._userInfo, false);\n        }\n        if (tmp361) {\n            _aether.logStatementStart([{ofs: 4292, row: 124, col: 7}, {ofs: 4371, row: 124, col: 86}]); tmp360 = tmp361;  _aether.logStatement([{ofs: 4292, row: 124, col: 7}, {ofs: 4371, row: 124, col: 86}], _aether._userInfo, false);\n        } else {\n            tmp374 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n            tmp375 = 'now';\n            _aether.logStatementStart([{ofs: 4338, row: 124, col: 53}, {ofs: 4348, row: 124, col: 63}]); tmp372 = _aether.createAPIClone(_aether, tmp374[tmp375]());  _aether.logStatement([{ofs: 4338, row: 124, col: 53}, {ofs: 4348, row: 124, col: 63}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 4351, row: 124, col: 66}, {ofs: 4353, row: 124, col: 68}]); tmp373 = 12;  _aether.logStatement([{ofs: 4351, row: 124, col: 66}, {ofs: 4353, row: 124, col: 68}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 4338, row: 124, col: 53}, {ofs: 4353, row: 124, col: 68}]); tmp371 = tmp372 > tmp373;  _aether.logStatement([{ofs: 4338, row: 124, col: 53}, {ofs: 4353, row: 124, col: 68}], _aether._userInfo, false);\n            if (tmp371) {\n                tmp377 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n                tmp378 = 'noArcher';\n                _aether.logStatementStart([{ofs: 4358, row: 124, col: 73}, {ofs: 4371, row: 124, col: 86}]); tmp376 = tmp377[tmp378];  _aether.logStatement([{ofs: 4358, row: 124, col: 73}, {ofs: 4371, row: 124, col: 86}], _aether._userInfo, false);\n                _aether.logStatementStart([{ofs: 4357, row: 124, col: 72}, {ofs: 4371, row: 124, col: 86}]); tmp360 = !tmp376;  _aether.logStatement([{ofs: 4357, row: 124, col: 72}, {ofs: 4371, row: 124, col: 86}], _aether._userInfo, false);\n            } else {\n                _aether.logStatementStart([{ofs: 4338, row: 124, col: 53}, {ofs: 4371, row: 124, col: 86}]); tmp360 = tmp371;  _aether.logStatement([{ofs: 4338, row: 124, col: 53}, {ofs: 4371, row: 124, col: 86}], _aether._userInfo, false);\n            }\n        }\n        if (tmp360) {\n            tmp379 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n            tmp380 = 'build';\n            _aether.logStatementStart([{ofs: 4394, row: 125, col: 19}, {ofs: 4402, row: 125, col: 27}]); tmp381 = 'archer';  _aether.logStatement([{ofs: 4394, row: 125, col: 19}, {ofs: 4402, row: 125, col: 27}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 4383, row: 125, col: 8}, {ofs: 4403, row: 125, col: 28}]); tmp382 = _aether.createAPIClone(_aether, tmp379[tmp380](_aether.restoreAPIClone(_aether, tmp381)));  _aether.logStatement([{ofs: 4383, row: 125, col: 8}, {ofs: 4403, row: 125, col: 28}], _aether._userInfo, false);\n            _aether.logCallEnd(); return;\n        } else {\n            ;\n        }\n        tmp387 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n        tmp388 = 'myHero';\n        _aether.logStatementStart([{ofs: 4434, row: 128, col: 7}, {ofs: 4445, row: 128, col: 18}]); tmp386 = tmp387[tmp388];  _aether.logStatement([{ofs: 4434, row: 128, col: 7}, {ofs: 4445, row: 128, col: 18}], _aether._userInfo, false);\n        if (tmp386) {\n            tmp391 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n            tmp392 = 'myHero';\n            _aether.logStatementStart([{ofs: 4449, row: 128, col: 22}, {ofs: 4460, row: 128, col: 33}]); tmp389 = tmp391[tmp392];  _aether.logStatement([{ofs: 4449, row: 128, col: 22}, {ofs: 4460, row: 128, col: 33}], _aether._userInfo, false);\n            tmp390 = 'lateJump';\n            _aether.logStatementStart([{ofs: 4449, row: 128, col: 22}, {ofs: 4469, row: 128, col: 42}]); tmp385 = tmp389[tmp390];  _aether.logStatement([{ofs: 4449, row: 128, col: 22}, {ofs: 4469, row: 128, col: 42}], _aether._userInfo, false);\n        } else {\n            _aether.logStatementStart([{ofs: 4434, row: 128, col: 7}, {ofs: 4469, row: 128, col: 42}]); tmp385 = tmp386;  _aether.logStatement([{ofs: 4434, row: 128, col: 7}, {ofs: 4469, row: 128, col: 42}], _aether._userInfo, false);\n        }\n        if (tmp385) {\n            tmp397 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n            tmp398 = 'friends';\n            _aether.logStatementStart([{ofs: 4473, row: 128, col: 46}, {ofs: 4485, row: 128, col: 58}]); tmp395 = tmp397[tmp398];  _aether.logStatement([{ofs: 4473, row: 128, col: 46}, {ofs: 4485, row: 128, col: 58}], _aether._userInfo, false);\n            tmp396 = 'length';\n            _aether.logStatementStart([{ofs: 4473, row: 128, col: 46}, {ofs: 4492, row: 128, col: 65}]); tmp393 = tmp395[tmp396];  _aether.logStatement([{ofs: 4473, row: 128, col: 46}, {ofs: 4492, row: 128, col: 65}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 4496, row: 128, col: 69}, {ofs: 4497, row: 128, col: 70}]); tmp394 = 3;  _aether.logStatement([{ofs: 4496, row: 128, col: 69}, {ofs: 4497, row: 128, col: 70}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 4473, row: 128, col: 46}, {ofs: 4497, row: 128, col: 70}]); tmp384 = tmp393 >= tmp394;  _aether.logStatement([{ofs: 4473, row: 128, col: 46}, {ofs: 4497, row: 128, col: 70}], _aether._userInfo, false);\n        } else {\n            _aether.logStatementStart([{ofs: 4434, row: 128, col: 7}, {ofs: 4497, row: 128, col: 70}]); tmp384 = tmp385;  _aether.logStatement([{ofs: 4434, row: 128, col: 7}, {ofs: 4497, row: 128, col: 70}], _aether._userInfo, false);\n        }\n        if (tmp384) {\n            tmp400 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n            tmp401 = 'noArcher';\n            _aether.logStatementStart([{ofs: 4502, row: 128, col: 75}, {ofs: 4515, row: 128, col: 88}]); tmp399 = tmp400[tmp401];  _aether.logStatement([{ofs: 4502, row: 128, col: 75}, {ofs: 4515, row: 128, col: 88}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 4501, row: 128, col: 74}, {ofs: 4515, row: 128, col: 88}]); tmp383 = !tmp399;  _aether.logStatement([{ofs: 4501, row: 128, col: 74}, {ofs: 4515, row: 128, col: 88}], _aether._userInfo, false);\n        } else {\n            _aether.logStatementStart([{ofs: 4434, row: 128, col: 7}, {ofs: 4515, row: 128, col: 88}]); tmp383 = tmp384;  _aether.logStatement([{ofs: 4434, row: 128, col: 7}, {ofs: 4515, row: 128, col: 88}], _aether._userInfo, false);\n        }\n        if (tmp383) {\n            tmp402 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n            tmp403 = 'build';\n            _aether.logStatementStart([{ofs: 4538, row: 129, col: 19}, {ofs: 4546, row: 129, col: 27}]); tmp404 = 'archer';  _aether.logStatement([{ofs: 4538, row: 129, col: 19}, {ofs: 4546, row: 129, col: 27}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 4527, row: 129, col: 8}, {ofs: 4547, row: 129, col: 28}]); tmp405 = _aether.createAPIClone(_aether, tmp402[tmp403](_aether.restoreAPIClone(_aether, tmp404)));  _aether.logStatement([{ofs: 4527, row: 129, col: 8}, {ofs: 4547, row: 129, col: 28}], _aether._userInfo, false);\n            _aether.logCallEnd(); return;\n        } else {\n            ;\n        }\n        tmp412 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n        tmp413 = 'enemies';\n        _aether.logStatementStart([{ofs: 4580, row: 134, col: 4}, {ofs: 4592, row: 134, col: 16}]); tmp410 = tmp412[tmp413];  _aether.logStatement([{ofs: 4580, row: 134, col: 4}, {ofs: 4592, row: 134, col: 16}], _aether._userInfo, false);\n        tmp411 = 'length';\n        _aether.logStatementStart([{ofs: 4580, row: 134, col: 4}, {ofs: 4599, row: 134, col: 23}]); tmp408 = tmp410[tmp411];  _aether.logStatement([{ofs: 4580, row: 134, col: 4}, {ofs: 4599, row: 134, col: 23}], _aether._userInfo, false);\n        _aether.logStatementStart([{ofs: 4603, row: 134, col: 27}, {ofs: 4604, row: 134, col: 28}]); tmp409 = 3;  _aether.logStatement([{ofs: 4603, row: 134, col: 27}, {ofs: 4604, row: 134, col: 28}], _aether._userInfo, false);\n        _aether.logStatementStart([{ofs: 4580, row: 134, col: 4}, {ofs: 4604, row: 134, col: 28}]); tmp407 = tmp408 >= tmp409;  _aether.logStatement([{ofs: 4580, row: 134, col: 4}, {ofs: 4604, row: 134, col: 28}], _aether._userInfo, false);\n        if (tmp407) {\n            tmp415 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n            tmp416 = 'noArcher';\n            _aether.logStatementStart([{ofs: 4609, row: 134, col: 33}, {ofs: 4622, row: 134, col: 46}]); tmp414 = tmp415[tmp416];  _aether.logStatement([{ofs: 4609, row: 134, col: 33}, {ofs: 4622, row: 134, col: 46}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 4608, row: 134, col: 32}, {ofs: 4622, row: 134, col: 46}]); tmp406 = !tmp414;  _aether.logStatement([{ofs: 4608, row: 134, col: 32}, {ofs: 4622, row: 134, col: 46}], _aether._userInfo, false);\n        } else {\n            _aether.logStatementStart([{ofs: 4580, row: 134, col: 4}, {ofs: 4622, row: 134, col: 46}]); tmp406 = tmp407;  _aether.logStatement([{ofs: 4580, row: 134, col: 4}, {ofs: 4622, row: 134, col: 46}], _aether._userInfo, false);\n        }\n        if (tmp406) {\n            _aether.logStatementStart([{ofs: 4630, row: 135, col: 4}, {ofs: 4644, row: 135, col: 18}]); count = 0;  _aether.logStatement([{ofs: 4630, row: 135, col: 4}, {ofs: 4644, row: 135, col: 18}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 4649, row: 136, col: 4}, {ofs: 4664, row: 136, col: 19}]); ranged = 0;  _aether.logStatement([{ofs: 4649, row: 136, col: 4}, {ofs: 4664, row: 136, col: 19}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 4674, row: 137, col: 9}, {ofs: 4683, row: 137, col: 18}]); i = 1;  _aether.logStatement([{ofs: 4674, row: 137, col: 9}, {ofs: 4683, row: 137, col: 18}], _aether._userInfo, false);\n            tmp418 = i;\n            tmp422 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n            tmp423 = 'enemies';\n            _aether.logStatementStart([{ofs: 4689, row: 137, col: 24}, {ofs: 4701, row: 137, col: 36}]); tmp420 = tmp422[tmp423];  _aether.logStatement([{ofs: 4689, row: 137, col: 24}, {ofs: 4701, row: 137, col: 36}], _aether._userInfo, false);\n            tmp421 = 'length';\n            _aether.logStatementStart([{ofs: 4689, row: 137, col: 24}, {ofs: 4708, row: 137, col: 43}]); tmp419 = tmp420[tmp421];  _aether.logStatement([{ofs: 4689, row: 137, col: 24}, {ofs: 4708, row: 137, col: 43}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 4685, row: 137, col: 20}, {ofs: 4708, row: 137, col: 43}]); tmp417 = tmp418 < tmp419;  _aether.logStatement([{ofs: 4685, row: 137, col: 20}, {ofs: 4708, row: 137, col: 43}], _aether._userInfo, false);\n            tmp432: {\n                while (tmp417) {\n                    tmp433: {\n                        tmp440 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n                        tmp441 = 'enemies';\n                        _aether.logStatementStart([{ofs: 4729, row: 138, col: 12}, {ofs: 4741, row: 138, col: 24}]); tmp438 = tmp440[tmp441];  _aether.logStatement([{ofs: 4729, row: 138, col: 12}, {ofs: 4741, row: 138, col: 24}], _aether._userInfo, false);\n                        tmp439 = i;\n                        _aether.logStatementStart([{ofs: 4729, row: 138, col: 12}, {ofs: 4744, row: 138, col: 27}]); tmp436 = tmp438[tmp439];  _aether.logStatement([{ofs: 4729, row: 138, col: 12}, {ofs: 4744, row: 138, col: 27}], _aether._userInfo, false);\n                        tmp437 = 'target';\n                        _aether.logStatementStart([{ofs: 4729, row: 138, col: 12}, {ofs: 4751, row: 138, col: 34}]); tmp435 = tmp436[tmp437];  _aether.logStatement([{ofs: 4729, row: 138, col: 12}, {ofs: 4751, row: 138, col: 34}], _aether._userInfo, false);\n                        if (tmp435) {\n                            tmp450 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n                            tmp451 = 'enemies';\n                            _aether.logStatementStart([{ofs: 4755, row: 138, col: 38}, {ofs: 4767, row: 138, col: 50}]); tmp448 = tmp450[tmp451];  _aether.logStatement([{ofs: 4755, row: 138, col: 38}, {ofs: 4767, row: 138, col: 50}], _aether._userInfo, false);\n                            tmp449 = i;\n                            _aether.logStatementStart([{ofs: 4755, row: 138, col: 38}, {ofs: 4770, row: 138, col: 53}]); tmp446 = tmp448[tmp449];  _aether.logStatement([{ofs: 4755, row: 138, col: 38}, {ofs: 4770, row: 138, col: 53}], _aether._userInfo, false);\n                            tmp447 = 'target';\n                            _aether.logStatementStart([{ofs: 4755, row: 138, col: 38}, {ofs: 4777, row: 138, col: 60}]); tmp444 = tmp446[tmp447];  _aether.logStatement([{ofs: 4755, row: 138, col: 38}, {ofs: 4777, row: 138, col: 60}], _aether._userInfo, false);\n                            tmp445 = 'type';\n                            _aether.logStatementStart([{ofs: 4755, row: 138, col: 38}, {ofs: 4782, row: 138, col: 65}]); tmp442 = tmp444[tmp445];  _aether.logStatement([{ofs: 4755, row: 138, col: 38}, {ofs: 4782, row: 138, col: 65}], _aether._userInfo, false);\n                            _aether.logStatementStart([{ofs: 4787, row: 138, col: 70}, {ofs: 4793, row: 138, col: 76}]); tmp443 = 'base';  _aether.logStatement([{ofs: 4787, row: 138, col: 70}, {ofs: 4793, row: 138, col: 76}], _aether._userInfo, false);\n                            _aether.logStatementStart([{ofs: 4755, row: 138, col: 38}, {ofs: 4793, row: 138, col: 76}]); tmp434 = tmp442 === tmp443;  _aether.logStatement([{ofs: 4755, row: 138, col: 38}, {ofs: 4793, row: 138, col: 76}], _aether._userInfo, false);\n                        } else {\n                            _aether.logStatementStart([{ofs: 4729, row: 138, col: 12}, {ofs: 4793, row: 138, col: 76}]); tmp434 = tmp435;  _aether.logStatement([{ofs: 4729, row: 138, col: 12}, {ofs: 4793, row: 138, col: 76}], _aether._userInfo, false);\n                        }\n                        if (tmp434) {\n                            _aether.logStatementStart([{ofs: 4809, row: 139, col: 12}, {ofs: 4820, row: 139, col: 23}]); tmp452 = 1;  _aether.logStatement([{ofs: 4809, row: 139, col: 12}, {ofs: 4820, row: 139, col: 23}], _aether._userInfo, false);\n                            tmp453 = count;\n                            tmp454 = tmp452;\n                            count = tmp453 + tmp454;\n                        } else {\n                            ;\n                        }\n                        tmp462 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n                        tmp463 = 'enemies';\n                        _aether.logStatementStart([{ofs: 4843, row: 141, col: 12}, {ofs: 4855, row: 141, col: 24}]); tmp460 = tmp462[tmp463];  _aether.logStatement([{ofs: 4843, row: 141, col: 12}, {ofs: 4855, row: 141, col: 24}], _aether._userInfo, false);\n                        tmp461 = i;\n                        _aether.logStatementStart([{ofs: 4843, row: 141, col: 12}, {ofs: 4858, row: 141, col: 27}]); tmp458 = tmp460[tmp461];  _aether.logStatement([{ofs: 4843, row: 141, col: 12}, {ofs: 4858, row: 141, col: 27}], _aether._userInfo, false);\n                        tmp459 = 'type';\n                        _aether.logStatementStart([{ofs: 4843, row: 141, col: 12}, {ofs: 4863, row: 141, col: 32}]); tmp456 = tmp458[tmp459];  _aether.logStatement([{ofs: 4843, row: 141, col: 12}, {ofs: 4863, row: 141, col: 32}], _aether._userInfo, false);\n                        _aether.logStatementStart([{ofs: 4868, row: 141, col: 37}, {ofs: 4877, row: 141, col: 46}]); tmp457 = 'thrower';  _aether.logStatement([{ofs: 4868, row: 141, col: 37}, {ofs: 4877, row: 141, col: 46}], _aether._userInfo, false);\n                        _aether.logStatementStart([{ofs: 4843, row: 141, col: 12}, {ofs: 4877, row: 141, col: 46}]); tmp455 = tmp456 === tmp457;  _aether.logStatement([{ofs: 4843, row: 141, col: 12}, {ofs: 4877, row: 141, col: 46}], _aether._userInfo, false);\n                        if (tmp455) {\n                            _aether.logStatementStart([{ofs: 4893, row: 142, col: 12}, {ofs: 4905, row: 142, col: 24}]); tmp464 = 1;  _aether.logStatement([{ofs: 4893, row: 142, col: 12}, {ofs: 4905, row: 142, col: 24}], _aether._userInfo, false);\n                            tmp465 = ranged;\n                            tmp466 = tmp464;\n                            ranged = tmp465 + tmp466;\n                        } else {\n                            ;\n                        }\n                    }\n                    tmp430 = i;\n                    tmp431 = 1;\n                    i = tmp430 + tmp431;\n                    tmp424 = i;\n                    tmp428 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n                    tmp429 = 'enemies';\n                    _aether.logStatementStart([{ofs: 4689, row: 137, col: 24}, {ofs: 4701, row: 137, col: 36}]); tmp426 = tmp428[tmp429];  _aether.logStatement([{ofs: 4689, row: 137, col: 24}, {ofs: 4701, row: 137, col: 36}], _aether._userInfo, false);\n                    tmp427 = 'length';\n                    _aether.logStatementStart([{ofs: 4689, row: 137, col: 24}, {ofs: 4708, row: 137, col: 43}]); tmp425 = tmp426[tmp427];  _aether.logStatement([{ofs: 4689, row: 137, col: 24}, {ofs: 4708, row: 137, col: 43}], _aether._userInfo, false);\n                    _aether.logStatementStart([{ofs: 4685, row: 137, col: 20}, {ofs: 4708, row: 137, col: 43}]); tmp417 = tmp424 < tmp425;  _aether.logStatement([{ofs: 4685, row: 137, col: 20}, {ofs: 4708, row: 137, col: 43}], _aether._userInfo, false);\n                }\n            }\n            tmp469 = count;\n            tmp475 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n            tmp476 = 'enemies';\n            _aether.logStatementStart([{ofs: 4939, row: 145, col: 17}, {ofs: 4951, row: 145, col: 29}]); tmp473 = tmp475[tmp476];  _aether.logStatement([{ofs: 4939, row: 145, col: 17}, {ofs: 4951, row: 145, col: 29}], _aether._userInfo, false);\n            tmp474 = 'length';\n            _aether.logStatementStart([{ofs: 4939, row: 145, col: 17}, {ofs: 4958, row: 145, col: 36}]); tmp471 = tmp473[tmp474];  _aether.logStatement([{ofs: 4939, row: 145, col: 17}, {ofs: 4958, row: 145, col: 36}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 4961, row: 145, col: 39}, {ofs: 4962, row: 145, col: 40}]); tmp472 = 2;  _aether.logStatement([{ofs: 4961, row: 145, col: 39}, {ofs: 4962, row: 145, col: 40}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 4939, row: 145, col: 17}, {ofs: 4962, row: 145, col: 40}]); tmp470 = tmp471 - tmp472;  _aether.logStatement([{ofs: 4939, row: 145, col: 17}, {ofs: 4962, row: 145, col: 40}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 4930, row: 145, col: 8}, {ofs: 4962, row: 145, col: 40}]); tmp468 = tmp469 >= tmp470;  _aether.logStatement([{ofs: 4930, row: 145, col: 8}, {ofs: 4962, row: 145, col: 40}], _aether._userInfo, false);\n            if (tmp468) {\n                tmp477 = ranged;\n                _aether.logStatementStart([{ofs: 4976, row: 145, col: 54}, {ofs: 4977, row: 145, col: 55}]); tmp478 = 1;  _aether.logStatement([{ofs: 4976, row: 145, col: 54}, {ofs: 4977, row: 145, col: 55}], _aether._userInfo, false);\n                _aether.logStatementStart([{ofs: 4966, row: 145, col: 44}, {ofs: 4977, row: 145, col: 55}]); tmp467 = tmp477 >= tmp478;  _aether.logStatement([{ofs: 4966, row: 145, col: 44}, {ofs: 4977, row: 145, col: 55}], _aether._userInfo, false);\n            } else {\n                _aether.logStatementStart([{ofs: 4930, row: 145, col: 8}, {ofs: 4977, row: 145, col: 55}]); tmp467 = tmp468;  _aether.logStatement([{ofs: 4930, row: 145, col: 8}, {ofs: 4977, row: 145, col: 55}], _aether._userInfo, false);\n            }\n            if (tmp467) {\n                tmp479 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n                tmp480 = 'archers';\n                _aether.logStatementStart([{ofs: 4989, row: 146, col: 8}, {ofs: 5009, row: 146, col: 28}]); tmp481 = true;  _aether.logStatement([{ofs: 4989, row: 146, col: 8}, {ofs: 5009, row: 146, col: 28}], _aether._userInfo, false);\n                _aether.logStatementStart([{ofs: 4989, row: 146, col: 8}, {ofs: 5008, row: 146, col: 27}]); tmp479[tmp480] = tmp481;  _aether.logStatement([{ofs: 4989, row: 146, col: 8}, {ofs: 5008, row: 146, col: 27}], _aether._userInfo, false);\n            } else {\n                ;\n            }\n        } else {\n            ;\n        }\n        tmp482 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n        tmp483 = 'build';\n        _aether.logStatementStart([{ofs: 5060, row: 150, col: 11}, {ofs: 5069, row: 150, col: 20}]); tmp484 = 'soldier';  _aether.logStatement([{ofs: 5060, row: 150, col: 11}, {ofs: 5069, row: 150, col: 20}], _aether._userInfo, false);\n        _aether.logStatementStart([{ofs: 5049, row: 150, col: 0}, {ofs: 5070, row: 150, col: 21}]); tmp485 = _aether.createAPIClone(_aether, tmp482[tmp483](_aether.restoreAPIClone(_aether, tmp484)));  _aether.logStatement([{ofs: 5049, row: 150, col: 0}, {ofs: 5070, row: 150, col: 21}], _aether._userInfo, false);\n        _aether.logCallEnd(); return;\n    };\n    tmp0 = 'chooseAction';\n    __global[tmp0] = tmp1;\n}(this));"
         },
         "programmable-tharin": {
-          "chooseAction": "..."
+          "chooseAction": "var __interceptThis=(function(){var G=this;return function($this,sandbox){if($this==G){return sandbox;}return $this;};})();\nreturn (function (__global) {\n    var tmp0, tmp1;\n    tmp1 = function () {\n        'use strict'; _aether.logCallStart(_aether._userInfo); var tUnit, tmp2, tmp3, tmp4, tmp45, tmp46, tmp47, tmp79, tmp80, tmp81, tmp186, tmp187, tmp188, tmp239, tmp240, tmp241, tmp273, tmp274, tmp275, tmp324, tmp325, tmp326, tmp376, tmp377, tmp378, tmp428, tmp429, tmp430, tmp494, tmp495, tmp496, tmp623, tmp624, tmp625, tmp626, tmp627, tmp628, tmp629, tmp630, tmp631, tmp632, tmp633, tmp634, tmp635, tmp636, tmp637, tmp638, tmp639, tmp640, tmp641, tmp642, tmp643, tmp644, tmp645, tmp646, tmp647, tmp648, tmp649, tmp650, tmp651, tmp652, tmp653, tmp654, tmp655, tmp656, tmp657, tmp658, tmp659, tmp660, tmp661, tmp662, tmp663, tmp664, tmp665, tmp666, tmp667, tmp668, tmp669, tmp670, tmp671, tmp672, tmp673, tmp674, tmp675, tmp676, tmp677, tmp678, tmp679, tmp680, tmp681, tmp682, tmp683, tmp684, tmp685, tmp686, tmp687, tmp688, tmp689, tmp690, tmp691, tmp692, tmp693, tmp694, tmp695, tmp696, tmp697, tmp698, tmp699, tmp700, tmp701, tmp702, tmp703, tmp704, tmp705, tmp706, tmp707, tmp708, tmp709, tmp710, tmp711, tmp712, tmp713, tmp714, tmp715, tmp716, tmp717, tmp718, tmp719, tmp720, tmp721, tmp722, tmp723, tmp724, tmp725, tmp726, tmp727, tmp728, tmp729, tmp730, tmp731, tmp732, tmp733, tmp734, tmp735, tmp736, tmp737, tmp738, tmp739, tmp740, tmp741, tmp742, tmp743, tmp744, tmp745, tmp746, tmp747, tmp748, tmp749, tmp750, tmp751, tmp752, tmp753, tmp754, tmp755, tmp756, tmp757, tmp758, tmp759, tmp760, tmp761, tmp762, tmp763, tmp764, tmp765, tmp766, tmp767, tmp768, tmp769, tmp770, tmp771, tmp772, tmp773, tmp774, tmp775, tmp776, tmp777, tmp778, tmp779, tmp780, tmp781, tmp782, tmp783, tmp784, tmp785, tmp786, tmp787, tmp788, tmp789, tmp790, tmp791, tmp792, tmp793, tmp794, tmp795, tmp796, tmp797, tmp798, tmp799, tmp800, tmp801, tmp802, tmp803, tmp804, tmp805, tmp806, tmp807, tmp808, tmp809, tmp810, tmp811, tmp812, tmp813, tmp814, tmp815, tmp816, tmp817, tmp818, tmp819, tmp820, tmp821, tmp822, tmp823, tmp824, tmp825, tmp826, tmp827, tmp828, tmp829, tmp830, tmp831, tmp832, tmp833, tmp834, tmp835, tmp836, tmp837, tmp838, tmp839, tmp840, tmp841, tmp842, tmp843, tmp844, tmp845, tmp846, tmp847, tmp848, tmp849, tmp850, tmp851, tmp852, tmp853, tmp854, tmp855, tmp856, tmp857, tmp858, tmp859, tmp860, tmp861, tmp862, tmp863, tmp864, tmp865, tmp866, tmp867, tmp868, tmp869, tmp870, tmp871, tmp872, tmp873, tmp874, tmp875, tmp876, tmp877, tmp878, tmp879, tmp880, tmp881, tmp882, tmp883, tmp884, tmp885, tmp886, tmp887, tmp888, tmp889, tmp890, tmp891, tmp892, tmp893, tmp894, tmp895, tmp896, tmp897, tmp898, tmp899, tmp900, tmp901, tmp902, tmp903, tmp904, tmp905, tmp906, tmp907, tmp908, tmp909, tmp910, tmp911, tmp912, tmp913, tmp914, tmp915, tmp916, tmp917, tmp918, tmp919, tmp920, tmp921, tmp922, tmp923, tmp924, tmp925, tmp926, tmp927, tmp928, tmp929, tmp930, tmp931, tmp932, tmp933, tmp934, tmp935, tmp936, tmp937, tmp938, tmp939, tmp940, tmp941, tmp942, tmp943, tmp944, tmp945, tmp946, tmp947, tmp948, tmp949, tmp950, tmp951, tmp952, tmp953, tmp954, tmp955, tmp956, tmp957, tmp958, tmp959, tmp960, tmp961, tmp962, tmp963, tmp964, tmp965, tmp966, tmp967, tmp968, tmp969, tmp970, tmp971, tmp972, tmp973, tmp974, tmp975, tmp976, tmp977, tmp978, tmp979, tmp980, tmp981, tmp982, tmp983, tmp984, tmp985, tmp986, tmp987, tmp988, tmp989, tmp990, tmp991, tmp992, tmp993, tmp994, tmp995, tmp996, tmp997, tmp998, tmp999, tmp1000, tmp1001, tmp1002, tmp1003, tmp1004, tmp1005, tmp1006, tmp1007, tmp1008, tmp1009, tmp1010, tmp1011, tmp1012, tmp1013, tmp1014, tmp1015, tmp1016, tmp1017, tmp1018, tmp1019, tmp1020, tmp1021, tmp1022, tmp1023, tmp1024, tmp1025, tmp1026, tmp1027, tmp1028, tmp1029, tmp1030, tmp1031, tmp1032, tmp1033, tmp1034, tmp1035, tmp1036, tmp1037, tmp1038, tmp1039, tmp1040, tmp1041, tmp1042, tmp1043, tmp1044, tmp1045, tmp1046, tmp1047, tmp1048, tmp1049, tmp1050, tmp1051, tmp1052, tmp1053, tmp1054, tmp1055, tmp1056, tmp1057, tmp1058, tmp1059, tmp1060, tmp1061, tmp1062, tmp1063, tmp1064, tmp1065, tmp1066, tmp1067, tmp1068, tmp1069, tmp1070, tmp1071, tmp1072, tmp1073, tmp1074, tmp1075, tmp1076, tmp1077, tmp1078, tmp1079, tmp1080, tmp1081, tmp1082, tmp1083, tmp1084, tmp1085, tmp1086, tmp1087, tmp1088, tmp1089, tmp1090, tmp1091, tmp1092, tmp1093, tmp1094, tmp1095, tmp1096, tmp1097, tmp1098, tmp1099, tmp1100, tmp1101, tmp1102, tmp1103, tmp1104, tmp1105, tmp1106, tmp1107, tmp1108, tmp1109, tmp1110, tmp1111, tmp1112, tmp1113, tmp1114, tmp1115, tmp1116, tmp1117, tmp1118, tmp1119, tmp1120, tmp1121, tmp1122, tmp1123, tmp1124, tmp1125, tmp1126, tmp1127, tmp1128, tmp1129, tmp1130, tmp1131, tmp1132, tmp1133, tmp1134, tmp1135, tmp1136, tmp1137, tmp1138, tmp1139, tmp1140, tmp1141, tmp1142, tmp1143, tmp1144, tmp1145, tmp1146, tmp1147, tmp1148, tmp1149, tmp1150, tmp1151, tmp1152, tmp1153, tmp1154, tmp1155, tmp1156, tmp1157, tmp1158, tmp1159, tmp1160, tmp1161, tmp1162, tmp1163, tmp1164, tmp1165, tmp1166, tmp1167, tmp1168, tmp1169, tmp1170, tmp1171, tmp1172, tmp1173, tmp1174, tmp1175, tmp1176, tmp1177, tmp1178, tmp1179, tmp1180, tmp1181, tmp1182, tmp1183, tmp1184, tmp1185, tmp1186, tmp1187, tmp1188, tmp1189, tmp1190, tmp1191, tmp1192, tmp1193, tmp1194, tmp1195, tmp1196, tmp1197, tmp1198, tmp1199, tmp1200, tmp1201, tmp1202, tmp1203, tmp1204, tmp1205, tmp1206, tmp1207, tmp1208, tmp1209, tmp1210, tmp1211, tmp1212, tmp1213, tmp1214, tmp1215, tmp1216, tmp1217, tmp1218, tmp1219, tmp1220, tmp1221, tmp1222, tmp1223, tmp1224, tmp1225, tmp1226, tmp1227, tmp1228, tmp1229, tmp1230, tmp1231, tmp1232, tmp1233, tmp1234, tmp1235, tmp1236, tmp1237, tmp1238, tmp1239, tmp1240, tmp1241, tmp1242, tmp1243, tmp1244, tmp1245, tmp1246, tmp1247, tmp1248, tmp1249, tmp1250, tmp1251, tmp1252, tmp1253, tmp1254, tmp1255, tmp1256, tmp1257, tmp1258, tmp1259, tmp1260, tmp1261, tmp1262, tmp1263, tmp1264, tmp1265, tmp1266, tmp1267, tmp1268, tmp1269, tmp1270, tmp1271, tmp1272, tmp1273, tmp1274, tmp1275;  for(var __argIndexer = 0; __argIndexer < arguments.length; ++__argIndexer) arguments[__argIndexer] = _aether.createAPIClone(_aether, arguments[__argIndexer]);\n        tmp2 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n        tmp3 = 'getEnemyHero';\n        _aether.logStatementStart([{ofs: 0, row: 0, col: 0}, {ofs: 264, row: 7, col: 2}]); tmp4 = function () {\n            var i, tmp5, tmp6, tmp7, tmp8, tmp9, tmp10, tmp11, tmp12, tmp13, tmp14, tmp15, tmp16, tmp17, tmp18, tmp19, tmp22, tmp23, tmp24, tmp25, tmp26, tmp27, tmp28, tmp29, tmp30, tmp31, tmp32, tmp33, tmp34, tmp35, tmp36, tmp37, tmp38, tmp39, tmp40, tmp41, tmp42, tmp43, tmp44;  for(var __argIndexer = 0; __argIndexer < arguments.length; ++__argIndexer) arguments[__argIndexer] = _aether.createAPIClone(_aether, arguments[__argIndexer]);\n            _aether.logStatementStart([{ofs: 81, row: 2, col: 8}, {ofs: 90, row: 2, col: 17}]); i = 0;  _aether.logStatement([{ofs: 81, row: 2, col: 8}, {ofs: 90, row: 2, col: 17}], _aether._userInfo, false);\n            tmp6 = i;\n            tmp10 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n            tmp11 = 'enemies';\n            _aether.logStatementStart([{ofs: 96, row: 2, col: 23}, {ofs: 108, row: 2, col: 35}]); tmp8 = tmp10[tmp11];  _aether.logStatement([{ofs: 96, row: 2, col: 23}, {ofs: 108, row: 2, col: 35}], _aether._userInfo, false);\n            tmp9 = 'length';\n            _aether.logStatementStart([{ofs: 96, row: 2, col: 23}, {ofs: 115, row: 2, col: 42}]); tmp7 = tmp8[tmp9];  _aether.logStatement([{ofs: 96, row: 2, col: 23}, {ofs: 115, row: 2, col: 42}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 92, row: 2, col: 19}, {ofs: 115, row: 2, col: 42}]); tmp5 = tmp6 < tmp7;  _aether.logStatement([{ofs: 92, row: 2, col: 19}, {ofs: 115, row: 2, col: 42}], _aether._userInfo, false);\n            tmp20: {\n                while (tmp5) {\n                    tmp21: {\n                        tmp30 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n                        tmp31 = 'enemies';\n                        _aether.logStatementStart([{ofs: 135, row: 3, col: 11}, {ofs: 147, row: 3, col: 23}]); tmp28 = tmp30[tmp31];  _aether.logStatement([{ofs: 135, row: 3, col: 11}, {ofs: 147, row: 3, col: 23}], _aether._userInfo, false);\n                        tmp29 = i;\n                        _aether.logStatementStart([{ofs: 135, row: 3, col: 11}, {ofs: 150, row: 3, col: 26}]); tmp26 = tmp28[tmp29];  _aether.logStatement([{ofs: 135, row: 3, col: 11}, {ofs: 150, row: 3, col: 26}], _aether._userInfo, false);\n                        tmp27 = 'type';\n                        _aether.logStatementStart([{ofs: 135, row: 3, col: 11}, {ofs: 155, row: 3, col: 31}]); tmp24 = tmp26[tmp27];  _aether.logStatement([{ofs: 135, row: 3, col: 11}, {ofs: 155, row: 3, col: 31}], _aether._userInfo, false);\n                        _aether.logStatementStart([{ofs: 160, row: 3, col: 36}, {ofs: 169, row: 3, col: 45}]); tmp25 = 'brawler';  _aether.logStatement([{ofs: 160, row: 3, col: 36}, {ofs: 169, row: 3, col: 45}], _aether._userInfo, false);\n                        _aether.logStatementStart([{ofs: 135, row: 3, col: 11}, {ofs: 169, row: 3, col: 45}]); tmp23 = tmp24 === tmp25;  _aether.logStatement([{ofs: 135, row: 3, col: 11}, {ofs: 169, row: 3, col: 45}], _aether._userInfo, false);\n                        if (tmp23) {\n                            _aether.logStatementStart([{ofs: 135, row: 3, col: 11}, {ofs: 206, row: 3, col: 82}]); tmp22 = tmp23;  _aether.logStatement([{ofs: 135, row: 3, col: 11}, {ofs: 206, row: 3, col: 82}], _aether._userInfo, false);\n                        } else {\n                            tmp38 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n                            tmp39 = 'enemies';\n                            _aether.logStatementStart([{ofs: 173, row: 3, col: 49}, {ofs: 185, row: 3, col: 61}]); tmp36 = tmp38[tmp39];  _aether.logStatement([{ofs: 173, row: 3, col: 49}, {ofs: 185, row: 3, col: 61}], _aether._userInfo, false);\n                            tmp37 = i;\n                            _aether.logStatementStart([{ofs: 173, row: 3, col: 49}, {ofs: 188, row: 3, col: 64}]); tmp34 = tmp36[tmp37];  _aether.logStatement([{ofs: 173, row: 3, col: 49}, {ofs: 188, row: 3, col: 64}], _aether._userInfo, false);\n                            tmp35 = 'type';\n                            _aether.logStatementStart([{ofs: 173, row: 3, col: 49}, {ofs: 193, row: 3, col: 69}]); tmp32 = tmp34[tmp35];  _aether.logStatement([{ofs: 173, row: 3, col: 49}, {ofs: 193, row: 3, col: 69}], _aether._userInfo, false);\n                            _aether.logStatementStart([{ofs: 198, row: 3, col: 74}, {ofs: 206, row: 3, col: 82}]); tmp33 = 'shaman';  _aether.logStatement([{ofs: 198, row: 3, col: 74}, {ofs: 206, row: 3, col: 82}], _aether._userInfo, false);\n                            _aether.logStatementStart([{ofs: 173, row: 3, col: 49}, {ofs: 206, row: 3, col: 82}]); tmp22 = tmp32 === tmp33;  _aether.logStatement([{ofs: 173, row: 3, col: 49}, {ofs: 206, row: 3, col: 82}], _aether._userInfo, false);\n                        }\n                        if (tmp22) {\n                            tmp43 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n                            tmp44 = 'enemies';\n                            _aether.logStatementStart([{ofs: 229, row: 4, col: 19}, {ofs: 241, row: 4, col: 31}]); tmp41 = tmp43[tmp44];  _aether.logStatement([{ofs: 229, row: 4, col: 19}, {ofs: 241, row: 4, col: 31}], _aether._userInfo, false);\n                            tmp42 = i;\n                            _aether.logStatementStart([{ofs: 229, row: 4, col: 19}, {ofs: 244, row: 4, col: 34}]); tmp40 = tmp41[tmp42];  _aether.logStatement([{ofs: 229, row: 4, col: 19}, {ofs: 244, row: 4, col: 34}], _aether._userInfo, false);\n                            return _aether.restoreAPIClone(_aether, tmp40);\n                        } else {\n                            ;\n                        }\n                    }\n                    tmp18 = i;\n                    tmp19 = 1;\n                    i = tmp18 + tmp19;\n                    tmp12 = i;\n                    tmp16 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n                    tmp17 = 'enemies';\n                    _aether.logStatementStart([{ofs: 96, row: 2, col: 23}, {ofs: 108, row: 2, col: 35}]); tmp14 = tmp16[tmp17];  _aether.logStatement([{ofs: 96, row: 2, col: 23}, {ofs: 108, row: 2, col: 35}], _aether._userInfo, false);\n                    tmp15 = 'length';\n                    _aether.logStatementStart([{ofs: 96, row: 2, col: 23}, {ofs: 115, row: 2, col: 42}]); tmp13 = tmp14[tmp15];  _aether.logStatement([{ofs: 96, row: 2, col: 23}, {ofs: 115, row: 2, col: 42}], _aether._userInfo, false);\n                    _aether.logStatementStart([{ofs: 92, row: 2, col: 19}, {ofs: 115, row: 2, col: 42}]); tmp5 = tmp12 < tmp13;  _aether.logStatement([{ofs: 92, row: 2, col: 19}, {ofs: 115, row: 2, col: 42}], _aether._userInfo, false);\n                }\n            }\n            return;\n        };  _aether.logStatement([{ofs: 0, row: 0, col: 0}, {ofs: 264, row: 7, col: 2}], _aether._userInfo, false);\n        _aether.logStatementStart([{ofs: 0, row: 0, col: 0}, {ofs: 263, row: 7, col: 1}]); tmp2[tmp3] = tmp4;  _aether.logStatement([{ofs: 0, row: 0, col: 0}, {ofs: 263, row: 7, col: 1}], _aether._userInfo, false);\n        tmp45 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n        tmp46 = 'getEnemyBase';\n        _aether.logStatementStart([{ofs: 266, row: 9, col: 0}, {ofs: 450, row: 15, col: 2}]); tmp47 = function () {\n            var i, tmp48, tmp49, tmp50, tmp51, tmp52, tmp53, tmp54, tmp55, tmp56, tmp57, tmp58, tmp59, tmp60, tmp61, tmp62, tmp65, tmp66, tmp67, tmp68, tmp69, tmp70, tmp71, tmp72, tmp73, tmp74, tmp75, tmp76, tmp77, tmp78;  for(var __argIndexer = 0; __argIndexer < arguments.length; ++__argIndexer) arguments[__argIndexer] = _aether.createAPIClone(_aether, arguments[__argIndexer]);\n            _aether.logStatementStart([{ofs: 307, row: 10, col: 8}, {ofs: 316, row: 10, col: 17}]); i = 0;  _aether.logStatement([{ofs: 307, row: 10, col: 8}, {ofs: 316, row: 10, col: 17}], _aether._userInfo, false);\n            tmp49 = i;\n            tmp53 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n            tmp54 = 'enemies';\n            _aether.logStatementStart([{ofs: 322, row: 10, col: 23}, {ofs: 334, row: 10, col: 35}]); tmp51 = tmp53[tmp54];  _aether.logStatement([{ofs: 322, row: 10, col: 23}, {ofs: 334, row: 10, col: 35}], _aether._userInfo, false);\n            tmp52 = 'length';\n            _aether.logStatementStart([{ofs: 322, row: 10, col: 23}, {ofs: 341, row: 10, col: 42}]); tmp50 = tmp51[tmp52];  _aether.logStatement([{ofs: 322, row: 10, col: 23}, {ofs: 341, row: 10, col: 42}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 318, row: 10, col: 19}, {ofs: 341, row: 10, col: 42}]); tmp48 = tmp49 < tmp50;  _aether.logStatement([{ofs: 318, row: 10, col: 19}, {ofs: 341, row: 10, col: 42}], _aether._userInfo, false);\n            tmp63: {\n                while (tmp48) {\n                    tmp64: {\n                        tmp72 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n                        tmp73 = 'enemies';\n                        _aether.logStatementStart([{ofs: 361, row: 11, col: 11}, {ofs: 373, row: 11, col: 23}]); tmp70 = tmp72[tmp73];  _aether.logStatement([{ofs: 361, row: 11, col: 11}, {ofs: 373, row: 11, col: 23}], _aether._userInfo, false);\n                        tmp71 = i;\n                        _aether.logStatementStart([{ofs: 361, row: 11, col: 11}, {ofs: 376, row: 11, col: 26}]); tmp68 = tmp70[tmp71];  _aether.logStatement([{ofs: 361, row: 11, col: 11}, {ofs: 376, row: 11, col: 26}], _aether._userInfo, false);\n                        tmp69 = 'type';\n                        _aether.logStatementStart([{ofs: 361, row: 11, col: 11}, {ofs: 381, row: 11, col: 31}]); tmp66 = tmp68[tmp69];  _aether.logStatement([{ofs: 361, row: 11, col: 11}, {ofs: 381, row: 11, col: 31}], _aether._userInfo, false);\n                        _aether.logStatementStart([{ofs: 386, row: 11, col: 36}, {ofs: 392, row: 11, col: 42}]); tmp67 = 'base';  _aether.logStatement([{ofs: 386, row: 11, col: 36}, {ofs: 392, row: 11, col: 42}], _aether._userInfo, false);\n                        _aether.logStatementStart([{ofs: 361, row: 11, col: 11}, {ofs: 392, row: 11, col: 42}]); tmp65 = tmp66 === tmp67;  _aether.logStatement([{ofs: 361, row: 11, col: 11}, {ofs: 392, row: 11, col: 42}], _aether._userInfo, false);\n                        if (tmp65) {\n                            tmp77 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n                            tmp78 = 'enemies';\n                            _aether.logStatementStart([{ofs: 415, row: 12, col: 19}, {ofs: 427, row: 12, col: 31}]); tmp75 = tmp77[tmp78];  _aether.logStatement([{ofs: 415, row: 12, col: 19}, {ofs: 427, row: 12, col: 31}], _aether._userInfo, false);\n                            tmp76 = i;\n                            _aether.logStatementStart([{ofs: 415, row: 12, col: 19}, {ofs: 430, row: 12, col: 34}]); tmp74 = tmp75[tmp76];  _aether.logStatement([{ofs: 415, row: 12, col: 19}, {ofs: 430, row: 12, col: 34}], _aether._userInfo, false);\n                            return _aether.restoreAPIClone(_aether, tmp74);\n                        } else {\n                            ;\n                        }\n                    }\n                    tmp61 = i;\n                    tmp62 = 1;\n                    i = tmp61 + tmp62;\n                    tmp55 = i;\n                    tmp59 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n                    tmp60 = 'enemies';\n                    _aether.logStatementStart([{ofs: 322, row: 10, col: 23}, {ofs: 334, row: 10, col: 35}]); tmp57 = tmp59[tmp60];  _aether.logStatement([{ofs: 322, row: 10, col: 23}, {ofs: 334, row: 10, col: 35}], _aether._userInfo, false);\n                    tmp58 = 'length';\n                    _aether.logStatementStart([{ofs: 322, row: 10, col: 23}, {ofs: 341, row: 10, col: 42}]); tmp56 = tmp57[tmp58];  _aether.logStatement([{ofs: 322, row: 10, col: 23}, {ofs: 341, row: 10, col: 42}], _aether._userInfo, false);\n                    _aether.logStatementStart([{ofs: 318, row: 10, col: 19}, {ofs: 341, row: 10, col: 42}]); tmp48 = tmp55 < tmp56;  _aether.logStatement([{ofs: 318, row: 10, col: 19}, {ofs: 341, row: 10, col: 42}], _aether._userInfo, false);\n                }\n            }\n            return;\n        };  _aether.logStatement([{ofs: 266, row: 9, col: 0}, {ofs: 450, row: 15, col: 2}], _aether._userInfo, false);\n        _aether.logStatementStart([{ofs: 266, row: 9, col: 0}, {ofs: 449, row: 15, col: 1}]); tmp45[tmp46] = tmp47;  _aether.logStatement([{ofs: 266, row: 9, col: 0}, {ofs: 449, row: 15, col: 1}], _aether._userInfo, false);\n        tmp79 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n        tmp80 = 'isOpponentBaseRushing';\n        _aether.logStatementStart([{ofs: 452, row: 17, col: 0}, {ofs: 1149, row: 34, col: 2}]); tmp81 = function () {\n            var count, i, tmp82, tmp83, tmp84, tmp85, tmp86, tmp87, tmp88, tmp89, tmp90, tmp91, tmp92, tmp93, tmp94, tmp95, tmp96, tmp97, tmp98, tmp99, tmp100, tmp101, tmp102, tmp103, tmp104, tmp105, tmp106, tmp107, tmp108, tmp109, tmp110, tmp111, tmp112, tmp113, tmp114, tmp115, tmp116, tmp117, tmp118, tmp119, tmp120, tmp121, tmp122, tmp123, tmp126, tmp127, tmp128, tmp129, tmp130, tmp131, tmp132, tmp133, tmp134, tmp135, tmp136, tmp137, tmp138, tmp139, tmp140, tmp141, tmp142, tmp143, tmp144, tmp145, tmp146, tmp147, tmp148, tmp149, tmp150, tmp151, tmp152, tmp153, tmp154, tmp155, tmp156, tmp157, tmp158, tmp159, tmp160, tmp161, tmp162, tmp163, tmp164, tmp165, tmp166, tmp167, tmp168, tmp169, tmp170, tmp171, tmp172, tmp173, tmp174, tmp175, tmp176, tmp177, tmp178, tmp179, tmp180, tmp181, tmp182, tmp183, tmp184, tmp185;  for(var __argIndexer = 0; __argIndexer < arguments.length; ++__argIndexer) arguments[__argIndexer] = _aether.createAPIClone(_aether, arguments[__argIndexer]);\n            _aether.logStatementStart([{ofs: 620, row: 21, col: 4}, {ofs: 634, row: 21, col: 18}]); count = 0;  _aether.logStatement([{ofs: 620, row: 21, col: 4}, {ofs: 634, row: 21, col: 18}], _aether._userInfo, false);\n            tmp85 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n            tmp86 = 'enemyHero';\n            _aether.logStatementStart([{ofs: 642, row: 22, col: 7}, {ofs: 656, row: 22, col: 21}]); tmp84 = tmp85[tmp86];  _aether.logStatement([{ofs: 642, row: 22, col: 7}, {ofs: 656, row: 22, col: 21}], _aether._userInfo, false);\n            if (tmp84) {\n                tmp89 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n                tmp90 = 'enemyHero';\n                _aether.logStatementStart([{ofs: 660, row: 22, col: 25}, {ofs: 674, row: 22, col: 39}]); tmp87 = tmp89[tmp90];  _aether.logStatement([{ofs: 660, row: 22, col: 25}, {ofs: 674, row: 22, col: 39}], _aether._userInfo, false);\n                tmp88 = 'target';\n                _aether.logStatementStart([{ofs: 660, row: 22, col: 25}, {ofs: 681, row: 22, col: 46}]); tmp83 = tmp87[tmp88];  _aether.logStatement([{ofs: 660, row: 22, col: 25}, {ofs: 681, row: 22, col: 46}], _aether._userInfo, false);\n            } else {\n                _aether.logStatementStart([{ofs: 642, row: 22, col: 7}, {ofs: 681, row: 22, col: 46}]); tmp83 = tmp84;  _aether.logStatement([{ofs: 642, row: 22, col: 7}, {ofs: 681, row: 22, col: 46}], _aether._userInfo, false);\n            }\n            if (tmp83) {\n                tmp98 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n                tmp99 = 'enemyHero';\n                _aether.logStatementStart([{ofs: 686, row: 22, col: 51}, {ofs: 700, row: 22, col: 65}]); tmp96 = tmp98[tmp99];  _aether.logStatement([{ofs: 686, row: 22, col: 51}, {ofs: 700, row: 22, col: 65}], _aether._userInfo, false);\n                tmp97 = 'target';\n                _aether.logStatementStart([{ofs: 686, row: 22, col: 51}, {ofs: 707, row: 22, col: 72}]); tmp94 = tmp96[tmp97];  _aether.logStatement([{ofs: 686, row: 22, col: 51}, {ofs: 707, row: 22, col: 72}], _aether._userInfo, false);\n                tmp95 = 'type';\n                _aether.logStatementStart([{ofs: 686, row: 22, col: 51}, {ofs: 712, row: 22, col: 77}]); tmp92 = tmp94[tmp95];  _aether.logStatement([{ofs: 686, row: 22, col: 51}, {ofs: 712, row: 22, col: 77}], _aether._userInfo, false);\n                _aether.logStatementStart([{ofs: 717, row: 22, col: 82}, {ofs: 723, row: 22, col: 88}]); tmp93 = 'base';  _aether.logStatement([{ofs: 717, row: 22, col: 82}, {ofs: 723, row: 22, col: 88}], _aether._userInfo, false);\n                _aether.logStatementStart([{ofs: 686, row: 22, col: 51}, {ofs: 723, row: 22, col: 88}]); tmp91 = tmp92 === tmp93;  _aether.logStatement([{ofs: 686, row: 22, col: 51}, {ofs: 723, row: 22, col: 88}], _aether._userInfo, false);\n                if (tmp91) {\n                    _aether.logStatementStart([{ofs: 686, row: 22, col: 51}, {ofs: 766, row: 22, col: 131}]); tmp82 = tmp91;  _aether.logStatement([{ofs: 686, row: 22, col: 51}, {ofs: 766, row: 22, col: 131}], _aether._userInfo, false);\n                } else {\n                    tmp106 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n                    tmp107 = 'enemyHero';\n                    _aether.logStatementStart([{ofs: 727, row: 22, col: 92}, {ofs: 741, row: 22, col: 106}]); tmp104 = tmp106[tmp107];  _aether.logStatement([{ofs: 727, row: 22, col: 92}, {ofs: 741, row: 22, col: 106}], _aether._userInfo, false);\n                    tmp105 = 'target';\n                    _aether.logStatementStart([{ofs: 727, row: 22, col: 92}, {ofs: 748, row: 22, col: 113}]); tmp102 = tmp104[tmp105];  _aether.logStatement([{ofs: 727, row: 22, col: 92}, {ofs: 748, row: 22, col: 113}], _aether._userInfo, false);\n                    tmp103 = 'type';\n                    _aether.logStatementStart([{ofs: 727, row: 22, col: 92}, {ofs: 753, row: 22, col: 118}]); tmp100 = tmp102[tmp103];  _aether.logStatement([{ofs: 727, row: 22, col: 92}, {ofs: 753, row: 22, col: 118}], _aether._userInfo, false);\n                    _aether.logStatementStart([{ofs: 758, row: 22, col: 123}, {ofs: 766, row: 22, col: 131}]); tmp101 = 'knight';  _aether.logStatement([{ofs: 758, row: 22, col: 123}, {ofs: 766, row: 22, col: 131}], _aether._userInfo, false);\n                    _aether.logStatementStart([{ofs: 727, row: 22, col: 92}, {ofs: 766, row: 22, col: 131}]); tmp82 = tmp100 === tmp101;  _aether.logStatement([{ofs: 727, row: 22, col: 92}, {ofs: 766, row: 22, col: 131}], _aether._userInfo, false);\n                }\n            } else {\n                _aether.logStatementStart([{ofs: 642, row: 22, col: 7}, {ofs: 767, row: 22, col: 132}]); tmp82 = tmp83;  _aether.logStatement([{ofs: 642, row: 22, col: 7}, {ofs: 767, row: 22, col: 132}], _aether._userInfo, false);\n            }\n            if (tmp82) {\n                _aether.logStatementStart([{ofs: 786, row: 23, col: 15}, {ofs: 790, row: 23, col: 19}]); tmp108 = true;  _aether.logStatement([{ofs: 786, row: 23, col: 15}, {ofs: 790, row: 23, col: 19}], _aether._userInfo, false);\n                return _aether.restoreAPIClone(_aether, tmp108);\n            } else {\n                ;\n            }\n            _aether.logStatementStart([{ofs: 806, row: 25, col: 8}, {ofs: 815, row: 25, col: 17}]); i = 1;  _aether.logStatement([{ofs: 806, row: 25, col: 8}, {ofs: 815, row: 25, col: 17}], _aether._userInfo, false);\n            tmp110 = i;\n            tmp114 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n            tmp115 = 'enemies';\n            _aether.logStatementStart([{ofs: 821, row: 25, col: 23}, {ofs: 833, row: 25, col: 35}]); tmp112 = tmp114[tmp115];  _aether.logStatement([{ofs: 821, row: 25, col: 23}, {ofs: 833, row: 25, col: 35}], _aether._userInfo, false);\n            tmp113 = 'length';\n            _aether.logStatementStart([{ofs: 821, row: 25, col: 23}, {ofs: 840, row: 25, col: 42}]); tmp111 = tmp112[tmp113];  _aether.logStatement([{ofs: 821, row: 25, col: 23}, {ofs: 840, row: 25, col: 42}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 817, row: 25, col: 19}, {ofs: 840, row: 25, col: 42}]); tmp109 = tmp110 < tmp111;  _aether.logStatement([{ofs: 817, row: 25, col: 19}, {ofs: 840, row: 25, col: 42}], _aether._userInfo, false);\n            tmp124: {\n                while (tmp109) {\n                    tmp125: {\n                        tmp132 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n                        tmp133 = 'enemies';\n                        _aether.logStatementStart([{ofs: 860, row: 26, col: 11}, {ofs: 872, row: 26, col: 23}]); tmp130 = tmp132[tmp133];  _aether.logStatement([{ofs: 860, row: 26, col: 11}, {ofs: 872, row: 26, col: 23}], _aether._userInfo, false);\n                        tmp131 = i;\n                        _aether.logStatementStart([{ofs: 860, row: 26, col: 11}, {ofs: 875, row: 26, col: 26}]); tmp128 = tmp130[tmp131];  _aether.logStatement([{ofs: 860, row: 26, col: 11}, {ofs: 875, row: 26, col: 26}], _aether._userInfo, false);\n                        tmp129 = 'target';\n                        _aether.logStatementStart([{ofs: 860, row: 26, col: 11}, {ofs: 882, row: 26, col: 33}]); tmp127 = tmp128[tmp129];  _aether.logStatement([{ofs: 860, row: 26, col: 11}, {ofs: 882, row: 26, col: 33}], _aether._userInfo, false);\n                        if (tmp127) {\n                            tmp143 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n                            tmp144 = 'enemies';\n                            _aether.logStatementStart([{ofs: 887, row: 26, col: 38}, {ofs: 899, row: 26, col: 50}]); tmp141 = tmp143[tmp144];  _aether.logStatement([{ofs: 887, row: 26, col: 38}, {ofs: 899, row: 26, col: 50}], _aether._userInfo, false);\n                            tmp142 = i;\n                            _aether.logStatementStart([{ofs: 887, row: 26, col: 38}, {ofs: 902, row: 26, col: 53}]); tmp139 = tmp141[tmp142];  _aether.logStatement([{ofs: 887, row: 26, col: 38}, {ofs: 902, row: 26, col: 53}], _aether._userInfo, false);\n                            tmp140 = 'target';\n                            _aether.logStatementStart([{ofs: 887, row: 26, col: 38}, {ofs: 909, row: 26, col: 60}]); tmp137 = tmp139[tmp140];  _aether.logStatement([{ofs: 887, row: 26, col: 38}, {ofs: 909, row: 26, col: 60}], _aether._userInfo, false);\n                            tmp138 = 'type';\n                            _aether.logStatementStart([{ofs: 887, row: 26, col: 38}, {ofs: 914, row: 26, col: 65}]); tmp135 = tmp137[tmp138];  _aether.logStatement([{ofs: 887, row: 26, col: 38}, {ofs: 914, row: 26, col: 65}], _aether._userInfo, false);\n                            _aether.logStatementStart([{ofs: 919, row: 26, col: 70}, {ofs: 925, row: 26, col: 76}]); tmp136 = 'base';  _aether.logStatement([{ofs: 919, row: 26, col: 70}, {ofs: 925, row: 26, col: 76}], _aether._userInfo, false);\n                            _aether.logStatementStart([{ofs: 887, row: 26, col: 38}, {ofs: 925, row: 26, col: 76}]); tmp134 = tmp135 === tmp136;  _aether.logStatement([{ofs: 887, row: 26, col: 38}, {ofs: 925, row: 26, col: 76}], _aether._userInfo, false);\n                            if (tmp134) {\n                                _aether.logStatementStart([{ofs: 887, row: 26, col: 38}, {ofs: 969, row: 26, col: 120}]); tmp126 = tmp134;  _aether.logStatement([{ofs: 887, row: 26, col: 38}, {ofs: 969, row: 26, col: 120}], _aether._userInfo, false);\n                            } else {\n                                tmp153 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n                                tmp154 = 'enemies';\n                                _aether.logStatementStart([{ofs: 929, row: 26, col: 80}, {ofs: 941, row: 26, col: 92}]); tmp151 = tmp153[tmp154];  _aether.logStatement([{ofs: 929, row: 26, col: 80}, {ofs: 941, row: 26, col: 92}], _aether._userInfo, false);\n                                tmp152 = i;\n                                _aether.logStatementStart([{ofs: 929, row: 26, col: 80}, {ofs: 944, row: 26, col: 95}]); tmp149 = tmp151[tmp152];  _aether.logStatement([{ofs: 929, row: 26, col: 80}, {ofs: 944, row: 26, col: 95}], _aether._userInfo, false);\n                                tmp150 = 'target';\n                                _aether.logStatementStart([{ofs: 929, row: 26, col: 80}, {ofs: 951, row: 26, col: 102}]); tmp147 = tmp149[tmp150];  _aether.logStatement([{ofs: 929, row: 26, col: 80}, {ofs: 951, row: 26, col: 102}], _aether._userInfo, false);\n                                tmp148 = 'type';\n                                _aether.logStatementStart([{ofs: 929, row: 26, col: 80}, {ofs: 956, row: 26, col: 107}]); tmp145 = tmp147[tmp148];  _aether.logStatement([{ofs: 929, row: 26, col: 80}, {ofs: 956, row: 26, col: 107}], _aether._userInfo, false);\n                                _aether.logStatementStart([{ofs: 961, row: 26, col: 112}, {ofs: 969, row: 26, col: 120}]); tmp146 = 'knight';  _aether.logStatement([{ofs: 961, row: 26, col: 112}, {ofs: 969, row: 26, col: 120}], _aether._userInfo, false);\n                                _aether.logStatementStart([{ofs: 929, row: 26, col: 80}, {ofs: 969, row: 26, col: 120}]); tmp126 = tmp145 === tmp146;  _aether.logStatement([{ofs: 929, row: 26, col: 80}, {ofs: 969, row: 26, col: 120}], _aether._userInfo, false);\n                            }\n                        } else {\n                            _aether.logStatementStart([{ofs: 860, row: 26, col: 11}, {ofs: 970, row: 26, col: 121}]); tmp126 = tmp127;  _aether.logStatement([{ofs: 860, row: 26, col: 11}, {ofs: 970, row: 26, col: 121}], _aether._userInfo, false);\n                        }\n                        if (tmp126) {\n                            _aether.logStatementStart([{ofs: 986, row: 27, col: 12}, {ofs: 997, row: 27, col: 23}]); tmp155 = 1;  _aether.logStatement([{ofs: 986, row: 27, col: 12}, {ofs: 997, row: 27, col: 23}], _aether._userInfo, false);\n                            tmp156 = count;\n                            tmp157 = tmp155;\n                            count = tmp156 + tmp157;\n                        } else {\n                            ;\n                        }\n                    }\n                    tmp122 = i;\n                    tmp123 = 1;\n                    i = tmp122 + tmp123;\n                    tmp116 = i;\n                    tmp120 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n                    tmp121 = 'enemies';\n                    _aether.logStatementStart([{ofs: 821, row: 25, col: 23}, {ofs: 833, row: 25, col: 35}]); tmp118 = tmp120[tmp121];  _aether.logStatement([{ofs: 821, row: 25, col: 23}, {ofs: 833, row: 25, col: 35}], _aether._userInfo, false);\n                    tmp119 = 'length';\n                    _aether.logStatementStart([{ofs: 821, row: 25, col: 23}, {ofs: 840, row: 25, col: 42}]); tmp117 = tmp118[tmp119];  _aether.logStatement([{ofs: 821, row: 25, col: 23}, {ofs: 840, row: 25, col: 42}], _aether._userInfo, false);\n                    _aether.logStatementStart([{ofs: 817, row: 25, col: 19}, {ofs: 840, row: 25, col: 42}]); tmp109 = tmp116 < tmp117;  _aether.logStatement([{ofs: 817, row: 25, col: 19}, {ofs: 840, row: 25, col: 42}], _aether._userInfo, false);\n                }\n            }\n            tmp164 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n            tmp165 = 'enemies';\n            _aether.logStatementStart([{ofs: 1021, row: 30, col: 7}, {ofs: 1033, row: 30, col: 19}]); tmp162 = tmp164[tmp165];  _aether.logStatement([{ofs: 1021, row: 30, col: 7}, {ofs: 1033, row: 30, col: 19}], _aether._userInfo, false);\n            tmp163 = 'length';\n            _aether.logStatementStart([{ofs: 1021, row: 30, col: 7}, {ofs: 1040, row: 30, col: 26}]); tmp160 = tmp162[tmp163];  _aether.logStatement([{ofs: 1021, row: 30, col: 7}, {ofs: 1040, row: 30, col: 26}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 1044, row: 30, col: 30}, {ofs: 1045, row: 30, col: 31}]); tmp161 = 3;  _aether.logStatement([{ofs: 1044, row: 30, col: 30}, {ofs: 1045, row: 30, col: 31}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 1021, row: 30, col: 7}, {ofs: 1045, row: 30, col: 31}]); tmp159 = tmp160 >= tmp161;  _aether.logStatement([{ofs: 1021, row: 30, col: 7}, {ofs: 1045, row: 30, col: 31}], _aether._userInfo, false);\n            if (tmp159) {\n                tmp168 = 'Math';\n                tmp169 = tmp168 in __global;\n                if (tmp169) {\n                    tmp166 = __global[tmp168];\n                } else {\n                    tmp170 = 'ReferenceError';\n                    tmp171 = __global[tmp170];\n                    tmp172 = new tmp171();\n                    throw tmp172;\n                }\n                tmp167 = 'ceil';\n                tmp174 = count;\n                tmp182 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n                tmp183 = 'enemies';\n                _aether.logStatementStart([{ofs: 1069, row: 30, col: 55}, {ofs: 1081, row: 30, col: 67}]); tmp180 = tmp182[tmp183];  _aether.logStatement([{ofs: 1069, row: 30, col: 55}, {ofs: 1081, row: 30, col: 67}], _aether._userInfo, false);\n                tmp181 = 'length';\n                _aether.logStatementStart([{ofs: 1069, row: 30, col: 55}, {ofs: 1088, row: 30, col: 74}]); tmp178 = tmp180[tmp181];  _aether.logStatement([{ofs: 1069, row: 30, col: 55}, {ofs: 1088, row: 30, col: 74}], _aether._userInfo, false);\n                _aether.logStatementStart([{ofs: 1091, row: 30, col: 77}, {ofs: 1092, row: 30, col: 78}]); tmp179 = 1;  _aether.logStatement([{ofs: 1091, row: 30, col: 77}, {ofs: 1092, row: 30, col: 78}], _aether._userInfo, false);\n                _aether.logStatementStart([{ofs: 1069, row: 30, col: 55}, {ofs: 1092, row: 30, col: 78}]); tmp176 = tmp178 - tmp179;  _aether.logStatement([{ofs: 1069, row: 30, col: 55}, {ofs: 1092, row: 30, col: 78}], _aether._userInfo, false);\n                _aether.logStatementStart([{ofs: 1096, row: 30, col: 82}, {ofs: 1097, row: 30, col: 83}]); tmp177 = 3;  _aether.logStatement([{ofs: 1096, row: 30, col: 82}, {ofs: 1097, row: 30, col: 83}], _aether._userInfo, false);\n                _aether.logStatementStart([{ofs: 1068, row: 30, col: 54}, {ofs: 1097, row: 30, col: 83}]); tmp175 = tmp176 / tmp177;  _aether.logStatement([{ofs: 1068, row: 30, col: 54}, {ofs: 1097, row: 30, col: 83}], _aether._userInfo, false);\n                _aether.logStatementStart([{ofs: 1059, row: 30, col: 45}, {ofs: 1097, row: 30, col: 83}]); tmp173 = tmp174 >= tmp175;  _aether.logStatement([{ofs: 1059, row: 30, col: 45}, {ofs: 1097, row: 30, col: 83}], _aether._userInfo, false);\n                _aether.logStatementStart([{ofs: 1049, row: 30, col: 35}, {ofs: 1098, row: 30, col: 84}]); tmp158 = _aether.createAPIClone(_aether, tmp166[tmp167](_aether.restoreAPIClone(_aether, tmp173)));  _aether.logStatement([{ofs: 1049, row: 30, col: 35}, {ofs: 1098, row: 30, col: 84}], _aether._userInfo, false);\n            } else {\n                _aether.logStatementStart([{ofs: 1021, row: 30, col: 7}, {ofs: 1098, row: 30, col: 84}]); tmp158 = tmp159;  _aether.logStatement([{ofs: 1021, row: 30, col: 7}, {ofs: 1098, row: 30, col: 84}], _aether._userInfo, false);\n            }\n            if (tmp158) {\n                _aether.logStatementStart([{ofs: 1117, row: 31, col: 15}, {ofs: 1121, row: 31, col: 19}]); tmp184 = true;  _aether.logStatement([{ofs: 1117, row: 31, col: 15}, {ofs: 1121, row: 31, col: 19}], _aether._userInfo, false);\n                return _aether.restoreAPIClone(_aether, tmp184);\n            } else {\n                ;\n            }\n            _aether.logStatementStart([{ofs: 1140, row: 33, col: 11}, {ofs: 1145, row: 33, col: 16}]); tmp185 = false;  _aether.logStatement([{ofs: 1140, row: 33, col: 11}, {ofs: 1145, row: 33, col: 16}], _aether._userInfo, false);\n            return _aether.restoreAPIClone(_aether, tmp185);\n        };  _aether.logStatement([{ofs: 452, row: 17, col: 0}, {ofs: 1149, row: 34, col: 2}], _aether._userInfo, false);\n        _aether.logStatementStart([{ofs: 452, row: 17, col: 0}, {ofs: 1148, row: 34, col: 1}]); tmp79[tmp80] = tmp81;  _aether.logStatement([{ofs: 452, row: 17, col: 0}, {ofs: 1148, row: 34, col: 1}], _aether._userInfo, false);\n        tmp186 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n        tmp187 = 'findTerrifyUnit';\n        _aether.logStatementStart([{ofs: 1151, row: 36, col: 0}, {ofs: 1780, row: 57, col: 2}]); tmp188 = function () {\n            var unit, unitSize, i, tempUnitSize, tmp189, tmp190, tmp191, tmp192, tmp193, tmp194, tmp195, tmp196, tmp197, tmp198, tmp199, tmp200, tmp201, tmp202, tmp203, tmp204, tmp205, tmp206, tmp207, tmp208, tmp209, tmp210, tmp211, tmp212, tmp213, tmp214, tmp215, tmp216, tmp219, tmp220, tmp221, tmp222, tmp223, tmp224, tmp225, tmp226, tmp227, tmp228, tmp229, tmp230, tmp231, tmp232, tmp233, tmp234, tmp235, tmp236, tmp237, tmp238;  for(var __argIndexer = 0; __argIndexer < arguments.length; ++__argIndexer) arguments[__argIndexer] = _aether.createAPIClone(_aether, arguments[__argIndexer]);\n            _aether.logStatementStart([{ofs: 1192, row: 38, col: 4}, {ofs: 1208, row: 38, col: 20}]); unit = null;  _aether.logStatement([{ofs: 1192, row: 38, col: 4}, {ofs: 1208, row: 38, col: 20}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 1213, row: 39, col: 4}, {ofs: 1230, row: 39, col: 21}]); unitSize = 0;  _aether.logStatement([{ofs: 1213, row: 39, col: 4}, {ofs: 1230, row: 39, col: 21}], _aether._userInfo, false);\n            tmp191 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n            tmp192 = 'enemyHero';\n            _aether.logStatementStart([{ofs: 1378, row: 45, col: 7}, {ofs: 1392, row: 45, col: 21}]); tmp190 = tmp191[tmp192];  _aether.logStatement([{ofs: 1378, row: 45, col: 7}, {ofs: 1392, row: 45, col: 21}], _aether._userInfo, false);\n            if (tmp190) {\n                tmp197 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n                tmp198 = 'enemyHero';\n                _aether.logStatementStart([{ofs: 1396, row: 45, col: 25}, {ofs: 1410, row: 45, col: 39}]); tmp195 = tmp197[tmp198];  _aether.logStatement([{ofs: 1396, row: 45, col: 25}, {ofs: 1410, row: 45, col: 39}], _aether._userInfo, false);\n                tmp196 = 'type';\n                _aether.logStatementStart([{ofs: 1396, row: 45, col: 25}, {ofs: 1415, row: 45, col: 44}]); tmp193 = tmp195[tmp196];  _aether.logStatement([{ofs: 1396, row: 45, col: 25}, {ofs: 1415, row: 45, col: 44}], _aether._userInfo, false);\n                _aether.logStatementStart([{ofs: 1420, row: 45, col: 49}, {ofs: 1428, row: 45, col: 57}]); tmp194 = 'shaman';  _aether.logStatement([{ofs: 1420, row: 45, col: 49}, {ofs: 1428, row: 45, col: 57}], _aether._userInfo, false);\n                _aether.logStatementStart([{ofs: 1396, row: 45, col: 25}, {ofs: 1428, row: 45, col: 57}]); tmp189 = tmp193 === tmp194;  _aether.logStatement([{ofs: 1396, row: 45, col: 25}, {ofs: 1428, row: 45, col: 57}], _aether._userInfo, false);\n            } else {\n                _aether.logStatementStart([{ofs: 1378, row: 45, col: 7}, {ofs: 1428, row: 45, col: 57}]); tmp189 = tmp190;  _aether.logStatement([{ofs: 1378, row: 45, col: 7}, {ofs: 1428, row: 45, col: 57}], _aether._userInfo, false);\n            }\n            if (tmp189) {\n                tmp199 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n                tmp200 = 'terrifyClumpMinSize';\n                _aether.logStatementStart([{ofs: 1440, row: 46, col: 8}, {ofs: 1469, row: 46, col: 37}]); tmp201 = 5;  _aether.logStatement([{ofs: 1440, row: 46, col: 8}, {ofs: 1469, row: 46, col: 37}], _aether._userInfo, false);\n                _aether.logStatementStart([{ofs: 1440, row: 46, col: 8}, {ofs: 1468, row: 46, col: 36}]); tmp199[tmp200] = tmp201;  _aether.logStatement([{ofs: 1440, row: 46, col: 8}, {ofs: 1468, row: 46, col: 36}], _aether._userInfo, false);\n            } else {\n                ;\n            }\n            _aether.logStatementStart([{ofs: 1485, row: 49, col: 8}, {ofs: 1494, row: 49, col: 17}]); i = 1;  _aether.logStatement([{ofs: 1485, row: 49, col: 8}, {ofs: 1494, row: 49, col: 17}], _aether._userInfo, false);\n            tmp203 = i;\n            tmp207 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n            tmp208 = 'enemies';\n            _aether.logStatementStart([{ofs: 1500, row: 49, col: 23}, {ofs: 1512, row: 49, col: 35}]); tmp205 = tmp207[tmp208];  _aether.logStatement([{ofs: 1500, row: 49, col: 23}, {ofs: 1512, row: 49, col: 35}], _aether._userInfo, false);\n            tmp206 = 'length';\n            _aether.logStatementStart([{ofs: 1500, row: 49, col: 23}, {ofs: 1519, row: 49, col: 42}]); tmp204 = tmp205[tmp206];  _aether.logStatement([{ofs: 1500, row: 49, col: 23}, {ofs: 1519, row: 49, col: 42}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 1496, row: 49, col: 19}, {ofs: 1519, row: 49, col: 42}]); tmp202 = tmp203 < tmp204;  _aether.logStatement([{ofs: 1496, row: 49, col: 19}, {ofs: 1519, row: 49, col: 42}], _aether._userInfo, false);\n            tmp217: {\n                while (tmp202) {\n                    tmp218: {\n                        tmp219 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n                        tmp220 = 'getClumpSize';\n                        tmp224 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n                        tmp225 = 'enemies';\n                        _aether.logStatementStart([{ofs: 1573, row: 50, col: 45}, {ofs: 1585, row: 50, col: 57}]); tmp222 = tmp224[tmp225];  _aether.logStatement([{ofs: 1573, row: 50, col: 45}, {ofs: 1585, row: 50, col: 57}], _aether._userInfo, false);\n                        tmp223 = i;\n                        _aether.logStatementStart([{ofs: 1573, row: 50, col: 45}, {ofs: 1588, row: 50, col: 60}]); tmp221 = tmp222[tmp223];  _aether.logStatement([{ofs: 1573, row: 50, col: 45}, {ofs: 1588, row: 50, col: 60}], _aether._userInfo, false);\n                        _aether.logStatementStart([{ofs: 1536, row: 50, col: 8}, {ofs: 1590, row: 50, col: 62}]); tempUnitSize = _aether.createAPIClone(_aether, tmp219[tmp220](_aether.restoreAPIClone(_aether, tmp221)));  _aether.logStatement([{ofs: 1536, row: 50, col: 8}, {ofs: 1590, row: 50, col: 62}], _aether._userInfo, false);\n                        tmp228 = tempUnitSize;\n                        tmp229 = unitSize;\n                        _aether.logStatementStart([{ofs: 1602, row: 51, col: 11}, {ofs: 1625, row: 51, col: 34}]); tmp227 = tmp228 > tmp229;  _aether.logStatement([{ofs: 1602, row: 51, col: 11}, {ofs: 1625, row: 51, col: 34}], _aether._userInfo, false);\n                        if (tmp227) {\n                            tmp230 = tempUnitSize;\n                            tmp232 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n                            tmp233 = 'terrifyClumpMinSize';\n                            _aether.logStatementStart([{ofs: 1644, row: 51, col: 53}, {ofs: 1668, row: 51, col: 77}]); tmp231 = tmp232[tmp233];  _aether.logStatement([{ofs: 1644, row: 51, col: 53}, {ofs: 1668, row: 51, col: 77}], _aether._userInfo, false);\n                            _aether.logStatementStart([{ofs: 1629, row: 51, col: 38}, {ofs: 1668, row: 51, col: 77}]); tmp226 = tmp230 > tmp231;  _aether.logStatement([{ofs: 1629, row: 51, col: 38}, {ofs: 1668, row: 51, col: 77}], _aether._userInfo, false);\n                        } else {\n                            _aether.logStatementStart([{ofs: 1602, row: 51, col: 11}, {ofs: 1668, row: 51, col: 77}]); tmp226 = tmp227;  _aether.logStatement([{ofs: 1602, row: 51, col: 11}, {ofs: 1668, row: 51, col: 77}], _aether._userInfo, false);\n                        }\n                        if (tmp226) {\n                            tmp236 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n                            tmp237 = 'enemies';\n                            _aether.logStatementStart([{ofs: 1691, row: 52, col: 19}, {ofs: 1703, row: 52, col: 31}]); tmp234 = tmp236[tmp237];  _aether.logStatement([{ofs: 1691, row: 52, col: 19}, {ofs: 1703, row: 52, col: 31}], _aether._userInfo, false);\n                            tmp235 = i;\n                            _aether.logStatementStart([{ofs: 1684, row: 52, col: 12}, {ofs: 1707, row: 52, col: 35}]); unit = tmp234[tmp235];  _aether.logStatement([{ofs: 1684, row: 52, col: 12}, {ofs: 1707, row: 52, col: 35}], _aether._userInfo, false);\n                            unitSize = tempUnitSize;\n                        } else {\n                            ;\n                        }\n                    }\n                    tmp215 = i;\n                    tmp216 = 1;\n                    i = tmp215 + tmp216;\n                    tmp209 = i;\n                    tmp213 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n                    tmp214 = 'enemies';\n                    _aether.logStatementStart([{ofs: 1500, row: 49, col: 23}, {ofs: 1512, row: 49, col: 35}]); tmp211 = tmp213[tmp214];  _aether.logStatement([{ofs: 1500, row: 49, col: 23}, {ofs: 1512, row: 49, col: 35}], _aether._userInfo, false);\n                    tmp212 = 'length';\n                    _aether.logStatementStart([{ofs: 1500, row: 49, col: 23}, {ofs: 1519, row: 49, col: 42}]); tmp210 = tmp211[tmp212];  _aether.logStatement([{ofs: 1500, row: 49, col: 23}, {ofs: 1519, row: 49, col: 42}], _aether._userInfo, false);\n                    _aether.logStatementStart([{ofs: 1496, row: 49, col: 19}, {ofs: 1519, row: 49, col: 42}]); tmp202 = tmp209 < tmp210;  _aether.logStatement([{ofs: 1496, row: 49, col: 19}, {ofs: 1519, row: 49, col: 42}], _aether._userInfo, false);\n                }\n            }\n            tmp238 = unit;\n            return _aether.restoreAPIClone(_aether, tmp238);\n        };  _aether.logStatement([{ofs: 1151, row: 36, col: 0}, {ofs: 1780, row: 57, col: 2}], _aether._userInfo, false);\n        _aether.logStatementStart([{ofs: 1151, row: 36, col: 0}, {ofs: 1779, row: 57, col: 1}]); tmp186[tmp187] = tmp188;  _aether.logStatement([{ofs: 1151, row: 36, col: 0}, {ofs: 1779, row: 57, col: 1}], _aether._userInfo, false);\n        tmp239 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n        tmp240 = 'getClumpSize';\n        _aether.logStatementStart([{ofs: 1782, row: 59, col: 0}, {ofs: 2001, row: 68, col: 2}]); tmp241 = function (unit) {\n            var count, i, tmp242, tmp243, tmp244, tmp245, tmp246, tmp247, tmp248, tmp249, tmp250, tmp251, tmp252, tmp253, tmp254, tmp255, tmp256, tmp259, tmp260, tmp261, tmp262, tmp263, tmp264, tmp265, tmp266, tmp267, tmp268, tmp269, tmp270, tmp271, tmp272; unit = _aether.createAPIClone(_aether, unit); for(var __argIndexer = 0; __argIndexer < arguments.length; ++__argIndexer) arguments[__argIndexer] = _aether.createAPIClone(_aether, arguments[__argIndexer]);\n            _aether.logStatementStart([{ofs: 1824, row: 61, col: 4}, {ofs: 1838, row: 61, col: 18}]); count = 0;  _aether.logStatement([{ofs: 1824, row: 61, col: 4}, {ofs: 1838, row: 61, col: 18}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 1847, row: 62, col: 8}, {ofs: 1856, row: 62, col: 17}]); i = 1;  _aether.logStatement([{ofs: 1847, row: 62, col: 8}, {ofs: 1856, row: 62, col: 17}], _aether._userInfo, false);\n            tmp243 = i;\n            tmp247 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n            tmp248 = 'enemies';\n            _aether.logStatementStart([{ofs: 1862, row: 62, col: 23}, {ofs: 1874, row: 62, col: 35}]); tmp245 = tmp247[tmp248];  _aether.logStatement([{ofs: 1862, row: 62, col: 23}, {ofs: 1874, row: 62, col: 35}], _aether._userInfo, false);\n            tmp246 = 'length';\n            _aether.logStatementStart([{ofs: 1862, row: 62, col: 23}, {ofs: 1881, row: 62, col: 42}]); tmp244 = tmp245[tmp246];  _aether.logStatement([{ofs: 1862, row: 62, col: 23}, {ofs: 1881, row: 62, col: 42}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 1858, row: 62, col: 19}, {ofs: 1881, row: 62, col: 42}]); tmp242 = tmp243 < tmp244;  _aether.logStatement([{ofs: 1858, row: 62, col: 19}, {ofs: 1881, row: 62, col: 42}], _aether._userInfo, false);\n            tmp257: {\n                while (tmp242) {\n                    tmp258: {\n                        tmp262 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n                        tmp263 = 'distance';\n                        tmp267 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n                        tmp268 = 'enemies';\n                        _aether.logStatementStart([{ofs: 1915, row: 63, col: 25}, {ofs: 1927, row: 63, col: 37}]); tmp265 = tmp267[tmp268];  _aether.logStatement([{ofs: 1915, row: 63, col: 25}, {ofs: 1927, row: 63, col: 37}], _aether._userInfo, false);\n                        tmp266 = i;\n                        _aether.logStatementStart([{ofs: 1915, row: 63, col: 25}, {ofs: 1930, row: 63, col: 40}]); tmp264 = tmp265[tmp266];  _aether.logStatement([{ofs: 1915, row: 63, col: 25}, {ofs: 1930, row: 63, col: 40}], _aether._userInfo, false);\n                        _aether.logStatementStart([{ofs: 1901, row: 63, col: 11}, {ofs: 1931, row: 63, col: 41}]); tmp260 = _aether.createAPIClone(_aether, tmp262[tmp263](_aether.restoreAPIClone(_aether, tmp264)));  _aether.logStatement([{ofs: 1901, row: 63, col: 11}, {ofs: 1931, row: 63, col: 41}], _aether._userInfo, false);\n                        _aether.logStatementStart([{ofs: 1935, row: 63, col: 45}, {ofs: 1937, row: 63, col: 47}]); tmp261 = 30;  _aether.logStatement([{ofs: 1935, row: 63, col: 45}, {ofs: 1937, row: 63, col: 47}], _aether._userInfo, false);\n                        _aether.logStatementStart([{ofs: 1901, row: 63, col: 11}, {ofs: 1937, row: 63, col: 47}]); tmp259 = tmp260 <= tmp261;  _aether.logStatement([{ofs: 1901, row: 63, col: 11}, {ofs: 1937, row: 63, col: 47}], _aether._userInfo, false);\n                        if (tmp259) {\n                            _aether.logStatementStart([{ofs: 1953, row: 64, col: 12}, {ofs: 1964, row: 64, col: 23}]); tmp269 = 1;  _aether.logStatement([{ofs: 1953, row: 64, col: 12}, {ofs: 1964, row: 64, col: 23}], _aether._userInfo, false);\n                            tmp270 = count;\n                            tmp271 = tmp269;\n                            count = tmp270 + tmp271;\n                        } else {\n                            ;\n                        }\n                    }\n                    tmp255 = i;\n                    tmp256 = 1;\n                    i = tmp255 + tmp256;\n                    tmp249 = i;\n                    tmp253 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n                    tmp254 = 'enemies';\n                    _aether.logStatementStart([{ofs: 1862, row: 62, col: 23}, {ofs: 1874, row: 62, col: 35}]); tmp251 = tmp253[tmp254];  _aether.logStatement([{ofs: 1862, row: 62, col: 23}, {ofs: 1874, row: 62, col: 35}], _aether._userInfo, false);\n                    tmp252 = 'length';\n                    _aether.logStatementStart([{ofs: 1862, row: 62, col: 23}, {ofs: 1881, row: 62, col: 42}]); tmp250 = tmp251[tmp252];  _aether.logStatement([{ofs: 1862, row: 62, col: 23}, {ofs: 1881, row: 62, col: 42}], _aether._userInfo, false);\n                    _aether.logStatementStart([{ofs: 1858, row: 62, col: 19}, {ofs: 1881, row: 62, col: 42}]); tmp242 = tmp249 < tmp250;  _aether.logStatement([{ofs: 1858, row: 62, col: 19}, {ofs: 1881, row: 62, col: 42}], _aether._userInfo, false);\n                }\n            }\n            tmp272 = count;\n            return _aether.restoreAPIClone(_aether, tmp272);\n        };  _aether.logStatement([{ofs: 1782, row: 59, col: 0}, {ofs: 2001, row: 68, col: 2}], _aether._userInfo, false);\n        _aether.logStatementStart([{ofs: 1782, row: 59, col: 0}, {ofs: 2000, row: 68, col: 1}]); tmp239[tmp240] = tmp241;  _aether.logStatement([{ofs: 1782, row: 59, col: 0}, {ofs: 2000, row: 68, col: 1}], _aether._userInfo, false);\n        tmp273 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n        tmp274 = 'determineSayAndAction';\n        _aether.logStatementStart([{ofs: 2003, row: 70, col: 0}, {ofs: 2716, row: 88, col: 2}]); tmp275 = function () {\n            var tmp276, tmp277, tmp278, tmp279, tmp280, tmp281, tmp282, tmp283, tmp284, tmp285, tmp286, tmp287, tmp288, tmp289, tmp290, tmp291, tmp292, tmp293, tmp294, tmp295, tmp296, tmp297, tmp298, tmp299, tmp300, tmp301, tmp302, tmp303, tmp304, tmp305, tmp306, tmp307, tmp308, tmp309, tmp310, tmp311, tmp312, tmp313, tmp314, tmp315, tmp316, tmp317, tmp318, tmp319, tmp320, tmp321, tmp322, tmp323;  for(var __argIndexer = 0; __argIndexer < arguments.length; ++__argIndexer) arguments[__argIndexer] = _aether.createAPIClone(_aether, arguments[__argIndexer]);\n            tmp279 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n            tmp280 = 'distance';\n            tmp282 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n            tmp283 = 'enemyBase';\n            _aether.logStatementStart([{ofs: 2331, row: 77, col: 21}, {ofs: 2345, row: 77, col: 35}]); tmp281 = tmp282[tmp283];  _aether.logStatement([{ofs: 2331, row: 77, col: 21}, {ofs: 2345, row: 77, col: 35}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 2317, row: 77, col: 7}, {ofs: 2346, row: 77, col: 36}]); tmp277 = _aether.createAPIClone(_aether, tmp279[tmp280](_aether.restoreAPIClone(_aether, tmp281)));  _aether.logStatement([{ofs: 2317, row: 77, col: 7}, {ofs: 2346, row: 77, col: 36}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 2350, row: 77, col: 40}, {ofs: 2352, row: 77, col: 42}]); tmp278 = 30;  _aether.logStatement([{ofs: 2350, row: 77, col: 40}, {ofs: 2352, row: 77, col: 42}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 2317, row: 77, col: 7}, {ofs: 2352, row: 77, col: 42}]); tmp276 = tmp277 >= tmp278;  _aether.logStatement([{ofs: 2317, row: 77, col: 7}, {ofs: 2352, row: 77, col: 42}], _aether._userInfo, false);\n            if (tmp276) {\n                tmp284 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n                tmp285 = 'say';\n                _aether.logStatementStart([{ofs: 2373, row: 78, col: 17}, {ofs: 2385, row: 78, col: 29}]); tmp286 = 'follow me!';  _aether.logStatement([{ofs: 2373, row: 78, col: 17}, {ofs: 2385, row: 78, col: 29}], _aether._userInfo, false);\n                _aether.logStatementStart([{ofs: 2364, row: 78, col: 8}, {ofs: 2386, row: 78, col: 30}]); tmp287 = _aether.createAPIClone(_aether, tmp284[tmp285](_aether.restoreAPIClone(_aether, tmp286)));  _aether.logStatement([{ofs: 2364, row: 78, col: 8}, {ofs: 2386, row: 78, col: 30}], _aether._userInfo, false);\n                tmp288 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n                tmp289 = 'move';\n                tmp297 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n                tmp298 = 'enemyBase';\n                _aether.logStatementStart([{ofs: 2410, row: 79, col: 22}, {ofs: 2424, row: 79, col: 36}]); tmp295 = tmp297[tmp298];  _aether.logStatement([{ofs: 2410, row: 79, col: 22}, {ofs: 2424, row: 79, col: 36}], _aether._userInfo, false);\n                tmp296 = 'pos';\n                _aether.logStatementStart([{ofs: 2410, row: 79, col: 22}, {ofs: 2428, row: 79, col: 40}]); tmp293 = tmp295[tmp296];  _aether.logStatement([{ofs: 2410, row: 79, col: 22}, {ofs: 2428, row: 79, col: 40}], _aether._userInfo, false);\n                tmp294 = 'x';\n                _aether.logStatementStart([{ofs: 2410, row: 79, col: 22}, {ofs: 2430, row: 79, col: 42}]); tmp291 = tmp293[tmp294];  _aether.logStatement([{ofs: 2410, row: 79, col: 22}, {ofs: 2430, row: 79, col: 42}], _aether._userInfo, false);\n                tmp303 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n                tmp304 = 'enemyBase';\n                _aether.logStatementStart([{ofs: 2435, row: 79, col: 47}, {ofs: 2449, row: 79, col: 61}]); tmp301 = tmp303[tmp304];  _aether.logStatement([{ofs: 2435, row: 79, col: 47}, {ofs: 2449, row: 79, col: 61}], _aether._userInfo, false);\n                tmp302 = 'pos';\n                _aether.logStatementStart([{ofs: 2435, row: 79, col: 47}, {ofs: 2453, row: 79, col: 65}]); tmp299 = tmp301[tmp302];  _aether.logStatement([{ofs: 2435, row: 79, col: 47}, {ofs: 2453, row: 79, col: 65}], _aether._userInfo, false);\n                tmp300 = 'y';\n                _aether.logStatementStart([{ofs: 2435, row: 79, col: 47}, {ofs: 2455, row: 79, col: 67}]); tmp292 = tmp299[tmp300];  _aether.logStatement([{ofs: 2435, row: 79, col: 47}, {ofs: 2455, row: 79, col: 67}], _aether._userInfo, false);\n                _aether.logStatementStart([{ofs: 2406, row: 79, col: 18}, {ofs: 2456, row: 79, col: 68}]); tmp290 = {\n                    x: tmp291,\n                    y: tmp292\n                };  _aether.logStatement([{ofs: 2406, row: 79, col: 18}, {ofs: 2456, row: 79, col: 68}], _aether._userInfo, false);\n                _aether.logStatementStart([{ofs: 2396, row: 79, col: 8}, {ofs: 2457, row: 79, col: 69}]); tmp305 = _aether.createAPIClone(_aether, tmp288[tmp289](_aether.restoreAPIClone(_aether, tmp290)));  _aether.logStatement([{ofs: 2396, row: 79, col: 8}, {ofs: 2457, row: 79, col: 69}], _aether._userInfo, false);\n            } else {\n                tmp306 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n                tmp307 = 'say';\n                _aether.logStatementStart([{ofs: 2493, row: 82, col: 17}, {ofs: 2502, row: 82, col: 26}]); tmp308 = 'Attack!';  _aether.logStatement([{ofs: 2493, row: 82, col: 17}, {ofs: 2502, row: 82, col: 26}], _aether._userInfo, false);\n                tmp313 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n                tmp314 = 'enemies';\n                _aether.logStatementStart([{ofs: 2513, row: 82, col: 37}, {ofs: 2525, row: 82, col: 49}]); tmp311 = tmp313[tmp314];  _aether.logStatement([{ofs: 2513, row: 82, col: 37}, {ofs: 2525, row: 82, col: 49}], _aether._userInfo, false);\n                _aether.logStatementStart([{ofs: 2526, row: 82, col: 50}, {ofs: 2527, row: 82, col: 51}]); tmp312 = 0;  _aether.logStatement([{ofs: 2526, row: 82, col: 50}, {ofs: 2527, row: 82, col: 51}], _aether._userInfo, false);\n                _aether.logStatementStart([{ofs: 2513, row: 82, col: 37}, {ofs: 2528, row: 82, col: 52}]); tmp310 = tmp311[tmp312];  _aether.logStatement([{ofs: 2513, row: 82, col: 37}, {ofs: 2528, row: 82, col: 52}], _aether._userInfo, false);\n                _aether.logStatementStart([{ofs: 2504, row: 82, col: 28}, {ofs: 2529, row: 82, col: 53}]); tmp309 = { target: tmp310 };  _aether.logStatement([{ofs: 2504, row: 82, col: 28}, {ofs: 2529, row: 82, col: 53}], _aether._userInfo, false);\n                _aether.logStatementStart([{ofs: 2484, row: 82, col: 8}, {ofs: 2530, row: 82, col: 54}]); tmp315 = _aether.createAPIClone(_aether, tmp306[tmp307](_aether.restoreAPIClone(_aether, tmp308), _aether.restoreAPIClone(_aether, tmp309)));  _aether.logStatement([{ofs: 2484, row: 82, col: 8}, {ofs: 2530, row: 82, col: 54}], _aether._userInfo, false);\n                tmp316 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n                tmp317 = 'attack';\n                tmp321 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n                tmp322 = 'enemies';\n                _aether.logStatementStart([{ofs: 2552, row: 83, col: 20}, {ofs: 2564, row: 83, col: 32}]); tmp319 = tmp321[tmp322];  _aether.logStatement([{ofs: 2552, row: 83, col: 20}, {ofs: 2564, row: 83, col: 32}], _aether._userInfo, false);\n                _aether.logStatementStart([{ofs: 2565, row: 83, col: 33}, {ofs: 2566, row: 83, col: 34}]); tmp320 = 0;  _aether.logStatement([{ofs: 2565, row: 83, col: 33}, {ofs: 2566, row: 83, col: 34}], _aether._userInfo, false);\n                _aether.logStatementStart([{ofs: 2552, row: 83, col: 20}, {ofs: 2567, row: 83, col: 35}]); tmp318 = tmp319[tmp320];  _aether.logStatement([{ofs: 2552, row: 83, col: 20}, {ofs: 2567, row: 83, col: 35}], _aether._userInfo, false);\n                _aether.logStatementStart([{ofs: 2540, row: 83, col: 8}, {ofs: 2568, row: 83, col: 36}]); tmp323 = _aether.createAPIClone(_aether, tmp316[tmp317](_aether.restoreAPIClone(_aether, tmp318)));  _aether.logStatement([{ofs: 2540, row: 83, col: 8}, {ofs: 2568, row: 83, col: 36}], _aether._userInfo, false);\n            }\n            return;\n        };  _aether.logStatement([{ofs: 2003, row: 70, col: 0}, {ofs: 2716, row: 88, col: 2}], _aether._userInfo, false);\n        _aether.logStatementStart([{ofs: 2003, row: 70, col: 0}, {ofs: 2715, row: 88, col: 1}]); tmp273[tmp274] = tmp275;  _aether.logStatement([{ofs: 2003, row: 70, col: 0}, {ofs: 2715, row: 88, col: 1}], _aether._userInfo, false);\n        tmp324 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n        tmp325 = 'recalculateBaseRace';\n        _aether.logStatementStart([{ofs: 2718, row: 90, col: 0}, {ofs: 3302, row: 108, col: 2}]); tmp326 = function () {\n            var count, i, tmp327, tmp328, tmp329, tmp330, tmp331, tmp332, tmp333, tmp334, tmp335, tmp336, tmp337, tmp338, tmp339, tmp340, tmp341, tmp344, tmp345, tmp346, tmp347, tmp348, tmp349, tmp350, tmp351, tmp352, tmp353, tmp354, tmp355, tmp356, tmp357, tmp358, tmp359, tmp360, tmp361, tmp362, tmp363, tmp364, tmp365, tmp366, tmp367, tmp368, tmp369, tmp370, tmp371, tmp372, tmp373, tmp374, tmp375;  for(var __argIndexer = 0; __argIndexer < arguments.length; ++__argIndexer) arguments[__argIndexer] = _aether.createAPIClone(_aether, arguments[__argIndexer]);\n            _aether.logStatementStart([{ofs: 2957, row: 96, col: 4}, {ofs: 2971, row: 96, col: 18}]); count = 0;  _aether.logStatement([{ofs: 2957, row: 96, col: 4}, {ofs: 2971, row: 96, col: 18}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 2980, row: 97, col: 8}, {ofs: 2989, row: 97, col: 17}]); i = 1;  _aether.logStatement([{ofs: 2980, row: 97, col: 8}, {ofs: 2989, row: 97, col: 17}], _aether._userInfo, false);\n            tmp328 = i;\n            tmp332 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n            tmp333 = 'enemies';\n            _aether.logStatementStart([{ofs: 2995, row: 97, col: 23}, {ofs: 3007, row: 97, col: 35}]); tmp330 = tmp332[tmp333];  _aether.logStatement([{ofs: 2995, row: 97, col: 23}, {ofs: 3007, row: 97, col: 35}], _aether._userInfo, false);\n            tmp331 = 'length';\n            _aether.logStatementStart([{ofs: 2995, row: 97, col: 23}, {ofs: 3014, row: 97, col: 42}]); tmp329 = tmp330[tmp331];  _aether.logStatement([{ofs: 2995, row: 97, col: 23}, {ofs: 3014, row: 97, col: 42}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 2991, row: 97, col: 19}, {ofs: 3014, row: 97, col: 42}]); tmp327 = tmp328 < tmp329;  _aether.logStatement([{ofs: 2991, row: 97, col: 19}, {ofs: 3014, row: 97, col: 42}], _aether._userInfo, false);\n            tmp342: {\n                while (tmp327) {\n                    tmp343: {\n                        tmp350 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n                        tmp351 = 'enemies';\n                        _aether.logStatementStart([{ofs: 3034, row: 98, col: 11}, {ofs: 3046, row: 98, col: 23}]); tmp348 = tmp350[tmp351];  _aether.logStatement([{ofs: 3034, row: 98, col: 11}, {ofs: 3046, row: 98, col: 23}], _aether._userInfo, false);\n                        tmp349 = i;\n                        _aether.logStatementStart([{ofs: 3034, row: 98, col: 11}, {ofs: 3049, row: 98, col: 26}]); tmp346 = tmp348[tmp349];  _aether.logStatement([{ofs: 3034, row: 98, col: 11}, {ofs: 3049, row: 98, col: 26}], _aether._userInfo, false);\n                        tmp347 = 'target';\n                        _aether.logStatementStart([{ofs: 3034, row: 98, col: 11}, {ofs: 3056, row: 98, col: 33}]); tmp345 = tmp346[tmp347];  _aether.logStatement([{ofs: 3034, row: 98, col: 11}, {ofs: 3056, row: 98, col: 33}], _aether._userInfo, false);\n                        if (tmp345) {\n                            tmp360 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n                            tmp361 = 'enemies';\n                            _aether.logStatementStart([{ofs: 3060, row: 98, col: 37}, {ofs: 3072, row: 98, col: 49}]); tmp358 = tmp360[tmp361];  _aether.logStatement([{ofs: 3060, row: 98, col: 37}, {ofs: 3072, row: 98, col: 49}], _aether._userInfo, false);\n                            tmp359 = i;\n                            _aether.logStatementStart([{ofs: 3060, row: 98, col: 37}, {ofs: 3075, row: 98, col: 52}]); tmp356 = tmp358[tmp359];  _aether.logStatement([{ofs: 3060, row: 98, col: 37}, {ofs: 3075, row: 98, col: 52}], _aether._userInfo, false);\n                            tmp357 = 'target';\n                            _aether.logStatementStart([{ofs: 3060, row: 98, col: 37}, {ofs: 3082, row: 98, col: 59}]); tmp354 = tmp356[tmp357];  _aether.logStatement([{ofs: 3060, row: 98, col: 37}, {ofs: 3082, row: 98, col: 59}], _aether._userInfo, false);\n                            tmp355 = 'type';\n                            _aether.logStatementStart([{ofs: 3060, row: 98, col: 37}, {ofs: 3087, row: 98, col: 64}]); tmp352 = tmp354[tmp355];  _aether.logStatement([{ofs: 3060, row: 98, col: 37}, {ofs: 3087, row: 98, col: 64}], _aether._userInfo, false);\n                            _aether.logStatementStart([{ofs: 3092, row: 98, col: 69}, {ofs: 3098, row: 98, col: 75}]); tmp353 = 'base';  _aether.logStatement([{ofs: 3092, row: 98, col: 69}, {ofs: 3098, row: 98, col: 75}], _aether._userInfo, false);\n                            _aether.logStatementStart([{ofs: 3060, row: 98, col: 37}, {ofs: 3098, row: 98, col: 75}]); tmp344 = tmp352 === tmp353;  _aether.logStatement([{ofs: 3060, row: 98, col: 37}, {ofs: 3098, row: 98, col: 75}], _aether._userInfo, false);\n                        } else {\n                            _aether.logStatementStart([{ofs: 3034, row: 98, col: 11}, {ofs: 3098, row: 98, col: 75}]); tmp344 = tmp345;  _aether.logStatement([{ofs: 3034, row: 98, col: 11}, {ofs: 3098, row: 98, col: 75}], _aether._userInfo, false);\n                        }\n                        if (tmp344) {\n                            _aether.logStatementStart([{ofs: 3114, row: 99, col: 12}, {ofs: 3125, row: 99, col: 23}]); tmp362 = 1;  _aether.logStatement([{ofs: 3114, row: 99, col: 12}, {ofs: 3125, row: 99, col: 23}], _aether._userInfo, false);\n                            tmp363 = count;\n                            tmp364 = tmp362;\n                            count = tmp363 + tmp364;\n                        } else {\n                            ;\n                        }\n                    }\n                    tmp340 = i;\n                    tmp341 = 1;\n                    i = tmp340 + tmp341;\n                    tmp334 = i;\n                    tmp338 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n                    tmp339 = 'enemies';\n                    _aether.logStatementStart([{ofs: 2995, row: 97, col: 23}, {ofs: 3007, row: 97, col: 35}]); tmp336 = tmp338[tmp339];  _aether.logStatement([{ofs: 2995, row: 97, col: 23}, {ofs: 3007, row: 97, col: 35}], _aether._userInfo, false);\n                    tmp337 = 'length';\n                    _aether.logStatementStart([{ofs: 2995, row: 97, col: 23}, {ofs: 3014, row: 97, col: 42}]); tmp335 = tmp336[tmp337];  _aether.logStatement([{ofs: 2995, row: 97, col: 23}, {ofs: 3014, row: 97, col: 42}], _aether._userInfo, false);\n                    _aether.logStatementStart([{ofs: 2991, row: 97, col: 19}, {ofs: 3014, row: 97, col: 42}]); tmp327 = tmp334 < tmp335;  _aether.logStatement([{ofs: 2991, row: 97, col: 19}, {ofs: 3014, row: 97, col: 42}], _aether._userInfo, false);\n                }\n            }\n            tmp366 = count;\n            tmp372 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n            tmp373 = 'enemies';\n            _aether.logStatementStart([{ofs: 3227, row: 104, col: 17}, {ofs: 3239, row: 104, col: 29}]); tmp370 = tmp372[tmp373];  _aether.logStatement([{ofs: 3227, row: 104, col: 17}, {ofs: 3239, row: 104, col: 29}], _aether._userInfo, false);\n            tmp371 = 'length';\n            _aether.logStatementStart([{ofs: 3227, row: 104, col: 17}, {ofs: 3246, row: 104, col: 36}]); tmp368 = tmp370[tmp371];  _aether.logStatement([{ofs: 3227, row: 104, col: 17}, {ofs: 3246, row: 104, col: 36}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 3249, row: 104, col: 39}, {ofs: 3250, row: 104, col: 40}]); tmp369 = 1;  _aether.logStatement([{ofs: 3249, row: 104, col: 39}, {ofs: 3250, row: 104, col: 40}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 3227, row: 104, col: 17}, {ofs: 3250, row: 104, col: 40}]); tmp367 = tmp368 - tmp369;  _aether.logStatement([{ofs: 3227, row: 104, col: 17}, {ofs: 3250, row: 104, col: 40}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 3217, row: 104, col: 7}, {ofs: 3251, row: 104, col: 41}]); tmp365 = tmp366 >= tmp367;  _aether.logStatement([{ofs: 3217, row: 104, col: 7}, {ofs: 3251, row: 104, col: 41}], _aether._userInfo, false);\n            if (tmp365) {\n                _aether.logStatementStart([{ofs: 3270, row: 105, col: 15}, {ofs: 3274, row: 105, col: 19}]); tmp374 = true;  _aether.logStatement([{ofs: 3270, row: 105, col: 15}, {ofs: 3274, row: 105, col: 19}], _aether._userInfo, false);\n                return _aether.restoreAPIClone(_aether, tmp374);\n            } else {\n                ;\n            }\n            _aether.logStatementStart([{ofs: 3293, row: 107, col: 11}, {ofs: 3298, row: 107, col: 16}]); tmp375 = false;  _aether.logStatement([{ofs: 3293, row: 107, col: 11}, {ofs: 3298, row: 107, col: 16}], _aether._userInfo, false);\n            return _aether.restoreAPIClone(_aether, tmp375);\n        };  _aether.logStatement([{ofs: 2718, row: 90, col: 0}, {ofs: 3302, row: 108, col: 2}], _aether._userInfo, false);\n        _aether.logStatementStart([{ofs: 2718, row: 90, col: 0}, {ofs: 3301, row: 108, col: 1}]); tmp324[tmp325] = tmp326;  _aether.logStatement([{ofs: 2718, row: 90, col: 0}, {ofs: 3301, row: 108, col: 1}], _aether._userInfo, false);\n        tmp376 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n        tmp377 = 'isOpponentHeroRushing';\n        _aether.logStatementStart([{ofs: 3304, row: 110, col: 0}, {ofs: 3639, row: 123, col: 2}]); tmp378 = function () {\n            var count, i, tmp379, tmp380, tmp381, tmp382, tmp383, tmp384, tmp385, tmp386, tmp387, tmp388, tmp389, tmp390, tmp391, tmp392, tmp393, tmp396, tmp397, tmp398, tmp399, tmp400, tmp401, tmp402, tmp403, tmp404, tmp405, tmp406, tmp407, tmp408, tmp409, tmp410, tmp411, tmp412, tmp413, tmp414, tmp415, tmp416, tmp417, tmp418, tmp419, tmp420, tmp421, tmp422, tmp423, tmp424, tmp425, tmp426, tmp427;  for(var __argIndexer = 0; __argIndexer < arguments.length; ++__argIndexer) arguments[__argIndexer] = _aether.createAPIClone(_aether, arguments[__argIndexer]);\n            _aether.logStatementStart([{ofs: 3355, row: 112, col: 4}, {ofs: 3369, row: 112, col: 18}]); count = 0;  _aether.logStatement([{ofs: 3355, row: 112, col: 4}, {ofs: 3369, row: 112, col: 18}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 3378, row: 113, col: 8}, {ofs: 3387, row: 113, col: 17}]); i = 1;  _aether.logStatement([{ofs: 3378, row: 113, col: 8}, {ofs: 3387, row: 113, col: 17}], _aether._userInfo, false);\n            tmp380 = i;\n            tmp384 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n            tmp385 = 'enemies';\n            _aether.logStatementStart([{ofs: 3393, row: 113, col: 23}, {ofs: 3405, row: 113, col: 35}]); tmp382 = tmp384[tmp385];  _aether.logStatement([{ofs: 3393, row: 113, col: 23}, {ofs: 3405, row: 113, col: 35}], _aether._userInfo, false);\n            tmp383 = 'length';\n            _aether.logStatementStart([{ofs: 3393, row: 113, col: 23}, {ofs: 3412, row: 113, col: 42}]); tmp381 = tmp382[tmp383];  _aether.logStatement([{ofs: 3393, row: 113, col: 23}, {ofs: 3412, row: 113, col: 42}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 3389, row: 113, col: 19}, {ofs: 3412, row: 113, col: 42}]); tmp379 = tmp380 < tmp381;  _aether.logStatement([{ofs: 3389, row: 113, col: 19}, {ofs: 3412, row: 113, col: 42}], _aether._userInfo, false);\n            tmp394: {\n                while (tmp379) {\n                    tmp395: {\n                        tmp402 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n                        tmp403 = 'enemies';\n                        _aether.logStatementStart([{ofs: 3432, row: 114, col: 11}, {ofs: 3444, row: 114, col: 23}]); tmp400 = tmp402[tmp403];  _aether.logStatement([{ofs: 3432, row: 114, col: 11}, {ofs: 3444, row: 114, col: 23}], _aether._userInfo, false);\n                        tmp401 = i;\n                        _aether.logStatementStart([{ofs: 3432, row: 114, col: 11}, {ofs: 3447, row: 114, col: 26}]); tmp398 = tmp400[tmp401];  _aether.logStatement([{ofs: 3432, row: 114, col: 11}, {ofs: 3447, row: 114, col: 26}], _aether._userInfo, false);\n                        tmp399 = 'target';\n                        _aether.logStatementStart([{ofs: 3432, row: 114, col: 11}, {ofs: 3454, row: 114, col: 33}]); tmp397 = tmp398[tmp399];  _aether.logStatement([{ofs: 3432, row: 114, col: 11}, {ofs: 3454, row: 114, col: 33}], _aether._userInfo, false);\n                        if (tmp397) {\n                            tmp412 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n                            tmp413 = 'enemies';\n                            _aether.logStatementStart([{ofs: 3458, row: 114, col: 37}, {ofs: 3470, row: 114, col: 49}]); tmp410 = tmp412[tmp413];  _aether.logStatement([{ofs: 3458, row: 114, col: 37}, {ofs: 3470, row: 114, col: 49}], _aether._userInfo, false);\n                            tmp411 = i;\n                            _aether.logStatementStart([{ofs: 3458, row: 114, col: 37}, {ofs: 3473, row: 114, col: 52}]); tmp408 = tmp410[tmp411];  _aether.logStatement([{ofs: 3458, row: 114, col: 37}, {ofs: 3473, row: 114, col: 52}], _aether._userInfo, false);\n                            tmp409 = 'target';\n                            _aether.logStatementStart([{ofs: 3458, row: 114, col: 37}, {ofs: 3480, row: 114, col: 59}]); tmp406 = tmp408[tmp409];  _aether.logStatement([{ofs: 3458, row: 114, col: 37}, {ofs: 3480, row: 114, col: 59}], _aether._userInfo, false);\n                            tmp407 = 'type';\n                            _aether.logStatementStart([{ofs: 3458, row: 114, col: 37}, {ofs: 3485, row: 114, col: 64}]); tmp404 = tmp406[tmp407];  _aether.logStatement([{ofs: 3458, row: 114, col: 37}, {ofs: 3485, row: 114, col: 64}], _aether._userInfo, false);\n                            _aether.logStatementStart([{ofs: 3490, row: 114, col: 69}, {ofs: 3498, row: 114, col: 77}]); tmp405 = 'knight';  _aether.logStatement([{ofs: 3490, row: 114, col: 69}, {ofs: 3498, row: 114, col: 77}], _aether._userInfo, false);\n                            _aether.logStatementStart([{ofs: 3458, row: 114, col: 37}, {ofs: 3498, row: 114, col: 77}]); tmp396 = tmp404 === tmp405;  _aether.logStatement([{ofs: 3458, row: 114, col: 37}, {ofs: 3498, row: 114, col: 77}], _aether._userInfo, false);\n                        } else {\n                            _aether.logStatementStart([{ofs: 3432, row: 114, col: 11}, {ofs: 3498, row: 114, col: 77}]); tmp396 = tmp397;  _aether.logStatement([{ofs: 3432, row: 114, col: 11}, {ofs: 3498, row: 114, col: 77}], _aether._userInfo, false);\n                        }\n                        if (tmp396) {\n                            _aether.logStatementStart([{ofs: 3514, row: 115, col: 12}, {ofs: 3525, row: 115, col: 23}]); tmp414 = 1;  _aether.logStatement([{ofs: 3514, row: 115, col: 12}, {ofs: 3525, row: 115, col: 23}], _aether._userInfo, false);\n                            tmp415 = count;\n                            tmp416 = tmp414;\n                            count = tmp415 + tmp416;\n                        } else {\n                            ;\n                        }\n                    }\n                    tmp392 = i;\n                    tmp393 = 1;\n                    i = tmp392 + tmp393;\n                    tmp386 = i;\n                    tmp390 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n                    tmp391 = 'enemies';\n                    _aether.logStatementStart([{ofs: 3393, row: 113, col: 23}, {ofs: 3405, row: 113, col: 35}]); tmp388 = tmp390[tmp391];  _aether.logStatement([{ofs: 3393, row: 113, col: 23}, {ofs: 3405, row: 113, col: 35}], _aether._userInfo, false);\n                    tmp389 = 'length';\n                    _aether.logStatementStart([{ofs: 3393, row: 113, col: 23}, {ofs: 3412, row: 113, col: 42}]); tmp387 = tmp388[tmp389];  _aether.logStatement([{ofs: 3393, row: 113, col: 23}, {ofs: 3412, row: 113, col: 42}], _aether._userInfo, false);\n                    _aether.logStatementStart([{ofs: 3389, row: 113, col: 19}, {ofs: 3412, row: 113, col: 42}]); tmp379 = tmp386 < tmp387;  _aether.logStatement([{ofs: 3389, row: 113, col: 19}, {ofs: 3412, row: 113, col: 42}], _aether._userInfo, false);\n                }\n            }\n            tmp418 = count;\n            tmp424 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n            tmp425 = 'enemies';\n            _aether.logStatementStart([{ofs: 3564, row: 119, col: 17}, {ofs: 3576, row: 119, col: 29}]); tmp422 = tmp424[tmp425];  _aether.logStatement([{ofs: 3564, row: 119, col: 17}, {ofs: 3576, row: 119, col: 29}], _aether._userInfo, false);\n            tmp423 = 'length';\n            _aether.logStatementStart([{ofs: 3564, row: 119, col: 17}, {ofs: 3583, row: 119, col: 36}]); tmp420 = tmp422[tmp423];  _aether.logStatement([{ofs: 3564, row: 119, col: 17}, {ofs: 3583, row: 119, col: 36}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 3586, row: 119, col: 39}, {ofs: 3587, row: 119, col: 40}]); tmp421 = 1;  _aether.logStatement([{ofs: 3586, row: 119, col: 39}, {ofs: 3587, row: 119, col: 40}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 3564, row: 119, col: 17}, {ofs: 3587, row: 119, col: 40}]); tmp419 = tmp420 - tmp421;  _aether.logStatement([{ofs: 3564, row: 119, col: 17}, {ofs: 3587, row: 119, col: 40}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 3554, row: 119, col: 7}, {ofs: 3588, row: 119, col: 41}]); tmp417 = tmp418 == tmp419;  _aether.logStatement([{ofs: 3554, row: 119, col: 7}, {ofs: 3588, row: 119, col: 41}], _aether._userInfo, false);\n            if (tmp417) {\n                _aether.logStatementStart([{ofs: 3607, row: 120, col: 15}, {ofs: 3611, row: 120, col: 19}]); tmp426 = true;  _aether.logStatement([{ofs: 3607, row: 120, col: 15}, {ofs: 3611, row: 120, col: 19}], _aether._userInfo, false);\n                return _aether.restoreAPIClone(_aether, tmp426);\n            } else {\n                ;\n            }\n            _aether.logStatementStart([{ofs: 3630, row: 122, col: 11}, {ofs: 3635, row: 122, col: 16}]); tmp427 = false;  _aether.logStatement([{ofs: 3630, row: 122, col: 11}, {ofs: 3635, row: 122, col: 16}], _aether._userInfo, false);\n            return _aether.restoreAPIClone(_aether, tmp427);\n        };  _aether.logStatement([{ofs: 3304, row: 110, col: 0}, {ofs: 3639, row: 123, col: 2}], _aether._userInfo, false);\n        _aether.logStatementStart([{ofs: 3304, row: 110, col: 0}, {ofs: 3638, row: 123, col: 1}]); tmp376[tmp377] = tmp378;  _aether.logStatement([{ofs: 3304, row: 110, col: 0}, {ofs: 3638, row: 123, col: 1}], _aether._userInfo, false);\n        tmp428 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n        tmp429 = 'doesOpponentHaveRanged';\n        _aether.logStatementStart([{ofs: 3641, row: 125, col: 0}, {ofs: 4238, row: 149, col: 2}]); tmp430 = function () {\n            var ranged, melee, i, tmp431, tmp432, tmp433, tmp434, tmp435, tmp436, tmp437, tmp438, tmp439, tmp440, tmp441, tmp442, tmp443, tmp444, tmp445, tmp448, tmp449, tmp450, tmp451, tmp452, tmp453, tmp454, tmp455, tmp456, tmp457, tmp458, tmp459, tmp460, tmp461, tmp462, tmp463, tmp464, tmp465, tmp466, tmp467, tmp468, tmp469, tmp470, tmp471, tmp472, tmp473, tmp474, tmp475, tmp476, tmp477, tmp478, tmp479, tmp480, tmp481, tmp482, tmp483, tmp484, tmp485, tmp486, tmp487, tmp488, tmp489, tmp490, tmp491, tmp492, tmp493;  for(var __argIndexer = 0; __argIndexer < arguments.length; ++__argIndexer) arguments[__argIndexer] = _aether.createAPIClone(_aether, arguments[__argIndexer]);\n            _aether.logStatementStart([{ofs: 3746, row: 129, col: 4}, {ofs: 3761, row: 129, col: 19}]); ranged = 0;  _aether.logStatement([{ofs: 3746, row: 129, col: 4}, {ofs: 3761, row: 129, col: 19}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 3766, row: 130, col: 4}, {ofs: 3780, row: 130, col: 18}]); melee = 0;  _aether.logStatement([{ofs: 3766, row: 130, col: 4}, {ofs: 3780, row: 130, col: 18}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 3789, row: 131, col: 8}, {ofs: 3798, row: 131, col: 17}]); i = 2;  _aether.logStatement([{ofs: 3789, row: 131, col: 8}, {ofs: 3798, row: 131, col: 17}], _aether._userInfo, false);\n            tmp432 = i;\n            tmp436 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n            tmp437 = 'enemies';\n            _aether.logStatementStart([{ofs: 3804, row: 131, col: 23}, {ofs: 3816, row: 131, col: 35}]); tmp434 = tmp436[tmp437];  _aether.logStatement([{ofs: 3804, row: 131, col: 23}, {ofs: 3816, row: 131, col: 35}], _aether._userInfo, false);\n            tmp435 = 'length';\n            _aether.logStatementStart([{ofs: 3804, row: 131, col: 23}, {ofs: 3823, row: 131, col: 42}]); tmp433 = tmp434[tmp435];  _aether.logStatement([{ofs: 3804, row: 131, col: 23}, {ofs: 3823, row: 131, col: 42}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 3800, row: 131, col: 19}, {ofs: 3823, row: 131, col: 42}]); tmp431 = tmp432 < tmp433;  _aether.logStatement([{ofs: 3800, row: 131, col: 19}, {ofs: 3823, row: 131, col: 42}], _aether._userInfo, false);\n            tmp446: {\n                while (tmp431) {\n                    tmp447: {\n                        tmp455 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n                        tmp456 = 'enemies';\n                        _aether.logStatementStart([{ofs: 3843, row: 132, col: 11}, {ofs: 3855, row: 132, col: 23}]); tmp453 = tmp455[tmp456];  _aether.logStatement([{ofs: 3843, row: 132, col: 11}, {ofs: 3855, row: 132, col: 23}], _aether._userInfo, false);\n                        tmp454 = i;\n                        _aether.logStatementStart([{ofs: 3843, row: 132, col: 11}, {ofs: 3858, row: 132, col: 26}]); tmp451 = tmp453[tmp454];  _aether.logStatement([{ofs: 3843, row: 132, col: 11}, {ofs: 3858, row: 132, col: 26}], _aether._userInfo, false);\n                        tmp452 = 'type';\n                        _aether.logStatementStart([{ofs: 3843, row: 132, col: 11}, {ofs: 3863, row: 132, col: 31}]); tmp449 = tmp451[tmp452];  _aether.logStatement([{ofs: 3843, row: 132, col: 11}, {ofs: 3863, row: 132, col: 31}], _aether._userInfo, false);\n                        _aether.logStatementStart([{ofs: 3868, row: 132, col: 36}, {ofs: 3877, row: 132, col: 45}]); tmp450 = 'thrower';  _aether.logStatement([{ofs: 3868, row: 132, col: 36}, {ofs: 3877, row: 132, col: 45}], _aether._userInfo, false);\n                        _aether.logStatementStart([{ofs: 3843, row: 132, col: 11}, {ofs: 3877, row: 132, col: 45}]); tmp448 = tmp449 === tmp450;  _aether.logStatement([{ofs: 3843, row: 132, col: 11}, {ofs: 3877, row: 132, col: 45}], _aether._userInfo, false);\n                        if (tmp448) {\n                            _aether.logStatementStart([{ofs: 3893, row: 133, col: 12}, {ofs: 3905, row: 133, col: 24}]); tmp457 = 1;  _aether.logStatement([{ofs: 3893, row: 133, col: 12}, {ofs: 3905, row: 133, col: 24}], _aether._userInfo, false);\n                            tmp458 = ranged;\n                            tmp459 = tmp457;\n                            ranged = tmp458 + tmp459;\n                        } else {\n                            tmp467 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n                            tmp468 = 'enemies';\n                            _aether.logStatementStart([{ofs: 3932, row: 135, col: 16}, {ofs: 3944, row: 135, col: 28}]); tmp465 = tmp467[tmp468];  _aether.logStatement([{ofs: 3932, row: 135, col: 16}, {ofs: 3944, row: 135, col: 28}], _aether._userInfo, false);\n                            tmp466 = i;\n                            _aether.logStatementStart([{ofs: 3932, row: 135, col: 16}, {ofs: 3947, row: 135, col: 31}]); tmp463 = tmp465[tmp466];  _aether.logStatement([{ofs: 3932, row: 135, col: 16}, {ofs: 3947, row: 135, col: 31}], _aether._userInfo, false);\n                            tmp464 = 'type';\n                            _aether.logStatementStart([{ofs: 3932, row: 135, col: 16}, {ofs: 3952, row: 135, col: 36}]); tmp461 = tmp463[tmp464];  _aether.logStatement([{ofs: 3932, row: 135, col: 16}, {ofs: 3952, row: 135, col: 36}], _aether._userInfo, false);\n                            _aether.logStatementStart([{ofs: 3957, row: 135, col: 41}, {ofs: 3967, row: 135, col: 51}]); tmp462 = 'munchkin';  _aether.logStatement([{ofs: 3957, row: 135, col: 41}, {ofs: 3967, row: 135, col: 51}], _aether._userInfo, false);\n                            _aether.logStatementStart([{ofs: 3932, row: 135, col: 16}, {ofs: 3967, row: 135, col: 51}]); tmp460 = tmp461 === tmp462;  _aether.logStatement([{ofs: 3932, row: 135, col: 16}, {ofs: 3967, row: 135, col: 51}], _aether._userInfo, false);\n                            if (tmp460) {\n                                _aether.logStatementStart([{ofs: 3983, row: 136, col: 12}, {ofs: 3994, row: 136, col: 23}]); tmp469 = 1;  _aether.logStatement([{ofs: 3983, row: 136, col: 12}, {ofs: 3994, row: 136, col: 23}], _aether._userInfo, false);\n                                tmp470 = melee;\n                                tmp471 = tmp469;\n                                melee = tmp470 + tmp471;\n                            } else {\n                                ;\n                            }\n                        }\n                    }\n                    tmp444 = i;\n                    tmp445 = 1;\n                    i = tmp444 + tmp445;\n                    tmp438 = i;\n                    tmp442 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n                    tmp443 = 'enemies';\n                    _aether.logStatementStart([{ofs: 3804, row: 131, col: 23}, {ofs: 3816, row: 131, col: 35}]); tmp440 = tmp442[tmp443];  _aether.logStatement([{ofs: 3804, row: 131, col: 23}, {ofs: 3816, row: 131, col: 35}], _aether._userInfo, false);\n                    tmp441 = 'length';\n                    _aether.logStatementStart([{ofs: 3804, row: 131, col: 23}, {ofs: 3823, row: 131, col: 42}]); tmp439 = tmp440[tmp441];  _aether.logStatement([{ofs: 3804, row: 131, col: 23}, {ofs: 3823, row: 131, col: 42}], _aether._userInfo, false);\n                    _aether.logStatementStart([{ofs: 3800, row: 131, col: 19}, {ofs: 3823, row: 131, col: 42}]); tmp431 = tmp438 < tmp439;  _aether.logStatement([{ofs: 3800, row: 131, col: 19}, {ofs: 3823, row: 131, col: 42}], _aether._userInfo, false);\n                }\n            }\n            tmp474 = melee;\n            _aether.logStatementStart([{ofs: 4026, row: 139, col: 15}, {ofs: 4027, row: 139, col: 16}]); tmp475 = 0;  _aether.logStatement([{ofs: 4026, row: 139, col: 15}, {ofs: 4027, row: 139, col: 16}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 4018, row: 139, col: 7}, {ofs: 4027, row: 139, col: 16}]); tmp473 = tmp474 > tmp475;  _aether.logStatement([{ofs: 4018, row: 139, col: 7}, {ofs: 4027, row: 139, col: 16}], _aether._userInfo, false);\n            if (tmp473) {\n                tmp476 = ranged;\n                _aether.logStatementStart([{ofs: 4042, row: 139, col: 31}, {ofs: 4043, row: 139, col: 32}]); tmp477 = 0;  _aether.logStatement([{ofs: 4042, row: 139, col: 31}, {ofs: 4043, row: 139, col: 32}], _aether._userInfo, false);\n                _aether.logStatementStart([{ofs: 4031, row: 139, col: 20}, {ofs: 4043, row: 139, col: 32}]); tmp472 = tmp476 === tmp477;  _aether.logStatement([{ofs: 4031, row: 139, col: 20}, {ofs: 4043, row: 139, col: 32}], _aether._userInfo, false);\n            } else {\n                _aether.logStatementStart([{ofs: 4018, row: 139, col: 7}, {ofs: 4043, row: 139, col: 32}]); tmp472 = tmp473;  _aether.logStatement([{ofs: 4018, row: 139, col: 7}, {ofs: 4043, row: 139, col: 32}], _aether._userInfo, false);\n            }\n            if (tmp472) {\n                _aether.logStatementStart([{ofs: 4062, row: 140, col: 15}, {ofs: 4063, row: 140, col: 16}]); tmp478 = 1;  _aether.logStatement([{ofs: 4062, row: 140, col: 15}, {ofs: 4063, row: 140, col: 16}], _aether._userInfo, false);\n                return _aether.restoreAPIClone(_aether, tmp478);\n            } else {\n                tmp481 = ranged;\n                _aether.logStatementStart([{ofs: 4092, row: 142, col: 21}, {ofs: 4093, row: 142, col: 22}]); tmp482 = 0;  _aether.logStatement([{ofs: 4092, row: 142, col: 21}, {ofs: 4093, row: 142, col: 22}], _aether._userInfo, false);\n                _aether.logStatementStart([{ofs: 4083, row: 142, col: 12}, {ofs: 4093, row: 142, col: 22}]); tmp480 = tmp481 > tmp482;  _aether.logStatement([{ofs: 4083, row: 142, col: 12}, {ofs: 4093, row: 142, col: 22}], _aether._userInfo, false);\n                if (tmp480) {\n                    tmp483 = melee;\n                    _aether.logStatementStart([{ofs: 4107, row: 142, col: 36}, {ofs: 4108, row: 142, col: 37}]); tmp484 = 0;  _aether.logStatement([{ofs: 4107, row: 142, col: 36}, {ofs: 4108, row: 142, col: 37}], _aether._userInfo, false);\n                    _aether.logStatementStart([{ofs: 4097, row: 142, col: 26}, {ofs: 4108, row: 142, col: 37}]); tmp479 = tmp483 === tmp484;  _aether.logStatement([{ofs: 4097, row: 142, col: 26}, {ofs: 4108, row: 142, col: 37}], _aether._userInfo, false);\n                } else {\n                    _aether.logStatementStart([{ofs: 4083, row: 142, col: 12}, {ofs: 4108, row: 142, col: 37}]); tmp479 = tmp480;  _aether.logStatement([{ofs: 4083, row: 142, col: 12}, {ofs: 4108, row: 142, col: 37}], _aether._userInfo, false);\n                }\n                if (tmp479) {\n                    _aether.logStatementStart([{ofs: 4127, row: 143, col: 15}, {ofs: 4128, row: 143, col: 16}]); tmp485 = 2;  _aether.logStatement([{ofs: 4127, row: 143, col: 15}, {ofs: 4128, row: 143, col: 16}], _aether._userInfo, false);\n                    return _aether.restoreAPIClone(_aether, tmp485);\n                } else {\n                    tmp488 = ranged;\n                    _aether.logStatementStart([{ofs: 4157, row: 145, col: 21}, {ofs: 4158, row: 145, col: 22}]); tmp489 = 0;  _aether.logStatement([{ofs: 4157, row: 145, col: 21}, {ofs: 4158, row: 145, col: 22}], _aether._userInfo, false);\n                    _aether.logStatementStart([{ofs: 4148, row: 145, col: 12}, {ofs: 4158, row: 145, col: 22}]); tmp487 = tmp488 > tmp489;  _aether.logStatement([{ofs: 4148, row: 145, col: 12}, {ofs: 4158, row: 145, col: 22}], _aether._userInfo, false);\n                    if (tmp487) {\n                        tmp490 = melee;\n                        _aether.logStatementStart([{ofs: 4170, row: 145, col: 34}, {ofs: 4171, row: 145, col: 35}]); tmp491 = 0;  _aether.logStatement([{ofs: 4170, row: 145, col: 34}, {ofs: 4171, row: 145, col: 35}], _aether._userInfo, false);\n                        _aether.logStatementStart([{ofs: 4162, row: 145, col: 26}, {ofs: 4171, row: 145, col: 35}]); tmp486 = tmp490 > tmp491;  _aether.logStatement([{ofs: 4162, row: 145, col: 26}, {ofs: 4171, row: 145, col: 35}], _aether._userInfo, false);\n                    } else {\n                        _aether.logStatementStart([{ofs: 4148, row: 145, col: 12}, {ofs: 4171, row: 145, col: 35}]); tmp486 = tmp487;  _aether.logStatement([{ofs: 4148, row: 145, col: 12}, {ofs: 4171, row: 145, col: 35}], _aether._userInfo, false);\n                    }\n                    if (tmp486) {\n                        _aether.logStatementStart([{ofs: 4190, row: 146, col: 15}, {ofs: 4191, row: 146, col: 16}]); tmp492 = 3;  _aether.logStatement([{ofs: 4190, row: 146, col: 15}, {ofs: 4191, row: 146, col: 16}], _aether._userInfo, false);\n                        return _aether.restoreAPIClone(_aether, tmp492);\n                    } else {\n                        ;\n                    }\n                }\n            }\n            _aether.logStatementStart([{ofs: 4210, row: 148, col: 11}, {ofs: 4211, row: 148, col: 12}]); tmp493 = 0;  _aether.logStatement([{ofs: 4210, row: 148, col: 11}, {ofs: 4211, row: 148, col: 12}], _aether._userInfo, false);\n            return _aether.restoreAPIClone(_aether, tmp493);\n        };  _aether.logStatement([{ofs: 3641, row: 125, col: 0}, {ofs: 4238, row: 149, col: 2}], _aether._userInfo, false);\n        _aether.logStatementStart([{ofs: 3641, row: 125, col: 0}, {ofs: 4237, row: 149, col: 1}]); tmp428[tmp429] = tmp430;  _aether.logStatement([{ofs: 3641, row: 125, col: 0}, {ofs: 4237, row: 149, col: 1}], _aether._userInfo, false);\n        tmp494 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n        tmp495 = 'getTerrifyTargets';\n        _aether.logStatementStart([{ofs: 4240, row: 151, col: 0}, {ofs: 5566, row: 200, col: 2}]); tmp496 = function () {\n            var tharin, base, other, i, tmp497, tmp498, tmp499, tmp500, tmp501, tmp502, tmp503, tmp504, tmp505, tmp506, tmp507, tmp508, tmp509, tmp510, tmp511, tmp512, tmp513, tmp514, tmp515, tmp516, tmp517, tmp518, tmp519, tmp520, tmp521, tmp524, tmp525, tmp526, tmp527, tmp528, tmp529, tmp530, tmp531, tmp532, tmp533, tmp534, tmp535, tmp536, tmp537, tmp538, tmp539, tmp540, tmp541, tmp542, tmp543, tmp544, tmp545, tmp546, tmp547, tmp548, tmp549, tmp550, tmp551, tmp552, tmp553, tmp554, tmp555, tmp556, tmp557, tmp558, tmp559, tmp560, tmp561, tmp562, tmp563, tmp564, tmp565, tmp566, tmp567, tmp568, tmp569, tmp570, tmp571, tmp572, tmp573, tmp574, tmp575, tmp576, tmp577, tmp578, tmp579, tmp580, tmp581, tmp582, tmp583, tmp584, tmp585, tmp586, tmp587, tmp588, tmp589, tmp590, tmp591, tmp592, tmp593, tmp594, tmp595, tmp596, tmp597, tmp598, tmp599, tmp600, tmp601, tmp602, tmp603, tmp604, tmp605, tmp606, tmp607, tmp608, tmp609, tmp610, tmp611, tmp612, tmp613, tmp614, tmp615, tmp616, tmp617, tmp618, tmp619, tmp620, tmp621, tmp622;  for(var __argIndexer = 0; __argIndexer < arguments.length; ++__argIndexer) arguments[__argIndexer] = _aether.createAPIClone(_aether, arguments[__argIndexer]);\n            _aether.logStatementStart([{ofs: 4421, row: 157, col: 4}, {ofs: 4436, row: 157, col: 19}]); tharin = 0;  _aether.logStatement([{ofs: 4421, row: 157, col: 4}, {ofs: 4436, row: 157, col: 19}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 4441, row: 158, col: 4}, {ofs: 4454, row: 158, col: 17}]); base = 0;  _aether.logStatement([{ofs: 4441, row: 158, col: 4}, {ofs: 4454, row: 158, col: 17}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 4459, row: 159, col: 4}, {ofs: 4473, row: 159, col: 18}]); other = 0;  _aether.logStatement([{ofs: 4459, row: 159, col: 4}, {ofs: 4473, row: 159, col: 18}], _aether._userInfo, false);\n            tmp497 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n            tmp498 = 'terrifyCooldown';\n            _aether.logStatementStart([{ofs: 4522, row: 162, col: 4}, {ofs: 4550, row: 162, col: 32}]); tmp499 = true;  _aether.logStatement([{ofs: 4522, row: 162, col: 4}, {ofs: 4550, row: 162, col: 32}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 4522, row: 162, col: 4}, {ofs: 4549, row: 162, col: 31}]); tmp497[tmp498] = tmp499;  _aether.logStatement([{ofs: 4522, row: 162, col: 4}, {ofs: 4549, row: 162, col: 31}], _aether._userInfo, false);\n            tmp500 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n            tmp501 = 'terrifyUnitCount';\n            tmp505 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n            tmp506 = 'enemies';\n            _aether.logStatementStart([{ofs: 4579, row: 163, col: 28}, {ofs: 4591, row: 163, col: 40}]); tmp503 = tmp505[tmp506];  _aether.logStatement([{ofs: 4579, row: 163, col: 28}, {ofs: 4591, row: 163, col: 40}], _aether._userInfo, false);\n            tmp504 = 'length';\n            _aether.logStatementStart([{ofs: 4555, row: 163, col: 4}, {ofs: 4599, row: 163, col: 48}]); tmp502 = tmp503[tmp504];  _aether.logStatement([{ofs: 4555, row: 163, col: 4}, {ofs: 4599, row: 163, col: 48}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 4555, row: 163, col: 4}, {ofs: 4598, row: 163, col: 47}]); tmp500[tmp501] = tmp502;  _aether.logStatement([{ofs: 4555, row: 163, col: 4}, {ofs: 4598, row: 163, col: 47}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 4609, row: 165, col: 8}, {ofs: 4618, row: 165, col: 17}]); i = 0;  _aether.logStatement([{ofs: 4609, row: 165, col: 8}, {ofs: 4618, row: 165, col: 17}], _aether._userInfo, false);\n            tmp508 = i;\n            tmp512 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n            tmp513 = 'enemies';\n            _aether.logStatementStart([{ofs: 4624, row: 165, col: 23}, {ofs: 4636, row: 165, col: 35}]); tmp510 = tmp512[tmp513];  _aether.logStatement([{ofs: 4624, row: 165, col: 23}, {ofs: 4636, row: 165, col: 35}], _aether._userInfo, false);\n            tmp511 = 'length';\n            _aether.logStatementStart([{ofs: 4624, row: 165, col: 23}, {ofs: 4643, row: 165, col: 42}]); tmp509 = tmp510[tmp511];  _aether.logStatement([{ofs: 4624, row: 165, col: 23}, {ofs: 4643, row: 165, col: 42}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 4620, row: 165, col: 19}, {ofs: 4643, row: 165, col: 42}]); tmp507 = tmp508 < tmp509;  _aether.logStatement([{ofs: 4620, row: 165, col: 19}, {ofs: 4643, row: 165, col: 42}], _aether._userInfo, false);\n            tmp522: {\n                while (tmp507) {\n                    tmp523: {\n                        tmp529 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n                        tmp530 = 'enemies';\n                        _aether.logStatementStart([{ofs: 4663, row: 166, col: 11}, {ofs: 4675, row: 166, col: 23}]); tmp527 = tmp529[tmp530];  _aether.logStatement([{ofs: 4663, row: 166, col: 11}, {ofs: 4675, row: 166, col: 23}], _aether._userInfo, false);\n                        tmp528 = i;\n                        _aether.logStatementStart([{ofs: 4663, row: 166, col: 11}, {ofs: 4678, row: 166, col: 26}]); tmp525 = tmp527[tmp528];  _aether.logStatement([{ofs: 4663, row: 166, col: 11}, {ofs: 4678, row: 166, col: 26}], _aether._userInfo, false);\n                        tmp526 = 'target';\n                        _aether.logStatementStart([{ofs: 4663, row: 166, col: 11}, {ofs: 4685, row: 166, col: 33}]); tmp524 = tmp525[tmp526];  _aether.logStatement([{ofs: 4663, row: 166, col: 11}, {ofs: 4685, row: 166, col: 33}], _aether._userInfo, false);\n                        if (tmp524) {\n                            tmp540 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n                            tmp541 = 'enemies';\n                            _aether.logStatementStart([{ofs: 4704, row: 167, col: 15}, {ofs: 4716, row: 167, col: 27}]); tmp538 = tmp540[tmp541];  _aether.logStatement([{ofs: 4704, row: 167, col: 15}, {ofs: 4716, row: 167, col: 27}], _aether._userInfo, false);\n                            tmp539 = i;\n                            _aether.logStatementStart([{ofs: 4704, row: 167, col: 15}, {ofs: 4719, row: 167, col: 30}]); tmp536 = tmp538[tmp539];  _aether.logStatement([{ofs: 4704, row: 167, col: 15}, {ofs: 4719, row: 167, col: 30}], _aether._userInfo, false);\n                            tmp537 = 'target';\n                            _aether.logStatementStart([{ofs: 4704, row: 167, col: 15}, {ofs: 4726, row: 167, col: 37}]); tmp534 = tmp536[tmp537];  _aether.logStatement([{ofs: 4704, row: 167, col: 15}, {ofs: 4726, row: 167, col: 37}], _aether._userInfo, false);\n                            tmp535 = 'type';\n                            _aether.logStatementStart([{ofs: 4704, row: 167, col: 15}, {ofs: 4731, row: 167, col: 42}]); tmp532 = tmp534[tmp535];  _aether.logStatement([{ofs: 4704, row: 167, col: 15}, {ofs: 4731, row: 167, col: 42}], _aether._userInfo, false);\n                            _aether.logStatementStart([{ofs: 4736, row: 167, col: 47}, {ofs: 4744, row: 167, col: 55}]); tmp533 = 'knight';  _aether.logStatement([{ofs: 4736, row: 167, col: 47}, {ofs: 4744, row: 167, col: 55}], _aether._userInfo, false);\n                            _aether.logStatementStart([{ofs: 4704, row: 167, col: 15}, {ofs: 4744, row: 167, col: 55}]); tmp531 = tmp532 === tmp533;  _aether.logStatement([{ofs: 4704, row: 167, col: 15}, {ofs: 4744, row: 167, col: 55}], _aether._userInfo, false);\n                            if (tmp531) {\n                                _aether.logStatementStart([{ofs: 4764, row: 168, col: 16}, {ofs: 4776, row: 168, col: 28}]); tmp542 = 1;  _aether.logStatement([{ofs: 4764, row: 168, col: 16}, {ofs: 4776, row: 168, col: 28}], _aether._userInfo, false);\n                                tmp543 = tharin;\n                                tmp544 = tmp542;\n                                tharin = tmp543 + tmp544;\n                            } else {\n                                tmp554 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n                                tmp555 = 'enemies';\n                                _aether.logStatementStart([{ofs: 4811, row: 170, col: 20}, {ofs: 4823, row: 170, col: 32}]); tmp552 = tmp554[tmp555];  _aether.logStatement([{ofs: 4811, row: 170, col: 20}, {ofs: 4823, row: 170, col: 32}], _aether._userInfo, false);\n                                tmp553 = i;\n                                _aether.logStatementStart([{ofs: 4811, row: 170, col: 20}, {ofs: 4826, row: 170, col: 35}]); tmp550 = tmp552[tmp553];  _aether.logStatement([{ofs: 4811, row: 170, col: 20}, {ofs: 4826, row: 170, col: 35}], _aether._userInfo, false);\n                                tmp551 = 'target';\n                                _aether.logStatementStart([{ofs: 4811, row: 170, col: 20}, {ofs: 4833, row: 170, col: 42}]); tmp548 = tmp550[tmp551];  _aether.logStatement([{ofs: 4811, row: 170, col: 20}, {ofs: 4833, row: 170, col: 42}], _aether._userInfo, false);\n                                tmp549 = 'type';\n                                _aether.logStatementStart([{ofs: 4811, row: 170, col: 20}, {ofs: 4838, row: 170, col: 47}]); tmp546 = tmp548[tmp549];  _aether.logStatement([{ofs: 4811, row: 170, col: 20}, {ofs: 4838, row: 170, col: 47}], _aether._userInfo, false);\n                                _aether.logStatementStart([{ofs: 4843, row: 170, col: 52}, {ofs: 4849, row: 170, col: 58}]); tmp547 = 'base';  _aether.logStatement([{ofs: 4843, row: 170, col: 52}, {ofs: 4849, row: 170, col: 58}], _aether._userInfo, false);\n                                _aether.logStatementStart([{ofs: 4811, row: 170, col: 20}, {ofs: 4849, row: 170, col: 58}]); tmp545 = tmp546 === tmp547;  _aether.logStatement([{ofs: 4811, row: 170, col: 20}, {ofs: 4849, row: 170, col: 58}], _aether._userInfo, false);\n                                if (tmp545) {\n                                    _aether.logStatementStart([{ofs: 4869, row: 171, col: 16}, {ofs: 4879, row: 171, col: 26}]); tmp556 = 1;  _aether.logStatement([{ofs: 4869, row: 171, col: 16}, {ofs: 4879, row: 171, col: 26}], _aether._userInfo, false);\n                                    tmp557 = base;\n                                    tmp558 = tmp556;\n                                    base = tmp557 + tmp558;\n                                } else {\n                                    _aether.logStatementStart([{ofs: 4929, row: 174, col: 16}, {ofs: 4940, row: 174, col: 27}]); tmp559 = 1;  _aether.logStatement([{ofs: 4929, row: 174, col: 16}, {ofs: 4940, row: 174, col: 27}], _aether._userInfo, false);\n                                    tmp560 = other;\n                                    tmp561 = tmp559;\n                                    other = tmp560 + tmp561;\n                                }\n                            }\n                        } else {\n                            tmp567 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n                            tmp568 = 'enemies';\n                            _aether.logStatementStart([{ofs: 4981, row: 177, col: 16}, {ofs: 4993, row: 177, col: 28}]); tmp565 = tmp567[tmp568];  _aether.logStatement([{ofs: 4981, row: 177, col: 16}, {ofs: 4993, row: 177, col: 28}], _aether._userInfo, false);\n                            tmp566 = i;\n                            _aether.logStatementStart([{ofs: 4981, row: 177, col: 16}, {ofs: 4996, row: 177, col: 31}]); tmp563 = tmp565[tmp566];  _aether.logStatement([{ofs: 4981, row: 177, col: 16}, {ofs: 4996, row: 177, col: 31}], _aether._userInfo, false);\n                            tmp564 = 'action';\n                            _aether.logStatementStart([{ofs: 4981, row: 177, col: 16}, {ofs: 5003, row: 177, col: 38}]); tmp562 = tmp563[tmp564];  _aether.logStatement([{ofs: 4981, row: 177, col: 16}, {ofs: 5003, row: 177, col: 38}], _aether._userInfo, false);\n                            if (tmp562) {\n                                _aether.logStatementStart([{ofs: 5019, row: 178, col: 12}, {ofs: 5030, row: 178, col: 23}]); tmp569 = 1;  _aether.logStatement([{ofs: 5019, row: 178, col: 12}, {ofs: 5030, row: 178, col: 23}], _aether._userInfo, false);\n                                tmp570 = other;\n                                tmp571 = tmp569;\n                                other = tmp570 + tmp571;\n                            } else {\n                                ;\n                            }\n                        }\n                    }\n                    tmp520 = i;\n                    tmp521 = 1;\n                    i = tmp520 + tmp521;\n                    tmp514 = i;\n                    tmp518 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n                    tmp519 = 'enemies';\n                    _aether.logStatementStart([{ofs: 4624, row: 165, col: 23}, {ofs: 4636, row: 165, col: 35}]); tmp516 = tmp518[tmp519];  _aether.logStatement([{ofs: 4624, row: 165, col: 23}, {ofs: 4636, row: 165, col: 35}], _aether._userInfo, false);\n                    tmp517 = 'length';\n                    _aether.logStatementStart([{ofs: 4624, row: 165, col: 23}, {ofs: 4643, row: 165, col: 42}]); tmp515 = tmp516[tmp517];  _aether.logStatement([{ofs: 4624, row: 165, col: 23}, {ofs: 4643, row: 165, col: 42}], _aether._userInfo, false);\n                    _aether.logStatementStart([{ofs: 4620, row: 165, col: 19}, {ofs: 4643, row: 165, col: 42}]); tmp507 = tmp514 < tmp515;  _aether.logStatement([{ofs: 4620, row: 165, col: 19}, {ofs: 4643, row: 165, col: 42}], _aether._userInfo, false);\n                }\n            }\n            tmp575 = base;\n            _aether.logStatementStart([{ofs: 5061, row: 181, col: 14}, {ofs: 5062, row: 181, col: 15}]); tmp576 = 0;  _aether.logStatement([{ofs: 5061, row: 181, col: 14}, {ofs: 5062, row: 181, col: 15}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 5054, row: 181, col: 7}, {ofs: 5062, row: 181, col: 15}]); tmp574 = tmp575 > tmp576;  _aether.logStatement([{ofs: 5054, row: 181, col: 7}, {ofs: 5062, row: 181, col: 15}], _aether._userInfo, false);\n            if (tmp574) {\n                tmp577 = tharin;\n                _aether.logStatementStart([{ofs: 5077, row: 181, col: 30}, {ofs: 5078, row: 181, col: 31}]); tmp578 = 0;  _aether.logStatement([{ofs: 5077, row: 181, col: 30}, {ofs: 5078, row: 181, col: 31}], _aether._userInfo, false);\n                _aether.logStatementStart([{ofs: 5066, row: 181, col: 19}, {ofs: 5078, row: 181, col: 31}]); tmp573 = tmp577 === tmp578;  _aether.logStatement([{ofs: 5066, row: 181, col: 19}, {ofs: 5078, row: 181, col: 31}], _aether._userInfo, false);\n            } else {\n                _aether.logStatementStart([{ofs: 5054, row: 181, col: 7}, {ofs: 5078, row: 181, col: 31}]); tmp573 = tmp574;  _aether.logStatement([{ofs: 5054, row: 181, col: 7}, {ofs: 5078, row: 181, col: 31}], _aether._userInfo, false);\n            }\n            if (tmp573) {\n                tmp579 = other;\n                _aether.logStatementStart([{ofs: 5092, row: 181, col: 45}, {ofs: 5093, row: 181, col: 46}]); tmp580 = 0;  _aether.logStatement([{ofs: 5092, row: 181, col: 45}, {ofs: 5093, row: 181, col: 46}], _aether._userInfo, false);\n                _aether.logStatementStart([{ofs: 5082, row: 181, col: 35}, {ofs: 5093, row: 181, col: 46}]); tmp572 = tmp579 === tmp580;  _aether.logStatement([{ofs: 5082, row: 181, col: 35}, {ofs: 5093, row: 181, col: 46}], _aether._userInfo, false);\n            } else {\n                _aether.logStatementStart([{ofs: 5054, row: 181, col: 7}, {ofs: 5093, row: 181, col: 46}]); tmp572 = tmp573;  _aether.logStatement([{ofs: 5054, row: 181, col: 7}, {ofs: 5093, row: 181, col: 46}], _aether._userInfo, false);\n            }\n            if (tmp572) {\n                _aether.logStatementStart([{ofs: 5112, row: 182, col: 15}, {ofs: 5113, row: 182, col: 16}]); tmp581 = 1;  _aether.logStatement([{ofs: 5112, row: 182, col: 15}, {ofs: 5113, row: 182, col: 16}], _aether._userInfo, false);\n                return _aether.restoreAPIClone(_aether, tmp581);\n            } else {\n                tmp585 = tharin;\n                _aether.logStatementStart([{ofs: 5142, row: 184, col: 21}, {ofs: 5143, row: 184, col: 22}]); tmp586 = 0;  _aether.logStatement([{ofs: 5142, row: 184, col: 21}, {ofs: 5143, row: 184, col: 22}], _aether._userInfo, false);\n                _aether.logStatementStart([{ofs: 5133, row: 184, col: 12}, {ofs: 5143, row: 184, col: 22}]); tmp584 = tmp585 > tmp586;  _aether.logStatement([{ofs: 5133, row: 184, col: 12}, {ofs: 5143, row: 184, col: 22}], _aether._userInfo, false);\n                if (tmp584) {\n                    tmp587 = base;\n                    _aether.logStatementStart([{ofs: 5156, row: 184, col: 35}, {ofs: 5157, row: 184, col: 36}]); tmp588 = 0;  _aether.logStatement([{ofs: 5156, row: 184, col: 35}, {ofs: 5157, row: 184, col: 36}], _aether._userInfo, false);\n                    _aether.logStatementStart([{ofs: 5147, row: 184, col: 26}, {ofs: 5157, row: 184, col: 36}]); tmp583 = tmp587 === tmp588;  _aether.logStatement([{ofs: 5147, row: 184, col: 26}, {ofs: 5157, row: 184, col: 36}], _aether._userInfo, false);\n                } else {\n                    _aether.logStatementStart([{ofs: 5133, row: 184, col: 12}, {ofs: 5157, row: 184, col: 36}]); tmp583 = tmp584;  _aether.logStatement([{ofs: 5133, row: 184, col: 12}, {ofs: 5157, row: 184, col: 36}], _aether._userInfo, false);\n                }\n                if (tmp583) {\n                    tmp589 = other;\n                    _aether.logStatementStart([{ofs: 5171, row: 184, col: 50}, {ofs: 5172, row: 184, col: 51}]); tmp590 = 0;  _aether.logStatement([{ofs: 5171, row: 184, col: 50}, {ofs: 5172, row: 184, col: 51}], _aether._userInfo, false);\n                    _aether.logStatementStart([{ofs: 5161, row: 184, col: 40}, {ofs: 5172, row: 184, col: 51}]); tmp582 = tmp589 === tmp590;  _aether.logStatement([{ofs: 5161, row: 184, col: 40}, {ofs: 5172, row: 184, col: 51}], _aether._userInfo, false);\n                } else {\n                    _aether.logStatementStart([{ofs: 5133, row: 184, col: 12}, {ofs: 5172, row: 184, col: 51}]); tmp582 = tmp583;  _aether.logStatement([{ofs: 5133, row: 184, col: 12}, {ofs: 5172, row: 184, col: 51}], _aether._userInfo, false);\n                }\n                if (tmp582) {\n                    _aether.logStatementStart([{ofs: 5191, row: 185, col: 15}, {ofs: 5192, row: 185, col: 16}]); tmp591 = 2;  _aether.logStatement([{ofs: 5191, row: 185, col: 15}, {ofs: 5192, row: 185, col: 16}], _aether._userInfo, false);\n                    return _aether.restoreAPIClone(_aether, tmp591);\n                } else {\n                    tmp595 = tharin;\n                    _aether.logStatementStart([{ofs: 5221, row: 187, col: 21}, {ofs: 5222, row: 187, col: 22}]); tmp596 = 0;  _aether.logStatement([{ofs: 5221, row: 187, col: 21}, {ofs: 5222, row: 187, col: 22}], _aether._userInfo, false);\n                    _aether.logStatementStart([{ofs: 5212, row: 187, col: 12}, {ofs: 5222, row: 187, col: 22}]); tmp594 = tmp595 > tmp596;  _aether.logStatement([{ofs: 5212, row: 187, col: 12}, {ofs: 5222, row: 187, col: 22}], _aether._userInfo, false);\n                    if (tmp594) {\n                        tmp597 = base;\n                        _aether.logStatementStart([{ofs: 5233, row: 187, col: 33}, {ofs: 5234, row: 187, col: 34}]); tmp598 = 0;  _aether.logStatement([{ofs: 5233, row: 187, col: 33}, {ofs: 5234, row: 187, col: 34}], _aether._userInfo, false);\n                        _aether.logStatementStart([{ofs: 5226, row: 187, col: 26}, {ofs: 5234, row: 187, col: 34}]); tmp593 = tmp597 > tmp598;  _aether.logStatement([{ofs: 5226, row: 187, col: 26}, {ofs: 5234, row: 187, col: 34}], _aether._userInfo, false);\n                    } else {\n                        _aether.logStatementStart([{ofs: 5212, row: 187, col: 12}, {ofs: 5234, row: 187, col: 34}]); tmp593 = tmp594;  _aether.logStatement([{ofs: 5212, row: 187, col: 12}, {ofs: 5234, row: 187, col: 34}], _aether._userInfo, false);\n                    }\n                    if (tmp593) {\n                        tmp599 = other;\n                        _aether.logStatementStart([{ofs: 5248, row: 187, col: 48}, {ofs: 5249, row: 187, col: 49}]); tmp600 = 0;  _aether.logStatement([{ofs: 5248, row: 187, col: 48}, {ofs: 5249, row: 187, col: 49}], _aether._userInfo, false);\n                        _aether.logStatementStart([{ofs: 5238, row: 187, col: 38}, {ofs: 5249, row: 187, col: 49}]); tmp592 = tmp599 === tmp600;  _aether.logStatement([{ofs: 5238, row: 187, col: 38}, {ofs: 5249, row: 187, col: 49}], _aether._userInfo, false);\n                    } else {\n                        _aether.logStatementStart([{ofs: 5212, row: 187, col: 12}, {ofs: 5249, row: 187, col: 49}]); tmp592 = tmp593;  _aether.logStatement([{ofs: 5212, row: 187, col: 12}, {ofs: 5249, row: 187, col: 49}], _aether._userInfo, false);\n                    }\n                    if (tmp592) {\n                        _aether.logStatementStart([{ofs: 5268, row: 188, col: 15}, {ofs: 5269, row: 188, col: 16}]); tmp601 = 3;  _aether.logStatement([{ofs: 5268, row: 188, col: 15}, {ofs: 5269, row: 188, col: 16}], _aether._userInfo, false);\n                        return _aether.restoreAPIClone(_aether, tmp601);\n                    } else {\n                        tmp604 = other;\n                        _aether.logStatementStart([{ofs: 5297, row: 190, col: 20}, {ofs: 5298, row: 190, col: 21}]); tmp605 = 0;  _aether.logStatement([{ofs: 5297, row: 190, col: 20}, {ofs: 5298, row: 190, col: 21}], _aether._userInfo, false);\n                        _aether.logStatementStart([{ofs: 5289, row: 190, col: 12}, {ofs: 5298, row: 190, col: 21}]); tmp603 = tmp604 > tmp605;  _aether.logStatement([{ofs: 5289, row: 190, col: 12}, {ofs: 5298, row: 190, col: 21}], _aether._userInfo, false);\n                        if (tmp603) {\n                            tmp607 = tharin;\n                            _aether.logStatementStart([{ofs: 5312, row: 190, col: 35}, {ofs: 5313, row: 190, col: 36}]); tmp608 = 0;  _aether.logStatement([{ofs: 5312, row: 190, col: 35}, {ofs: 5313, row: 190, col: 36}], _aether._userInfo, false);\n                            _aether.logStatementStart([{ofs: 5303, row: 190, col: 26}, {ofs: 5313, row: 190, col: 36}]); tmp606 = tmp607 > tmp608;  _aether.logStatement([{ofs: 5303, row: 190, col: 26}, {ofs: 5313, row: 190, col: 36}], _aether._userInfo, false);\n                            if (tmp606) {\n                                _aether.logStatementStart([{ofs: 5303, row: 190, col: 26}, {ofs: 5325, row: 190, col: 48}]); tmp602 = tmp606;  _aether.logStatement([{ofs: 5303, row: 190, col: 26}, {ofs: 5325, row: 190, col: 48}], _aether._userInfo, false);\n                            } else {\n                                tmp609 = base;\n                                _aether.logStatementStart([{ofs: 5324, row: 190, col: 47}, {ofs: 5325, row: 190, col: 48}]); tmp610 = 0;  _aether.logStatement([{ofs: 5324, row: 190, col: 47}, {ofs: 5325, row: 190, col: 48}], _aether._userInfo, false);\n                                _aether.logStatementStart([{ofs: 5317, row: 190, col: 40}, {ofs: 5325, row: 190, col: 48}]); tmp602 = tmp609 > tmp610;  _aether.logStatement([{ofs: 5317, row: 190, col: 40}, {ofs: 5325, row: 190, col: 48}], _aether._userInfo, false);\n                            }\n                        } else {\n                            _aether.logStatementStart([{ofs: 5289, row: 190, col: 12}, {ofs: 5326, row: 190, col: 49}]); tmp602 = tmp603;  _aether.logStatement([{ofs: 5289, row: 190, col: 12}, {ofs: 5326, row: 190, col: 49}], _aether._userInfo, false);\n                        }\n                        if (tmp602) {\n                            _aether.logStatementStart([{ofs: 5345, row: 191, col: 15}, {ofs: 5346, row: 191, col: 16}]); tmp611 = 4;  _aether.logStatement([{ofs: 5345, row: 191, col: 15}, {ofs: 5346, row: 191, col: 16}], _aether._userInfo, false);\n                            return _aether.restoreAPIClone(_aether, tmp611);\n                        } else {\n                            tmp615 = other;\n                            _aether.logStatementStart([{ofs: 5374, row: 193, col: 20}, {ofs: 5375, row: 193, col: 21}]); tmp616 = 0;  _aether.logStatement([{ofs: 5374, row: 193, col: 20}, {ofs: 5375, row: 193, col: 21}], _aether._userInfo, false);\n                            _aether.logStatementStart([{ofs: 5366, row: 193, col: 12}, {ofs: 5375, row: 193, col: 21}]); tmp614 = tmp615 > tmp616;  _aether.logStatement([{ofs: 5366, row: 193, col: 12}, {ofs: 5375, row: 193, col: 21}], _aether._userInfo, false);\n                            if (tmp614) {\n                                tmp617 = tharin;\n                                _aether.logStatementStart([{ofs: 5390, row: 193, col: 36}, {ofs: 5391, row: 193, col: 37}]); tmp618 = 0;  _aether.logStatement([{ofs: 5390, row: 193, col: 36}, {ofs: 5391, row: 193, col: 37}], _aether._userInfo, false);\n                                _aether.logStatementStart([{ofs: 5379, row: 193, col: 25}, {ofs: 5391, row: 193, col: 37}]); tmp613 = tmp617 === tmp618;  _aether.logStatement([{ofs: 5379, row: 193, col: 25}, {ofs: 5391, row: 193, col: 37}], _aether._userInfo, false);\n                            } else {\n                                _aether.logStatementStart([{ofs: 5366, row: 193, col: 12}, {ofs: 5391, row: 193, col: 37}]); tmp613 = tmp614;  _aether.logStatement([{ofs: 5366, row: 193, col: 12}, {ofs: 5391, row: 193, col: 37}], _aether._userInfo, false);\n                            }\n                            if (tmp613) {\n                                tmp619 = base;\n                                _aether.logStatementStart([{ofs: 5404, row: 193, col: 50}, {ofs: 5405, row: 193, col: 51}]); tmp620 = 0;  _aether.logStatement([{ofs: 5404, row: 193, col: 50}, {ofs: 5405, row: 193, col: 51}], _aether._userInfo, false);\n                                _aether.logStatementStart([{ofs: 5395, row: 193, col: 41}, {ofs: 5405, row: 193, col: 51}]); tmp612 = tmp619 === tmp620;  _aether.logStatement([{ofs: 5395, row: 193, col: 41}, {ofs: 5405, row: 193, col: 51}], _aether._userInfo, false);\n                            } else {\n                                _aether.logStatementStart([{ofs: 5366, row: 193, col: 12}, {ofs: 5405, row: 193, col: 51}]); tmp612 = tmp613;  _aether.logStatement([{ofs: 5366, row: 193, col: 12}, {ofs: 5405, row: 193, col: 51}], _aether._userInfo, false);\n                            }\n                            if (tmp612) {\n                                _aether.logStatementStart([{ofs: 5424, row: 194, col: 15}, {ofs: 5425, row: 194, col: 16}]); tmp621 = 5;  _aether.logStatement([{ofs: 5424, row: 194, col: 15}, {ofs: 5425, row: 194, col: 16}], _aether._userInfo, false);\n                                return _aether.restoreAPIClone(_aether, tmp621);\n                            } else {\n                                ;\n                            }\n                        }\n                    }\n                }\n            }\n            _aether.logStatementStart([{ofs: 5561, row: 199, col: 11}, {ofs: 5562, row: 199, col: 12}]); tmp622 = 0;  _aether.logStatement([{ofs: 5561, row: 199, col: 11}, {ofs: 5562, row: 199, col: 12}], _aether._userInfo, false);\n            return _aether.restoreAPIClone(_aether, tmp622);\n        };  _aether.logStatement([{ofs: 4240, row: 151, col: 0}, {ofs: 5566, row: 200, col: 2}], _aether._userInfo, false);\n        _aether.logStatementStart([{ofs: 4240, row: 151, col: 0}, {ofs: 5565, row: 200, col: 1}]); tmp494[tmp495] = tmp496;  _aether.logStatement([{ofs: 4240, row: 151, col: 0}, {ofs: 5565, row: 200, col: 1}], _aether._userInfo, false);\n        tmp623 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n        tmp624 = 'friends';\n        tmp626 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n        tmp627 = 'getFriends';\n        _aether.logStatementStart([{ofs: 5568, row: 202, col: 0}, {ofs: 5601, row: 202, col: 33}]); tmp625 = _aether.createAPIClone(_aether, tmp626[tmp627]());  _aether.logStatement([{ofs: 5568, row: 202, col: 0}, {ofs: 5601, row: 202, col: 33}], _aether._userInfo, false);\n        _aether.logStatementStart([{ofs: 5568, row: 202, col: 0}, {ofs: 5600, row: 202, col: 32}]); tmp623[tmp624] = tmp625;  _aether.logStatement([{ofs: 5568, row: 202, col: 0}, {ofs: 5600, row: 202, col: 32}], _aether._userInfo, false);\n        tmp628 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n        tmp629 = 'enemies';\n        tmp631 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n        tmp632 = 'getEnemies';\n        _aether.logStatementStart([{ofs: 5602, row: 203, col: 0}, {ofs: 5635, row: 203, col: 33}]); tmp630 = _aether.createAPIClone(_aether, tmp631[tmp632]());  _aether.logStatement([{ofs: 5602, row: 203, col: 0}, {ofs: 5635, row: 203, col: 33}], _aether._userInfo, false);\n        _aether.logStatementStart([{ofs: 5602, row: 203, col: 0}, {ofs: 5634, row: 203, col: 32}]); tmp628[tmp629] = tmp630;  _aether.logStatement([{ofs: 5602, row: 203, col: 0}, {ofs: 5634, row: 203, col: 32}], _aether._userInfo, false);\n        tmp633 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n        tmp634 = 'terrifyClumpMinSize';\n        _aether.logStatementStart([{ofs: 5826, row: 211, col: 0}, {ofs: 5855, row: 211, col: 29}]); tmp635 = 3;  _aether.logStatement([{ofs: 5826, row: 211, col: 0}, {ofs: 5855, row: 211, col: 29}], _aether._userInfo, false);\n        _aether.logStatementStart([{ofs: 5826, row: 211, col: 0}, {ofs: 5854, row: 211, col: 28}]); tmp633[tmp634] = tmp635;  _aether.logStatement([{ofs: 5826, row: 211, col: 0}, {ofs: 5854, row: 211, col: 28}], _aether._userInfo, false);\n        tmp638 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n        tmp639 = 'enemyBase';\n        _aether.logStatementStart([{ofs: 6007, row: 217, col: 4}, {ofs: 6021, row: 217, col: 18}]); tmp637 = tmp638[tmp639];  _aether.logStatement([{ofs: 6007, row: 217, col: 4}, {ofs: 6021, row: 217, col: 18}], _aether._userInfo, false);\n        _aether.logStatementStart([{ofs: 6006, row: 217, col: 3}, {ofs: 6021, row: 217, col: 18}]); tmp636 = !tmp637;  _aether.logStatement([{ofs: 6006, row: 217, col: 3}, {ofs: 6021, row: 217, col: 18}], _aether._userInfo, false);\n        if (tmp636) {\n            tmp640 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n            tmp641 = 'enemyBase';\n            tmp643 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n            tmp644 = 'getEnemyBase';\n            _aether.logStatementStart([{ofs: 6029, row: 218, col: 4}, {ofs: 6066, row: 218, col: 41}]); tmp642 = _aether.createAPIClone(_aether, tmp643[tmp644]());  _aether.logStatement([{ofs: 6029, row: 218, col: 4}, {ofs: 6066, row: 218, col: 41}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 6029, row: 218, col: 4}, {ofs: 6065, row: 218, col: 40}]); tmp640[tmp641] = tmp642;  _aether.logStatement([{ofs: 6029, row: 218, col: 4}, {ofs: 6065, row: 218, col: 40}], _aether._userInfo, false);\n        } else {\n            ;\n        }\n        tmp647 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n        tmp648 = 'enemyHero';\n        _aether.logStatementStart([{ofs: 6073, row: 220, col: 4}, {ofs: 6087, row: 220, col: 18}]); tmp646 = tmp647[tmp648];  _aether.logStatement([{ofs: 6073, row: 220, col: 4}, {ofs: 6087, row: 220, col: 18}], _aether._userInfo, false);\n        _aether.logStatementStart([{ofs: 6072, row: 220, col: 3}, {ofs: 6087, row: 220, col: 18}]); tmp645 = !tmp646;  _aether.logStatement([{ofs: 6072, row: 220, col: 3}, {ofs: 6087, row: 220, col: 18}], _aether._userInfo, false);\n        if (tmp645) {\n            tmp649 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n            tmp650 = 'enemyHero';\n            tmp652 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n            tmp653 = 'getEnemyHero';\n            _aether.logStatementStart([{ofs: 6095, row: 221, col: 4}, {ofs: 6132, row: 221, col: 41}]); tmp651 = _aether.createAPIClone(_aether, tmp652[tmp653]());  _aether.logStatement([{ofs: 6095, row: 221, col: 4}, {ofs: 6132, row: 221, col: 41}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 6095, row: 221, col: 4}, {ofs: 6131, row: 221, col: 40}]); tmp649[tmp650] = tmp651;  _aether.logStatement([{ofs: 6095, row: 221, col: 4}, {ofs: 6131, row: 221, col: 40}], _aether._userInfo, false);\n        } else {\n            ;\n        }\n        tmp660 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n        tmp661 = 'enemies';\n        _aether.logStatementStart([{ofs: 6231, row: 225, col: 3}, {ofs: 6243, row: 225, col: 15}]); tmp658 = tmp660[tmp661];  _aether.logStatement([{ofs: 6231, row: 225, col: 3}, {ofs: 6243, row: 225, col: 15}], _aether._userInfo, false);\n        tmp659 = 'length';\n        _aether.logStatementStart([{ofs: 6231, row: 225, col: 3}, {ofs: 6250, row: 225, col: 22}]); tmp656 = tmp658[tmp659];  _aether.logStatement([{ofs: 6231, row: 225, col: 3}, {ofs: 6250, row: 225, col: 22}], _aether._userInfo, false);\n        _aether.logStatementStart([{ofs: 6255, row: 225, col: 27}, {ofs: 6256, row: 225, col: 28}]); tmp657 = 2;  _aether.logStatement([{ofs: 6255, row: 225, col: 27}, {ofs: 6256, row: 225, col: 28}], _aether._userInfo, false);\n        _aether.logStatementStart([{ofs: 6231, row: 225, col: 3}, {ofs: 6256, row: 225, col: 28}]); tmp655 = tmp656 === tmp657;  _aether.logStatement([{ofs: 6231, row: 225, col: 3}, {ofs: 6256, row: 225, col: 28}], _aether._userInfo, false);\n        if (tmp655) {\n            tmp669 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n            tmp670 = 'enemies';\n            _aether.logStatementStart([{ofs: 6261, row: 225, col: 33}, {ofs: 6273, row: 225, col: 45}]); tmp667 = tmp669[tmp670];  _aether.logStatement([{ofs: 6261, row: 225, col: 33}, {ofs: 6273, row: 225, col: 45}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 6274, row: 225, col: 46}, {ofs: 6275, row: 225, col: 47}]); tmp668 = 1;  _aether.logStatement([{ofs: 6274, row: 225, col: 46}, {ofs: 6275, row: 225, col: 47}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 6261, row: 225, col: 33}, {ofs: 6276, row: 225, col: 48}]); tmp665 = tmp667[tmp668];  _aether.logStatement([{ofs: 6261, row: 225, col: 33}, {ofs: 6276, row: 225, col: 48}], _aether._userInfo, false);\n            tmp666 = 'type';\n            _aether.logStatementStart([{ofs: 6261, row: 225, col: 33}, {ofs: 6281, row: 225, col: 53}]); tmp663 = tmp665[tmp666];  _aether.logStatement([{ofs: 6261, row: 225, col: 33}, {ofs: 6281, row: 225, col: 53}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 6286, row: 225, col: 58}, {ofs: 6296, row: 225, col: 68}]); tmp664 = 'munchkin';  _aether.logStatement([{ofs: 6286, row: 225, col: 58}, {ofs: 6296, row: 225, col: 68}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 6261, row: 225, col: 33}, {ofs: 6296, row: 225, col: 68}]); tmp662 = tmp663 === tmp664;  _aether.logStatement([{ofs: 6261, row: 225, col: 33}, {ofs: 6296, row: 225, col: 68}], _aether._userInfo, false);\n            if (tmp662) {\n                _aether.logStatementStart([{ofs: 6261, row: 225, col: 33}, {ofs: 6334, row: 225, col: 106}]); tmp654 = tmp662;  _aether.logStatement([{ofs: 6261, row: 225, col: 33}, {ofs: 6334, row: 225, col: 106}], _aether._userInfo, false);\n            } else {\n                tmp677 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n                tmp678 = 'enemies';\n                _aether.logStatementStart([{ofs: 6300, row: 225, col: 72}, {ofs: 6312, row: 225, col: 84}]); tmp675 = tmp677[tmp678];  _aether.logStatement([{ofs: 6300, row: 225, col: 72}, {ofs: 6312, row: 225, col: 84}], _aether._userInfo, false);\n                _aether.logStatementStart([{ofs: 6313, row: 225, col: 85}, {ofs: 6314, row: 225, col: 86}]); tmp676 = 1;  _aether.logStatement([{ofs: 6313, row: 225, col: 85}, {ofs: 6314, row: 225, col: 86}], _aether._userInfo, false);\n                _aether.logStatementStart([{ofs: 6300, row: 225, col: 72}, {ofs: 6315, row: 225, col: 87}]); tmp673 = tmp675[tmp676];  _aether.logStatement([{ofs: 6300, row: 225, col: 72}, {ofs: 6315, row: 225, col: 87}], _aether._userInfo, false);\n                tmp674 = 'type';\n                _aether.logStatementStart([{ofs: 6300, row: 225, col: 72}, {ofs: 6320, row: 225, col: 92}]); tmp671 = tmp673[tmp674];  _aether.logStatement([{ofs: 6300, row: 225, col: 72}, {ofs: 6320, row: 225, col: 92}], _aether._userInfo, false);\n                _aether.logStatementStart([{ofs: 6325, row: 225, col: 97}, {ofs: 6334, row: 225, col: 106}]); tmp672 = 'thrower';  _aether.logStatement([{ofs: 6325, row: 225, col: 97}, {ofs: 6334, row: 225, col: 106}], _aether._userInfo, false);\n                _aether.logStatementStart([{ofs: 6300, row: 225, col: 72}, {ofs: 6334, row: 225, col: 106}]); tmp654 = tmp671 === tmp672;  _aether.logStatement([{ofs: 6300, row: 225, col: 72}, {ofs: 6334, row: 225, col: 106}], _aether._userInfo, false);\n            }\n        } else {\n            _aether.logStatementStart([{ofs: 6231, row: 225, col: 3}, {ofs: 6335, row: 225, col: 107}]); tmp654 = tmp655;  _aether.logStatement([{ofs: 6231, row: 225, col: 3}, {ofs: 6335, row: 225, col: 107}], _aether._userInfo, false);\n        }\n        if (tmp654) {\n            tmp679 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n            tmp680 = 'baseRace';\n            _aether.logStatementStart([{ofs: 6343, row: 226, col: 4}, {ofs: 6364, row: 226, col: 25}]); tmp681 = true;  _aether.logStatement([{ofs: 6343, row: 226, col: 4}, {ofs: 6364, row: 226, col: 25}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 6343, row: 226, col: 4}, {ofs: 6363, row: 226, col: 24}]); tmp679[tmp680] = tmp681;  _aether.logStatement([{ofs: 6343, row: 226, col: 4}, {ofs: 6363, row: 226, col: 24}], _aether._userInfo, false);\n            tmp682 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n            tmp683 = 'notHeroFirst';\n            _aether.logStatementStart([{ofs: 6369, row: 227, col: 4}, {ofs: 6394, row: 227, col: 29}]); tmp684 = true;  _aether.logStatement([{ofs: 6369, row: 227, col: 4}, {ofs: 6394, row: 227, col: 29}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 6369, row: 227, col: 4}, {ofs: 6393, row: 227, col: 28}]); tmp682[tmp683] = tmp684;  _aether.logStatement([{ofs: 6369, row: 227, col: 4}, {ofs: 6393, row: 227, col: 28}], _aether._userInfo, false);\n        } else {\n            ;\n        }\n        tmp688 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n        tmp689 = 'notHeroFirst';\n        _aether.logStatementStart([{ofs: 6400, row: 229, col: 3}, {ofs: 6417, row: 229, col: 20}]); tmp687 = tmp688[tmp689];  _aether.logStatement([{ofs: 6400, row: 229, col: 3}, {ofs: 6417, row: 229, col: 20}], _aether._userInfo, false);\n        if (tmp687) {\n            tmp694 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n            tmp695 = 'enemies';\n            _aether.logStatementStart([{ofs: 6421, row: 229, col: 24}, {ofs: 6433, row: 229, col: 36}]); tmp692 = tmp694[tmp695];  _aether.logStatement([{ofs: 6421, row: 229, col: 24}, {ofs: 6433, row: 229, col: 36}], _aether._userInfo, false);\n            tmp693 = 'length';\n            _aether.logStatementStart([{ofs: 6421, row: 229, col: 24}, {ofs: 6440, row: 229, col: 43}]); tmp690 = tmp692[tmp693];  _aether.logStatement([{ofs: 6421, row: 229, col: 24}, {ofs: 6440, row: 229, col: 43}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 6445, row: 229, col: 48}, {ofs: 6446, row: 229, col: 49}]); tmp691 = 3;  _aether.logStatement([{ofs: 6445, row: 229, col: 48}, {ofs: 6446, row: 229, col: 49}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 6421, row: 229, col: 24}, {ofs: 6446, row: 229, col: 49}]); tmp686 = tmp690 === tmp691;  _aether.logStatement([{ofs: 6421, row: 229, col: 24}, {ofs: 6446, row: 229, col: 49}], _aether._userInfo, false);\n        } else {\n            _aether.logStatementStart([{ofs: 6400, row: 229, col: 3}, {ofs: 6446, row: 229, col: 49}]); tmp686 = tmp687;  _aether.logStatement([{ofs: 6400, row: 229, col: 3}, {ofs: 6446, row: 229, col: 49}], _aether._userInfo, false);\n        }\n        if (tmp686) {\n            tmp703 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n            tmp704 = 'enemies';\n            _aether.logStatementStart([{ofs: 6451, row: 229, col: 54}, {ofs: 6463, row: 229, col: 66}]); tmp701 = tmp703[tmp704];  _aether.logStatement([{ofs: 6451, row: 229, col: 54}, {ofs: 6463, row: 229, col: 66}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 6464, row: 229, col: 67}, {ofs: 6465, row: 229, col: 68}]); tmp702 = 1;  _aether.logStatement([{ofs: 6464, row: 229, col: 67}, {ofs: 6465, row: 229, col: 68}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 6451, row: 229, col: 54}, {ofs: 6466, row: 229, col: 69}]); tmp699 = tmp701[tmp702];  _aether.logStatement([{ofs: 6451, row: 229, col: 54}, {ofs: 6466, row: 229, col: 69}], _aether._userInfo, false);\n            tmp700 = 'type';\n            _aether.logStatementStart([{ofs: 6451, row: 229, col: 54}, {ofs: 6471, row: 229, col: 74}]); tmp697 = tmp699[tmp700];  _aether.logStatement([{ofs: 6451, row: 229, col: 54}, {ofs: 6471, row: 229, col: 74}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 6476, row: 229, col: 79}, {ofs: 6486, row: 229, col: 89}]); tmp698 = 'munchkin';  _aether.logStatement([{ofs: 6476, row: 229, col: 79}, {ofs: 6486, row: 229, col: 89}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 6451, row: 229, col: 54}, {ofs: 6486, row: 229, col: 89}]); tmp696 = tmp697 === tmp698;  _aether.logStatement([{ofs: 6451, row: 229, col: 54}, {ofs: 6486, row: 229, col: 89}], _aether._userInfo, false);\n            if (tmp696) {\n                _aether.logStatementStart([{ofs: 6451, row: 229, col: 54}, {ofs: 6524, row: 229, col: 127}]); tmp685 = tmp696;  _aether.logStatement([{ofs: 6451, row: 229, col: 54}, {ofs: 6524, row: 229, col: 127}], _aether._userInfo, false);\n            } else {\n                tmp711 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n                tmp712 = 'enemies';\n                _aether.logStatementStart([{ofs: 6490, row: 229, col: 93}, {ofs: 6502, row: 229, col: 105}]); tmp709 = tmp711[tmp712];  _aether.logStatement([{ofs: 6490, row: 229, col: 93}, {ofs: 6502, row: 229, col: 105}], _aether._userInfo, false);\n                _aether.logStatementStart([{ofs: 6503, row: 229, col: 106}, {ofs: 6504, row: 229, col: 107}]); tmp710 = 1;  _aether.logStatement([{ofs: 6503, row: 229, col: 106}, {ofs: 6504, row: 229, col: 107}], _aether._userInfo, false);\n                _aether.logStatementStart([{ofs: 6490, row: 229, col: 93}, {ofs: 6505, row: 229, col: 108}]); tmp707 = tmp709[tmp710];  _aether.logStatement([{ofs: 6490, row: 229, col: 93}, {ofs: 6505, row: 229, col: 108}], _aether._userInfo, false);\n                tmp708 = 'type';\n                _aether.logStatementStart([{ofs: 6490, row: 229, col: 93}, {ofs: 6510, row: 229, col: 113}]); tmp705 = tmp707[tmp708];  _aether.logStatement([{ofs: 6490, row: 229, col: 93}, {ofs: 6510, row: 229, col: 113}], _aether._userInfo, false);\n                _aether.logStatementStart([{ofs: 6515, row: 229, col: 118}, {ofs: 6524, row: 229, col: 127}]); tmp706 = 'thrower';  _aether.logStatement([{ofs: 6515, row: 229, col: 118}, {ofs: 6524, row: 229, col: 127}], _aether._userInfo, false);\n                _aether.logStatementStart([{ofs: 6490, row: 229, col: 93}, {ofs: 6524, row: 229, col: 127}]); tmp685 = tmp705 === tmp706;  _aether.logStatement([{ofs: 6490, row: 229, col: 93}, {ofs: 6524, row: 229, col: 127}], _aether._userInfo, false);\n            }\n        } else {\n            _aether.logStatementStart([{ofs: 6400, row: 229, col: 3}, {ofs: 6525, row: 229, col: 128}]); tmp685 = tmp686;  _aether.logStatement([{ofs: 6400, row: 229, col: 3}, {ofs: 6525, row: 229, col: 128}], _aether._userInfo, false);\n        }\n        if (tmp685) {\n            tmp713 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n            tmp714 = 'notHeroSecond';\n            _aether.logStatementStart([{ofs: 6808, row: 235, col: 4}, {ofs: 6834, row: 235, col: 30}]); tmp715 = true;  _aether.logStatement([{ofs: 6808, row: 235, col: 4}, {ofs: 6834, row: 235, col: 30}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 6808, row: 235, col: 4}, {ofs: 6833, row: 235, col: 29}]); tmp713[tmp714] = tmp715;  _aether.logStatement([{ofs: 6808, row: 235, col: 4}, {ofs: 6833, row: 235, col: 29}], _aether._userInfo, false);\n        } else {\n            ;\n        }\n        tmp721 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n        tmp722 = 'earlyJump';\n        _aether.logStatementStart([{ofs: 7003, row: 243, col: 4}, {ofs: 7017, row: 243, col: 18}]); tmp720 = tmp721[tmp722];  _aether.logStatement([{ofs: 7003, row: 243, col: 4}, {ofs: 7017, row: 243, col: 18}], _aether._userInfo, false);\n        _aether.logStatementStart([{ofs: 7002, row: 243, col: 3}, {ofs: 7017, row: 243, col: 18}]); tmp719 = !tmp720;  _aether.logStatement([{ofs: 7002, row: 243, col: 3}, {ofs: 7017, row: 243, col: 18}], _aether._userInfo, false);\n        if (tmp719) {\n            tmp723 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n            tmp724 = 'enemyHero';\n            _aether.logStatementStart([{ofs: 7021, row: 243, col: 22}, {ofs: 7035, row: 243, col: 36}]); tmp718 = tmp723[tmp724];  _aether.logStatement([{ofs: 7021, row: 243, col: 22}, {ofs: 7035, row: 243, col: 36}], _aether._userInfo, false);\n        } else {\n            _aether.logStatementStart([{ofs: 7002, row: 243, col: 3}, {ofs: 7035, row: 243, col: 36}]); tmp718 = tmp719;  _aether.logStatement([{ofs: 7002, row: 243, col: 3}, {ofs: 7035, row: 243, col: 36}], _aether._userInfo, false);\n        }\n        if (tmp718) {\n            tmp727 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n            tmp728 = 'enemyHero';\n            _aether.logStatementStart([{ofs: 7039, row: 243, col: 40}, {ofs: 7053, row: 243, col: 54}]); tmp725 = tmp727[tmp728];  _aether.logStatement([{ofs: 7039, row: 243, col: 40}, {ofs: 7053, row: 243, col: 54}], _aether._userInfo, false);\n            tmp726 = 'action';\n            _aether.logStatementStart([{ofs: 7039, row: 243, col: 40}, {ofs: 7060, row: 243, col: 61}]); tmp717 = tmp725[tmp726];  _aether.logStatement([{ofs: 7039, row: 243, col: 40}, {ofs: 7060, row: 243, col: 61}], _aether._userInfo, false);\n        } else {\n            _aether.logStatementStart([{ofs: 7002, row: 243, col: 3}, {ofs: 7060, row: 243, col: 61}]); tmp717 = tmp718;  _aether.logStatement([{ofs: 7002, row: 243, col: 3}, {ofs: 7060, row: 243, col: 61}], _aether._userInfo, false);\n        }\n        if (tmp717) {\n            tmp731 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n            tmp732 = 'now';\n            _aether.logStatementStart([{ofs: 7064, row: 243, col: 65}, {ofs: 7074, row: 243, col: 75}]); tmp729 = _aether.createAPIClone(_aether, tmp731[tmp732]());  _aether.logStatement([{ofs: 7064, row: 243, col: 65}, {ofs: 7074, row: 243, col: 75}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 7078, row: 243, col: 79}, {ofs: 7079, row: 243, col: 80}]); tmp730 = 1;  _aether.logStatement([{ofs: 7078, row: 243, col: 79}, {ofs: 7079, row: 243, col: 80}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 7064, row: 243, col: 65}, {ofs: 7079, row: 243, col: 80}]); tmp716 = tmp729 <= tmp730;  _aether.logStatement([{ofs: 7064, row: 243, col: 65}, {ofs: 7079, row: 243, col: 80}], _aether._userInfo, false);\n        } else {\n            _aether.logStatementStart([{ofs: 7002, row: 243, col: 3}, {ofs: 7079, row: 243, col: 80}]); tmp716 = tmp717;  _aether.logStatement([{ofs: 7002, row: 243, col: 3}, {ofs: 7079, row: 243, col: 80}], _aether._userInfo, false);\n        }\n        if (tmp716) {\n            tmp733 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n            tmp734 = 'say';\n            _aether.logStatementStart([{ofs: 7096, row: 244, col: 13}, {ofs: 7107, row: 244, col: 24}]); tmp735 = 'follow me';  _aether.logStatement([{ofs: 7096, row: 244, col: 13}, {ofs: 7107, row: 244, col: 24}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 7087, row: 244, col: 4}, {ofs: 7108, row: 244, col: 25}]); tmp736 = _aether.createAPIClone(_aether, tmp733[tmp734](_aether.restoreAPIClone(_aether, tmp735)));  _aether.logStatement([{ofs: 7087, row: 244, col: 4}, {ofs: 7108, row: 244, col: 25}], _aether._userInfo, false);\n            tmp742 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n            tmp743 = 'enemyHero';\n            _aether.logStatementStart([{ofs: 7117, row: 245, col: 7}, {ofs: 7131, row: 245, col: 21}]); tmp740 = tmp742[tmp743];  _aether.logStatement([{ofs: 7117, row: 245, col: 7}, {ofs: 7131, row: 245, col: 21}], _aether._userInfo, false);\n            tmp741 = 'action';\n            _aether.logStatementStart([{ofs: 7117, row: 245, col: 7}, {ofs: 7138, row: 245, col: 28}]); tmp738 = tmp740[tmp741];  _aether.logStatement([{ofs: 7117, row: 245, col: 7}, {ofs: 7138, row: 245, col: 28}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 7143, row: 245, col: 33}, {ofs: 7149, row: 245, col: 39}]); tmp739 = 'jump';  _aether.logStatement([{ofs: 7143, row: 245, col: 33}, {ofs: 7149, row: 245, col: 39}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 7117, row: 245, col: 7}, {ofs: 7149, row: 245, col: 39}]); tmp737 = tmp738 === tmp739;  _aether.logStatement([{ofs: 7117, row: 245, col: 7}, {ofs: 7149, row: 245, col: 39}], _aether._userInfo, false);\n            if (tmp737) {\n                tmp744 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n                tmp745 = 'earlyJump';\n                _aether.logStatementStart([{ofs: 7161, row: 246, col: 8}, {ofs: 7183, row: 246, col: 30}]); tmp746 = true;  _aether.logStatement([{ofs: 7161, row: 246, col: 8}, {ofs: 7183, row: 246, col: 30}], _aether._userInfo, false);\n                _aether.logStatementStart([{ofs: 7161, row: 246, col: 8}, {ofs: 7182, row: 246, col: 29}]); tmp744[tmp745] = tmp746;  _aether.logStatement([{ofs: 7161, row: 246, col: 8}, {ofs: 7182, row: 246, col: 29}], _aether._userInfo, false);\n                tmp747 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n                tmp748 = 'baseRace';\n                _aether.logStatementStart([{ofs: 7192, row: 247, col: 8}, {ofs: 7213, row: 247, col: 29}]); tmp749 = true;  _aether.logStatement([{ofs: 7192, row: 247, col: 8}, {ofs: 7213, row: 247, col: 29}], _aether._userInfo, false);\n                _aether.logStatementStart([{ofs: 7192, row: 247, col: 8}, {ofs: 7212, row: 247, col: 28}]); tmp747[tmp748] = tmp749;  _aether.logStatement([{ofs: 7192, row: 247, col: 8}, {ofs: 7212, row: 247, col: 28}], _aether._userInfo, false);\n            } else {\n                ;\n            }\n            _aether.logCallEnd(); return;\n        } else {\n            ;\n        }\n        tmp758 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n        tmp759 = 'midJump';\n        _aether.logStatementStart([{ofs: 7265, row: 253, col: 4}, {ofs: 7277, row: 253, col: 16}]); tmp757 = tmp758[tmp759];  _aether.logStatement([{ofs: 7265, row: 253, col: 4}, {ofs: 7277, row: 253, col: 16}], _aether._userInfo, false);\n        _aether.logStatementStart([{ofs: 7264, row: 253, col: 3}, {ofs: 7277, row: 253, col: 16}]); tmp756 = !tmp757;  _aether.logStatement([{ofs: 7264, row: 253, col: 3}, {ofs: 7277, row: 253, col: 16}], _aether._userInfo, false);\n        if (tmp756) {\n            tmp762 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n            tmp763 = 'getCooldown';\n            _aether.logStatementStart([{ofs: 7298, row: 253, col: 37}, {ofs: 7307, row: 253, col: 46}]); tmp764 = 'terrify';  _aether.logStatement([{ofs: 7298, row: 253, col: 37}, {ofs: 7307, row: 253, col: 46}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 7281, row: 253, col: 20}, {ofs: 7308, row: 253, col: 47}]); tmp760 = _aether.createAPIClone(_aether, tmp762[tmp763](_aether.restoreAPIClone(_aether, tmp764)));  _aether.logStatement([{ofs: 7281, row: 253, col: 20}, {ofs: 7308, row: 253, col: 47}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 7313, row: 253, col: 52}, {ofs: 7314, row: 253, col: 53}]); tmp761 = 0;  _aether.logStatement([{ofs: 7313, row: 253, col: 52}, {ofs: 7314, row: 253, col: 53}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 7281, row: 253, col: 20}, {ofs: 7314, row: 253, col: 53}]); tmp755 = tmp760 === tmp761;  _aether.logStatement([{ofs: 7281, row: 253, col: 20}, {ofs: 7314, row: 253, col: 53}], _aether._userInfo, false);\n        } else {\n            _aether.logStatementStart([{ofs: 7264, row: 253, col: 3}, {ofs: 7314, row: 253, col: 53}]); tmp755 = tmp756;  _aether.logStatement([{ofs: 7264, row: 253, col: 3}, {ofs: 7314, row: 253, col: 53}], _aether._userInfo, false);\n        }\n        if (tmp755) {\n            tmp765 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n            tmp766 = 'enemyHero';\n            _aether.logStatementStart([{ofs: 7318, row: 253, col: 57}, {ofs: 7332, row: 253, col: 71}]); tmp754 = tmp765[tmp766];  _aether.logStatement([{ofs: 7318, row: 253, col: 57}, {ofs: 7332, row: 253, col: 71}], _aether._userInfo, false);\n        } else {\n            _aether.logStatementStart([{ofs: 7264, row: 253, col: 3}, {ofs: 7332, row: 253, col: 71}]); tmp754 = tmp755;  _aether.logStatement([{ofs: 7264, row: 253, col: 3}, {ofs: 7332, row: 253, col: 71}], _aether._userInfo, false);\n        }\n        if (tmp754) {\n            tmp769 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n            tmp770 = 'enemyHero';\n            _aether.logStatementStart([{ofs: 7336, row: 253, col: 75}, {ofs: 7350, row: 253, col: 89}]); tmp767 = tmp769[tmp770];  _aether.logStatement([{ofs: 7336, row: 253, col: 75}, {ofs: 7350, row: 253, col: 89}], _aether._userInfo, false);\n            tmp768 = 'action';\n            _aether.logStatementStart([{ofs: 7336, row: 253, col: 75}, {ofs: 7357, row: 253, col: 96}]); tmp753 = tmp767[tmp768];  _aether.logStatement([{ofs: 7336, row: 253, col: 75}, {ofs: 7357, row: 253, col: 96}], _aether._userInfo, false);\n        } else {\n            _aether.logStatementStart([{ofs: 7264, row: 253, col: 3}, {ofs: 7357, row: 253, col: 96}]); tmp753 = tmp754;  _aether.logStatement([{ofs: 7264, row: 253, col: 3}, {ofs: 7357, row: 253, col: 96}], _aether._userInfo, false);\n        }\n        if (tmp753) {\n            tmp775 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n            tmp776 = 'enemyHero';\n            _aether.logStatementStart([{ofs: 7361, row: 253, col: 100}, {ofs: 7375, row: 253, col: 114}]); tmp773 = tmp775[tmp776];  _aether.logStatement([{ofs: 7361, row: 253, col: 100}, {ofs: 7375, row: 253, col: 114}], _aether._userInfo, false);\n            tmp774 = 'action';\n            _aether.logStatementStart([{ofs: 7361, row: 253, col: 100}, {ofs: 7382, row: 253, col: 121}]); tmp771 = tmp773[tmp774];  _aether.logStatement([{ofs: 7361, row: 253, col: 100}, {ofs: 7382, row: 253, col: 121}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 7387, row: 253, col: 126}, {ofs: 7393, row: 253, col: 132}]); tmp772 = 'jump';  _aether.logStatement([{ofs: 7387, row: 253, col: 126}, {ofs: 7393, row: 253, col: 132}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 7361, row: 253, col: 100}, {ofs: 7393, row: 253, col: 132}]); tmp752 = tmp771 === tmp772;  _aether.logStatement([{ofs: 7361, row: 253, col: 100}, {ofs: 7393, row: 253, col: 132}], _aether._userInfo, false);\n        } else {\n            _aether.logStatementStart([{ofs: 7264, row: 253, col: 3}, {ofs: 7393, row: 253, col: 132}]); tmp752 = tmp753;  _aether.logStatement([{ofs: 7264, row: 253, col: 3}, {ofs: 7393, row: 253, col: 132}], _aether._userInfo, false);\n        }\n        if (tmp752) {\n            tmp779 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n            tmp780 = 'distance';\n            tmp782 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n            tmp783 = 'enemyHero';\n            _aether.logStatementStart([{ofs: 7411, row: 253, col: 150}, {ofs: 7425, row: 253, col: 164}]); tmp781 = tmp782[tmp783];  _aether.logStatement([{ofs: 7411, row: 253, col: 150}, {ofs: 7425, row: 253, col: 164}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 7397, row: 253, col: 136}, {ofs: 7426, row: 253, col: 165}]); tmp777 = _aether.createAPIClone(_aether, tmp779[tmp780](_aether.restoreAPIClone(_aether, tmp781)));  _aether.logStatement([{ofs: 7397, row: 253, col: 136}, {ofs: 7426, row: 253, col: 165}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 7430, row: 253, col: 169}, {ofs: 7432, row: 253, col: 171}]); tmp778 = 30;  _aether.logStatement([{ofs: 7430, row: 253, col: 169}, {ofs: 7432, row: 253, col: 171}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 7397, row: 253, col: 136}, {ofs: 7432, row: 253, col: 171}]); tmp751 = tmp777 >= tmp778;  _aether.logStatement([{ofs: 7397, row: 253, col: 136}, {ofs: 7432, row: 253, col: 171}], _aether._userInfo, false);\n        } else {\n            _aether.logStatementStart([{ofs: 7264, row: 253, col: 3}, {ofs: 7432, row: 253, col: 171}]); tmp751 = tmp752;  _aether.logStatement([{ofs: 7264, row: 253, col: 3}, {ofs: 7432, row: 253, col: 171}], _aether._userInfo, false);\n        }\n        if (tmp751) {\n            tmp786 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n            tmp787 = 'now';\n            _aether.logStatementStart([{ofs: 7436, row: 253, col: 175}, {ofs: 7446, row: 253, col: 185}]); tmp784 = _aether.createAPIClone(_aether, tmp786[tmp787]());  _aether.logStatement([{ofs: 7436, row: 253, col: 175}, {ofs: 7446, row: 253, col: 185}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 7449, row: 253, col: 188}, {ofs: 7450, row: 253, col: 189}]); tmp785 = 2;  _aether.logStatement([{ofs: 7449, row: 253, col: 188}, {ofs: 7450, row: 253, col: 189}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 7436, row: 253, col: 175}, {ofs: 7450, row: 253, col: 189}]); tmp750 = tmp784 > tmp785;  _aether.logStatement([{ofs: 7436, row: 253, col: 175}, {ofs: 7450, row: 253, col: 189}], _aether._userInfo, false);\n        } else {\n            _aether.logStatementStart([{ofs: 7264, row: 253, col: 3}, {ofs: 7450, row: 253, col: 189}]); tmp750 = tmp751;  _aether.logStatement([{ofs: 7264, row: 253, col: 3}, {ofs: 7450, row: 253, col: 189}], _aether._userInfo, false);\n        }\n        if (tmp750) {\n            tmp788 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n            tmp789 = 'midJump';\n            _aether.logStatementStart([{ofs: 7458, row: 254, col: 4}, {ofs: 7478, row: 254, col: 24}]); tmp790 = true;  _aether.logStatement([{ofs: 7458, row: 254, col: 4}, {ofs: 7478, row: 254, col: 24}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 7458, row: 254, col: 4}, {ofs: 7477, row: 254, col: 23}]); tmp788[tmp789] = tmp790;  _aether.logStatement([{ofs: 7458, row: 254, col: 4}, {ofs: 7477, row: 254, col: 23}], _aether._userInfo, false);\n        } else {\n            ;\n        }\n        tmp793 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n        tmp794 = 'baseRace';\n        _aether.logStatementStart([{ofs: 7490, row: 257, col: 4}, {ofs: 7503, row: 257, col: 17}]); tmp792 = tmp793[tmp794];  _aether.logStatement([{ofs: 7490, row: 257, col: 4}, {ofs: 7503, row: 257, col: 17}], _aether._userInfo, false);\n        _aether.logStatementStart([{ofs: 7489, row: 257, col: 3}, {ofs: 7503, row: 257, col: 17}]); tmp791 = !tmp792;  _aether.logStatement([{ofs: 7489, row: 257, col: 3}, {ofs: 7503, row: 257, col: 17}], _aether._userInfo, false);\n        if (tmp791) {\n            tmp795 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n            tmp796 = 'baseRace';\n            tmp798 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n            tmp799 = 'isOpponentBaseRushing';\n            _aether.logStatementStart([{ofs: 7511, row: 258, col: 4}, {ofs: 7556, row: 258, col: 49}]); tmp797 = _aether.createAPIClone(_aether, tmp798[tmp799]());  _aether.logStatement([{ofs: 7511, row: 258, col: 4}, {ofs: 7556, row: 258, col: 49}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 7511, row: 258, col: 4}, {ofs: 7555, row: 258, col: 48}]); tmp795[tmp796] = tmp797;  _aether.logStatement([{ofs: 7511, row: 258, col: 4}, {ofs: 7555, row: 258, col: 48}], _aether._userInfo, false);\n        } else {\n            ;\n        }\n        tmp803 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n        tmp804 = 'startedRushing';\n        _aether.logStatementStart([{ofs: 7564, row: 261, col: 4}, {ofs: 7583, row: 261, col: 23}]); tmp802 = tmp803[tmp804];  _aether.logStatement([{ofs: 7564, row: 261, col: 4}, {ofs: 7583, row: 261, col: 23}], _aether._userInfo, false);\n        _aether.logStatementStart([{ofs: 7563, row: 261, col: 3}, {ofs: 7583, row: 261, col: 23}]); tmp801 = !tmp802;  _aether.logStatement([{ofs: 7563, row: 261, col: 3}, {ofs: 7583, row: 261, col: 23}], _aether._userInfo, false);\n        if (tmp801) {\n            tmp806 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n            tmp807 = 'baseRace';\n            _aether.logStatementStart([{ofs: 7588, row: 261, col: 28}, {ofs: 7601, row: 261, col: 41}]); tmp805 = tmp806[tmp807];  _aether.logStatement([{ofs: 7588, row: 261, col: 28}, {ofs: 7601, row: 261, col: 41}], _aether._userInfo, false);\n            if (tmp805) {\n                _aether.logStatementStart([{ofs: 7588, row: 261, col: 28}, {ofs: 7619, row: 261, col: 59}]); tmp800 = tmp805;  _aether.logStatement([{ofs: 7588, row: 261, col: 28}, {ofs: 7619, row: 261, col: 59}], _aether._userInfo, false);\n            } else {\n                tmp808 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n                tmp809 = 'earlyJump';\n                _aether.logStatementStart([{ofs: 7605, row: 261, col: 45}, {ofs: 7619, row: 261, col: 59}]); tmp800 = tmp808[tmp809];  _aether.logStatement([{ofs: 7605, row: 261, col: 45}, {ofs: 7619, row: 261, col: 59}], _aether._userInfo, false);\n            }\n        } else {\n            _aether.logStatementStart([{ofs: 7563, row: 261, col: 3}, {ofs: 7620, row: 261, col: 60}]); tmp800 = tmp801;  _aether.logStatement([{ofs: 7563, row: 261, col: 3}, {ofs: 7620, row: 261, col: 60}], _aether._userInfo, false);\n        }\n        if (tmp800) {\n            tmp815 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n            tmp816 = 'friends';\n            _aether.logStatementStart([{ofs: 7631, row: 262, col: 7}, {ofs: 7643, row: 262, col: 19}]); tmp813 = tmp815[tmp816];  _aether.logStatement([{ofs: 7631, row: 262, col: 7}, {ofs: 7643, row: 262, col: 19}], _aether._userInfo, false);\n            tmp814 = 'length';\n            _aether.logStatementStart([{ofs: 7631, row: 262, col: 7}, {ofs: 7650, row: 262, col: 26}]); tmp811 = tmp813[tmp814];  _aether.logStatement([{ofs: 7631, row: 262, col: 7}, {ofs: 7650, row: 262, col: 26}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 7654, row: 262, col: 30}, {ofs: 7655, row: 262, col: 31}]); tmp812 = 2;  _aether.logStatement([{ofs: 7654, row: 262, col: 30}, {ofs: 7655, row: 262, col: 31}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 7631, row: 262, col: 7}, {ofs: 7655, row: 262, col: 31}]); tmp810 = tmp811 >= tmp812;  _aether.logStatement([{ofs: 7631, row: 262, col: 7}, {ofs: 7655, row: 262, col: 31}], _aether._userInfo, false);\n            if (tmp810) {\n                tmp820 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n                tmp821 = 'getCooldown';\n                _aether.logStatementStart([{ofs: 7724, row: 263, col: 28}, {ofs: 7732, row: 263, col: 36}]); tmp822 = 'warcry';  _aether.logStatement([{ofs: 7724, row: 263, col: 28}, {ofs: 7732, row: 263, col: 36}], _aether._userInfo, false);\n                _aether.logStatementStart([{ofs: 7707, row: 263, col: 11}, {ofs: 7733, row: 263, col: 37}]); tmp818 = _aether.createAPIClone(_aether, tmp820[tmp821](_aether.restoreAPIClone(_aether, tmp822)));  _aether.logStatement([{ofs: 7707, row: 263, col: 11}, {ofs: 7733, row: 263, col: 37}], _aether._userInfo, false);\n                _aether.logStatementStart([{ofs: 7738, row: 263, col: 42}, {ofs: 7739, row: 263, col: 43}]); tmp819 = 0;  _aether.logStatement([{ofs: 7738, row: 263, col: 42}, {ofs: 7739, row: 263, col: 43}], _aether._userInfo, false);\n                _aether.logStatementStart([{ofs: 7707, row: 263, col: 11}, {ofs: 7739, row: 263, col: 43}]); tmp817 = tmp818 === tmp819;  _aether.logStatement([{ofs: 7707, row: 263, col: 11}, {ofs: 7739, row: 263, col: 43}], _aether._userInfo, false);\n                if (tmp817) {\n                    tmp823 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n                    tmp824 = 'determineSayAndAction';\n                    _aether.logStatementStart([{ofs: 7755, row: 264, col: 12}, {ofs: 7783, row: 264, col: 40}]); tmp825 = _aether.createAPIClone(_aether, tmp823[tmp824]());  _aether.logStatement([{ofs: 7755, row: 264, col: 12}, {ofs: 7783, row: 264, col: 40}], _aether._userInfo, false);\n                    tmp826 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n                    tmp827 = 'warcry';\n                    _aether.logStatementStart([{ofs: 7797, row: 265, col: 12}, {ofs: 7810, row: 265, col: 25}]); tmp828 = _aether.createAPIClone(_aether, tmp826[tmp827]());  _aether.logStatement([{ofs: 7797, row: 265, col: 12}, {ofs: 7810, row: 265, col: 25}], _aether._userInfo, false);\n                    tmp829 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n                    tmp830 = 'startedRushing';\n                    _aether.logStatementStart([{ofs: 7824, row: 266, col: 12}, {ofs: 7851, row: 266, col: 39}]); tmp831 = true;  _aether.logStatement([{ofs: 7824, row: 266, col: 12}, {ofs: 7851, row: 266, col: 39}], _aether._userInfo, false);\n                    _aether.logStatementStart([{ofs: 7824, row: 266, col: 12}, {ofs: 7850, row: 266, col: 38}]); tmp829[tmp830] = tmp831;  _aether.logStatement([{ofs: 7824, row: 266, col: 12}, {ofs: 7850, row: 266, col: 38}], _aether._userInfo, false);\n                    _aether.logCallEnd(); return;\n                } else {\n                    ;\n                }\n            } else {\n                tmp832 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n                tmp833 = 'say';\n                _aether.logStatementStart([{ofs: 7955, row: 271, col: 17}, {ofs: 7966, row: 271, col: 28}]); tmp834 = 'follow me';  _aether.logStatement([{ofs: 7955, row: 271, col: 17}, {ofs: 7966, row: 271, col: 28}], _aether._userInfo, false);\n                _aether.logStatementStart([{ofs: 7946, row: 271, col: 8}, {ofs: 7967, row: 271, col: 29}]); tmp835 = _aether.createAPIClone(_aether, tmp832[tmp833](_aether.restoreAPIClone(_aether, tmp834)));  _aether.logStatement([{ofs: 7946, row: 271, col: 8}, {ofs: 7967, row: 271, col: 29}], _aether._userInfo, false);\n                tmp836 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n                tmp837 = 'shield';\n                _aether.logStatementStart([{ofs: 7977, row: 272, col: 8}, {ofs: 7990, row: 272, col: 21}]); tmp838 = _aether.createAPIClone(_aether, tmp836[tmp837]());  _aether.logStatement([{ofs: 7977, row: 272, col: 8}, {ofs: 7990, row: 272, col: 21}], _aether._userInfo, false);\n                _aether.logCallEnd(); return;\n            }\n        } else {\n            tmp841 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n            tmp842 = 'startedRushing';\n            _aether.logStatementStart([{ofs: 8025, row: 276, col: 9}, {ofs: 8044, row: 276, col: 28}]); tmp840 = tmp841[tmp842];  _aether.logStatement([{ofs: 8025, row: 276, col: 9}, {ofs: 8044, row: 276, col: 28}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 8024, row: 276, col: 8}, {ofs: 8044, row: 276, col: 28}]); tmp839 = !tmp840;  _aether.logStatement([{ofs: 8024, row: 276, col: 8}, {ofs: 8044, row: 276, col: 28}], _aether._userInfo, false);\n            if (tmp839) {\n                tmp848 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n                tmp849 = 'friends';\n                _aether.logStatementStart([{ofs: 8055, row: 277, col: 7}, {ofs: 8067, row: 277, col: 19}]); tmp846 = tmp848[tmp849];  _aether.logStatement([{ofs: 8055, row: 277, col: 7}, {ofs: 8067, row: 277, col: 19}], _aether._userInfo, false);\n                tmp847 = 'length';\n                _aether.logStatementStart([{ofs: 8055, row: 277, col: 7}, {ofs: 8074, row: 277, col: 26}]); tmp844 = tmp846[tmp847];  _aether.logStatement([{ofs: 8055, row: 277, col: 7}, {ofs: 8074, row: 277, col: 26}], _aether._userInfo, false);\n                _aether.logStatementStart([{ofs: 8078, row: 277, col: 30}, {ofs: 8079, row: 277, col: 31}]); tmp845 = 3;  _aether.logStatement([{ofs: 8078, row: 277, col: 30}, {ofs: 8079, row: 277, col: 31}], _aether._userInfo, false);\n                _aether.logStatementStart([{ofs: 8055, row: 277, col: 7}, {ofs: 8079, row: 277, col: 31}]); tmp843 = tmp844 >= tmp845;  _aether.logStatement([{ofs: 8055, row: 277, col: 7}, {ofs: 8079, row: 277, col: 31}], _aether._userInfo, false);\n                if (tmp843) {\n                    tmp853 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n                    tmp854 = 'getCooldown';\n                    _aether.logStatementStart([{ofs: 8147, row: 278, col: 28}, {ofs: 8155, row: 278, col: 36}]); tmp855 = 'warcry';  _aether.logStatement([{ofs: 8147, row: 278, col: 28}, {ofs: 8155, row: 278, col: 36}], _aether._userInfo, false);\n                    _aether.logStatementStart([{ofs: 8130, row: 278, col: 11}, {ofs: 8156, row: 278, col: 37}]); tmp851 = _aether.createAPIClone(_aether, tmp853[tmp854](_aether.restoreAPIClone(_aether, tmp855)));  _aether.logStatement([{ofs: 8130, row: 278, col: 11}, {ofs: 8156, row: 278, col: 37}], _aether._userInfo, false);\n                    _aether.logStatementStart([{ofs: 8161, row: 278, col: 42}, {ofs: 8162, row: 278, col: 43}]); tmp852 = 0;  _aether.logStatement([{ofs: 8161, row: 278, col: 42}, {ofs: 8162, row: 278, col: 43}], _aether._userInfo, false);\n                    _aether.logStatementStart([{ofs: 8130, row: 278, col: 11}, {ofs: 8162, row: 278, col: 43}]); tmp850 = tmp851 === tmp852;  _aether.logStatement([{ofs: 8130, row: 278, col: 11}, {ofs: 8162, row: 278, col: 43}], _aether._userInfo, false);\n                    if (tmp850) {\n                        tmp856 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n                        tmp857 = 'determineSayAndAction';\n                        _aether.logStatementStart([{ofs: 8178, row: 279, col: 12}, {ofs: 8206, row: 279, col: 40}]); tmp858 = _aether.createAPIClone(_aether, tmp856[tmp857]());  _aether.logStatement([{ofs: 8178, row: 279, col: 12}, {ofs: 8206, row: 279, col: 40}], _aether._userInfo, false);\n                        tmp859 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n                        tmp860 = 'warcry';\n                        _aether.logStatementStart([{ofs: 8220, row: 280, col: 12}, {ofs: 8233, row: 280, col: 25}]); tmp861 = _aether.createAPIClone(_aether, tmp859[tmp860]());  _aether.logStatement([{ofs: 8220, row: 280, col: 12}, {ofs: 8233, row: 280, col: 25}], _aether._userInfo, false);\n                        tmp862 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n                        tmp863 = 'startedRushing';\n                        _aether.logStatementStart([{ofs: 8247, row: 281, col: 12}, {ofs: 8274, row: 281, col: 39}]); tmp864 = true;  _aether.logStatement([{ofs: 8247, row: 281, col: 12}, {ofs: 8274, row: 281, col: 39}], _aether._userInfo, false);\n                        _aether.logStatementStart([{ofs: 8247, row: 281, col: 12}, {ofs: 8273, row: 281, col: 38}]); tmp862[tmp863] = tmp864;  _aether.logStatement([{ofs: 8247, row: 281, col: 12}, {ofs: 8273, row: 281, col: 38}], _aether._userInfo, false);\n                        _aether.logCallEnd(); return;\n                    } else {\n                        ;\n                    }\n                } else {\n                    tmp865 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n                    tmp866 = 'say';\n                    _aether.logStatementStart([{ofs: 8379, row: 286, col: 17}, {ofs: 8390, row: 286, col: 28}]); tmp867 = 'follow me';  _aether.logStatement([{ofs: 8379, row: 286, col: 17}, {ofs: 8390, row: 286, col: 28}], _aether._userInfo, false);\n                    _aether.logStatementStart([{ofs: 8370, row: 286, col: 8}, {ofs: 8391, row: 286, col: 29}]); tmp868 = _aether.createAPIClone(_aether, tmp865[tmp866](_aether.restoreAPIClone(_aether, tmp867)));  _aether.logStatement([{ofs: 8370, row: 286, col: 8}, {ofs: 8391, row: 286, col: 29}], _aether._userInfo, false);\n                    tmp869 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n                    tmp870 = 'shield';\n                    _aether.logStatementStart([{ofs: 8401, row: 287, col: 8}, {ofs: 8414, row: 287, col: 21}]); tmp871 = _aether.createAPIClone(_aether, tmp869[tmp870]());  _aether.logStatement([{ofs: 8401, row: 287, col: 8}, {ofs: 8414, row: 287, col: 21}], _aether._userInfo, false);\n                    _aether.logCallEnd(); return;\n                }\n            } else {\n                ;\n            }\n        }\n        tmp875 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n        tmp876 = 'getCooldown';\n        _aether.logStatementStart([{ofs: 8461, row: 292, col: 20}, {ofs: 8470, row: 292, col: 29}]); tmp877 = 'terrify';  _aether.logStatement([{ofs: 8461, row: 292, col: 20}, {ofs: 8470, row: 292, col: 29}], _aether._userInfo, false);\n        _aether.logStatementStart([{ofs: 8444, row: 292, col: 3}, {ofs: 8471, row: 292, col: 30}]); tmp873 = _aether.createAPIClone(_aether, tmp875[tmp876](_aether.restoreAPIClone(_aether, tmp877)));  _aether.logStatement([{ofs: 8444, row: 292, col: 3}, {ofs: 8471, row: 292, col: 30}], _aether._userInfo, false);\n        _aether.logStatementStart([{ofs: 8476, row: 292, col: 35}, {ofs: 8477, row: 292, col: 36}]); tmp874 = 0;  _aether.logStatement([{ofs: 8476, row: 292, col: 35}, {ofs: 8477, row: 292, col: 36}], _aether._userInfo, false);\n        _aether.logStatementStart([{ofs: 8444, row: 292, col: 3}, {ofs: 8477, row: 292, col: 36}]); tmp872 = tmp873 === tmp874;  _aether.logStatement([{ofs: 8444, row: 292, col: 3}, {ofs: 8477, row: 292, col: 36}], _aether._userInfo, false);\n        if (tmp872) {\n            tmp886 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n            tmp887 = 'earlyJump';\n            _aether.logStatementStart([{ofs: 8494, row: 294, col: 8}, {ofs: 8508, row: 294, col: 22}]); tmp885 = tmp886[tmp887];  _aether.logStatement([{ofs: 8494, row: 294, col: 8}, {ofs: 8508, row: 294, col: 22}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 8493, row: 294, col: 7}, {ofs: 8508, row: 294, col: 22}]); tmp884 = !tmp885;  _aether.logStatement([{ofs: 8493, row: 294, col: 7}, {ofs: 8508, row: 294, col: 22}], _aether._userInfo, false);\n            if (tmp884) {\n                tmp889 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n                tmp890 = 'lateJump';\n                _aether.logStatementStart([{ofs: 8513, row: 294, col: 27}, {ofs: 8526, row: 294, col: 40}]); tmp888 = tmp889[tmp890];  _aether.logStatement([{ofs: 8513, row: 294, col: 27}, {ofs: 8526, row: 294, col: 40}], _aether._userInfo, false);\n                _aether.logStatementStart([{ofs: 8512, row: 294, col: 26}, {ofs: 8526, row: 294, col: 40}]); tmp883 = !tmp888;  _aether.logStatement([{ofs: 8512, row: 294, col: 26}, {ofs: 8526, row: 294, col: 40}], _aether._userInfo, false);\n            } else {\n                _aether.logStatementStart([{ofs: 8493, row: 294, col: 7}, {ofs: 8526, row: 294, col: 40}]); tmp883 = tmp884;  _aether.logStatement([{ofs: 8493, row: 294, col: 7}, {ofs: 8526, row: 294, col: 40}], _aether._userInfo, false);\n            }\n            if (tmp883) {\n                tmp891 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n                tmp892 = 'enemyHero';\n                _aether.logStatementStart([{ofs: 8530, row: 294, col: 44}, {ofs: 8544, row: 294, col: 58}]); tmp882 = tmp891[tmp892];  _aether.logStatement([{ofs: 8530, row: 294, col: 44}, {ofs: 8544, row: 294, col: 58}], _aether._userInfo, false);\n            } else {\n                _aether.logStatementStart([{ofs: 8493, row: 294, col: 7}, {ofs: 8544, row: 294, col: 58}]); tmp882 = tmp883;  _aether.logStatement([{ofs: 8493, row: 294, col: 7}, {ofs: 8544, row: 294, col: 58}], _aether._userInfo, false);\n            }\n            if (tmp882) {\n                tmp895 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n                tmp896 = 'enemyHero';\n                _aether.logStatementStart([{ofs: 8548, row: 294, col: 62}, {ofs: 8562, row: 294, col: 76}]); tmp893 = tmp895[tmp896];  _aether.logStatement([{ofs: 8548, row: 294, col: 62}, {ofs: 8562, row: 294, col: 76}], _aether._userInfo, false);\n                tmp894 = 'action';\n                _aether.logStatementStart([{ofs: 8548, row: 294, col: 62}, {ofs: 8569, row: 294, col: 83}]); tmp881 = tmp893[tmp894];  _aether.logStatement([{ofs: 8548, row: 294, col: 62}, {ofs: 8569, row: 294, col: 83}], _aether._userInfo, false);\n            } else {\n                _aether.logStatementStart([{ofs: 8493, row: 294, col: 7}, {ofs: 8569, row: 294, col: 83}]); tmp881 = tmp882;  _aether.logStatement([{ofs: 8493, row: 294, col: 7}, {ofs: 8569, row: 294, col: 83}], _aether._userInfo, false);\n            }\n            if (tmp881) {\n                tmp901 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n                tmp902 = 'enemyHero';\n                _aether.logStatementStart([{ofs: 8573, row: 294, col: 87}, {ofs: 8587, row: 294, col: 101}]); tmp899 = tmp901[tmp902];  _aether.logStatement([{ofs: 8573, row: 294, col: 87}, {ofs: 8587, row: 294, col: 101}], _aether._userInfo, false);\n                tmp900 = 'action';\n                _aether.logStatementStart([{ofs: 8573, row: 294, col: 87}, {ofs: 8594, row: 294, col: 108}]); tmp897 = tmp899[tmp900];  _aether.logStatement([{ofs: 8573, row: 294, col: 87}, {ofs: 8594, row: 294, col: 108}], _aether._userInfo, false);\n                _aether.logStatementStart([{ofs: 8599, row: 294, col: 113}, {ofs: 8605, row: 294, col: 119}]); tmp898 = 'jump';  _aether.logStatement([{ofs: 8599, row: 294, col: 113}, {ofs: 8605, row: 294, col: 119}], _aether._userInfo, false);\n                _aether.logStatementStart([{ofs: 8573, row: 294, col: 87}, {ofs: 8605, row: 294, col: 119}]); tmp880 = tmp897 === tmp898;  _aether.logStatement([{ofs: 8573, row: 294, col: 87}, {ofs: 8605, row: 294, col: 119}], _aether._userInfo, false);\n            } else {\n                _aether.logStatementStart([{ofs: 8493, row: 294, col: 7}, {ofs: 8605, row: 294, col: 119}]); tmp880 = tmp881;  _aether.logStatement([{ofs: 8493, row: 294, col: 7}, {ofs: 8605, row: 294, col: 119}], _aether._userInfo, false);\n            }\n            if (tmp880) {\n                tmp905 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n                tmp906 = 'distance';\n                tmp908 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n                tmp909 = 'enemyHero';\n                _aether.logStatementStart([{ofs: 8623, row: 294, col: 137}, {ofs: 8637, row: 294, col: 151}]); tmp907 = tmp908[tmp909];  _aether.logStatement([{ofs: 8623, row: 294, col: 137}, {ofs: 8637, row: 294, col: 151}], _aether._userInfo, false);\n                _aether.logStatementStart([{ofs: 8609, row: 294, col: 123}, {ofs: 8638, row: 294, col: 152}]); tmp903 = _aether.createAPIClone(_aether, tmp905[tmp906](_aether.restoreAPIClone(_aether, tmp907)));  _aether.logStatement([{ofs: 8609, row: 294, col: 123}, {ofs: 8638, row: 294, col: 152}], _aether._userInfo, false);\n                _aether.logStatementStart([{ofs: 8642, row: 294, col: 156}, {ofs: 8644, row: 294, col: 158}]); tmp904 = 20;  _aether.logStatement([{ofs: 8642, row: 294, col: 156}, {ofs: 8644, row: 294, col: 158}], _aether._userInfo, false);\n                _aether.logStatementStart([{ofs: 8609, row: 294, col: 123}, {ofs: 8644, row: 294, col: 158}]); tmp879 = tmp903 <= tmp904;  _aether.logStatement([{ofs: 8609, row: 294, col: 123}, {ofs: 8644, row: 294, col: 158}], _aether._userInfo, false);\n            } else {\n                _aether.logStatementStart([{ofs: 8493, row: 294, col: 7}, {ofs: 8644, row: 294, col: 158}]); tmp879 = tmp880;  _aether.logStatement([{ofs: 8493, row: 294, col: 7}, {ofs: 8644, row: 294, col: 158}], _aether._userInfo, false);\n            }\n            if (tmp879) {\n                tmp912 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n                tmp913 = 'now';\n                _aether.logStatementStart([{ofs: 8648, row: 294, col: 162}, {ofs: 8658, row: 294, col: 172}]); tmp910 = _aether.createAPIClone(_aether, tmp912[tmp913]());  _aether.logStatement([{ofs: 8648, row: 294, col: 162}, {ofs: 8658, row: 294, col: 172}], _aether._userInfo, false);\n                _aether.logStatementStart([{ofs: 8661, row: 294, col: 175}, {ofs: 8662, row: 294, col: 176}]); tmp911 = 1;  _aether.logStatement([{ofs: 8661, row: 294, col: 175}, {ofs: 8662, row: 294, col: 176}], _aether._userInfo, false);\n                _aether.logStatementStart([{ofs: 8648, row: 294, col: 162}, {ofs: 8662, row: 294, col: 176}]); tmp878 = tmp910 > tmp911;  _aether.logStatement([{ofs: 8648, row: 294, col: 162}, {ofs: 8662, row: 294, col: 176}], _aether._userInfo, false);\n            } else {\n                _aether.logStatementStart([{ofs: 8493, row: 294, col: 7}, {ofs: 8662, row: 294, col: 176}]); tmp878 = tmp879;  _aether.logStatement([{ofs: 8493, row: 294, col: 7}, {ofs: 8662, row: 294, col: 176}], _aether._userInfo, false);\n            }\n            if (tmp878) {\n                tmp914 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n                tmp915 = 'lateJump';\n                _aether.logStatementStart([{ofs: 8674, row: 295, col: 8}, {ofs: 8695, row: 295, col: 29}]); tmp916 = true;  _aether.logStatement([{ofs: 8674, row: 295, col: 8}, {ofs: 8695, row: 295, col: 29}], _aether._userInfo, false);\n                _aether.logStatementStart([{ofs: 8674, row: 295, col: 8}, {ofs: 8694, row: 295, col: 28}]); tmp914[tmp915] = tmp916;  _aether.logStatement([{ofs: 8674, row: 295, col: 8}, {ofs: 8694, row: 295, col: 28}], _aether._userInfo, false);\n                tmp917 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n                tmp918 = 'move';\n                tmp924 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n                tmp925 = 'pos';\n                _aether.logStatementStart([{ofs: 8717, row: 296, col: 21}, {ofs: 8725, row: 296, col: 29}]); tmp922 = tmp924[tmp925];  _aether.logStatement([{ofs: 8717, row: 296, col: 21}, {ofs: 8725, row: 296, col: 29}], _aether._userInfo, false);\n                tmp923 = 'x';\n                _aether.logStatementStart([{ofs: 8717, row: 296, col: 21}, {ofs: 8727, row: 296, col: 31}]); tmp920 = tmp922[tmp923];  _aether.logStatement([{ofs: 8717, row: 296, col: 21}, {ofs: 8727, row: 296, col: 31}], _aether._userInfo, false);\n                tmp930 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n                tmp931 = 'pos';\n                _aether.logStatementStart([{ofs: 8731, row: 296, col: 35}, {ofs: 8739, row: 296, col: 43}]); tmp928 = tmp930[tmp931];  _aether.logStatement([{ofs: 8731, row: 296, col: 35}, {ofs: 8739, row: 296, col: 43}], _aether._userInfo, false);\n                tmp929 = 'y';\n                _aether.logStatementStart([{ofs: 8731, row: 296, col: 35}, {ofs: 8741, row: 296, col: 45}]); tmp926 = tmp928[tmp929];  _aether.logStatement([{ofs: 8731, row: 296, col: 35}, {ofs: 8741, row: 296, col: 45}], _aether._userInfo, false);\n                _aether.logStatementStart([{ofs: 8742, row: 296, col: 46}, {ofs: 8743, row: 296, col: 47}]); tmp927 = 1;  _aether.logStatement([{ofs: 8742, row: 296, col: 46}, {ofs: 8743, row: 296, col: 47}], _aether._userInfo, false);\n                _aether.logStatementStart([{ofs: 8731, row: 296, col: 35}, {ofs: 8743, row: 296, col: 47}]); tmp921 = tmp926 - tmp927;  _aether.logStatement([{ofs: 8731, row: 296, col: 35}, {ofs: 8743, row: 296, col: 47}], _aether._userInfo, false);\n                _aether.logStatementStart([{ofs: 8714, row: 296, col: 18}, {ofs: 8744, row: 296, col: 48}]); tmp919 = {\n                    x: tmp920,\n                    y: tmp921\n                };  _aether.logStatement([{ofs: 8714, row: 296, col: 18}, {ofs: 8744, row: 296, col: 48}], _aether._userInfo, false);\n                _aether.logStatementStart([{ofs: 8704, row: 296, col: 8}, {ofs: 8745, row: 296, col: 49}]); tmp932 = _aether.createAPIClone(_aether, tmp917[tmp918](_aether.restoreAPIClone(_aether, tmp919)));  _aether.logStatement([{ofs: 8704, row: 296, col: 8}, {ofs: 8745, row: 296, col: 49}], _aether._userInfo, false);\n                _aether.logCallEnd(); return;\n            } else {\n                tmp934 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n                tmp935 = 'lateJump';\n                _aether.logStatementStart([{ofs: 8781, row: 299, col: 12}, {ofs: 8794, row: 299, col: 25}]); tmp933 = tmp934[tmp935];  _aether.logStatement([{ofs: 8781, row: 299, col: 12}, {ofs: 8794, row: 299, col: 25}], _aether._userInfo, false);\n                if (tmp933) {\n                    tmp939 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n                    tmp940 = 'enemyHero';\n                    _aether.logStatementStart([{ofs: 8809, row: 300, col: 11}, {ofs: 8823, row: 300, col: 25}]); tmp938 = tmp939[tmp940];  _aether.logStatement([{ofs: 8809, row: 300, col: 11}, {ofs: 8823, row: 300, col: 25}], _aether._userInfo, false);\n                    if (tmp938) {\n                        tmp943 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n                        tmp944 = 'distance';\n                        tmp946 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n                        tmp947 = 'enemyHero';\n                        _aether.logStatementStart([{ofs: 8841, row: 300, col: 43}, {ofs: 8855, row: 300, col: 57}]); tmp945 = tmp946[tmp947];  _aether.logStatement([{ofs: 8841, row: 300, col: 43}, {ofs: 8855, row: 300, col: 57}], _aether._userInfo, false);\n                        _aether.logStatementStart([{ofs: 8827, row: 300, col: 29}, {ofs: 8856, row: 300, col: 58}]); tmp941 = _aether.createAPIClone(_aether, tmp943[tmp944](_aether.restoreAPIClone(_aether, tmp945)));  _aether.logStatement([{ofs: 8827, row: 300, col: 29}, {ofs: 8856, row: 300, col: 58}], _aether._userInfo, false);\n                        _aether.logStatementStart([{ofs: 8860, row: 300, col: 62}, {ofs: 8862, row: 300, col: 64}]); tmp942 = 10;  _aether.logStatement([{ofs: 8860, row: 300, col: 62}, {ofs: 8862, row: 300, col: 64}], _aether._userInfo, false);\n                        _aether.logStatementStart([{ofs: 8827, row: 300, col: 29}, {ofs: 8862, row: 300, col: 64}]); tmp937 = tmp941 >= tmp942;  _aether.logStatement([{ofs: 8827, row: 300, col: 29}, {ofs: 8862, row: 300, col: 64}], _aether._userInfo, false);\n                    } else {\n                        _aether.logStatementStart([{ofs: 8809, row: 300, col: 11}, {ofs: 8862, row: 300, col: 64}]); tmp937 = tmp938;  _aether.logStatement([{ofs: 8809, row: 300, col: 11}, {ofs: 8862, row: 300, col: 64}], _aether._userInfo, false);\n                    }\n                    if (tmp937) {\n                        tmp952 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n                        tmp953 = 'pos';\n                        _aether.logStatementStart([{ofs: 8866, row: 300, col: 68}, {ofs: 8874, row: 300, col: 76}]); tmp950 = tmp952[tmp953];  _aether.logStatement([{ofs: 8866, row: 300, col: 68}, {ofs: 8874, row: 300, col: 76}], _aether._userInfo, false);\n                        tmp951 = 'x';\n                        _aether.logStatementStart([{ofs: 8866, row: 300, col: 68}, {ofs: 8876, row: 300, col: 78}]); tmp948 = tmp950[tmp951];  _aether.logStatement([{ofs: 8866, row: 300, col: 68}, {ofs: 8876, row: 300, col: 78}], _aether._userInfo, false);\n                        tmp958 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n                        tmp959 = 'enemyHero';\n                        _aether.logStatementStart([{ofs: 8879, row: 300, col: 81}, {ofs: 8893, row: 300, col: 95}]); tmp956 = tmp958[tmp959];  _aether.logStatement([{ofs: 8879, row: 300, col: 81}, {ofs: 8893, row: 300, col: 95}], _aether._userInfo, false);\n                        tmp957 = 'pos';\n                        _aether.logStatementStart([{ofs: 8879, row: 300, col: 81}, {ofs: 8897, row: 300, col: 99}]); tmp954 = tmp956[tmp957];  _aether.logStatement([{ofs: 8879, row: 300, col: 81}, {ofs: 8897, row: 300, col: 99}], _aether._userInfo, false);\n                        tmp955 = 'x';\n                        _aether.logStatementStart([{ofs: 8879, row: 300, col: 81}, {ofs: 8899, row: 300, col: 101}]); tmp949 = tmp954[tmp955];  _aether.logStatement([{ofs: 8879, row: 300, col: 81}, {ofs: 8899, row: 300, col: 101}], _aether._userInfo, false);\n                        _aether.logStatementStart([{ofs: 8866, row: 300, col: 68}, {ofs: 8899, row: 300, col: 101}]); tmp936 = tmp948 > tmp949;  _aether.logStatement([{ofs: 8866, row: 300, col: 68}, {ofs: 8899, row: 300, col: 101}], _aether._userInfo, false);\n                    } else {\n                        _aether.logStatementStart([{ofs: 8809, row: 300, col: 11}, {ofs: 8899, row: 300, col: 101}]); tmp936 = tmp937;  _aether.logStatement([{ofs: 8809, row: 300, col: 11}, {ofs: 8899, row: 300, col: 101}], _aether._userInfo, false);\n                    }\n                    if (tmp936) {\n                        tmp960 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n                        tmp961 = 'terrifyTargets';\n                        tmp963 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n                        tmp964 = 'getTerrifyTargets';\n                        _aether.logStatementStart([{ofs: 8915, row: 301, col: 12}, {ofs: 8962, row: 301, col: 59}]); tmp962 = _aether.createAPIClone(_aether, tmp963[tmp964]());  _aether.logStatement([{ofs: 8915, row: 301, col: 12}, {ofs: 8962, row: 301, col: 59}], _aether._userInfo, false);\n                        _aether.logStatementStart([{ofs: 8915, row: 301, col: 12}, {ofs: 8961, row: 301, col: 58}]); tmp960[tmp961] = tmp962;  _aether.logStatement([{ofs: 8915, row: 301, col: 12}, {ofs: 8961, row: 301, col: 58}], _aether._userInfo, false);\n                        tmp965 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n                        tmp966 = 'terrify';\n                        _aether.logStatementStart([{ofs: 8975, row: 302, col: 12}, {ofs: 8989, row: 302, col: 26}]); tmp967 = _aether.createAPIClone(_aether, tmp965[tmp966]());  _aether.logStatement([{ofs: 8975, row: 302, col: 12}, {ofs: 8989, row: 302, col: 26}], _aether._userInfo, false);\n                        _aether.logCallEnd(); return;\n                    } else {\n                        ;\n                    }\n                } else {\n                    ;\n                }\n            }\n            tmp972 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n            tmp973 = 'health';\n            _aether.logStatementStart([{ofs: 9284, row: 312, col: 7}, {ofs: 9295, row: 312, col: 18}]); tmp970 = tmp972[tmp973];  _aether.logStatement([{ofs: 9284, row: 312, col: 7}, {ofs: 9295, row: 312, col: 18}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 9299, row: 312, col: 22}, {ofs: 9302, row: 312, col: 25}]); tmp971 = 100;  _aether.logStatement([{ofs: 9299, row: 312, col: 22}, {ofs: 9302, row: 312, col: 25}], _aether._userInfo, false);\n            _aether.logStatementStart([{ofs: 9284, row: 312, col: 7}, {ofs: 9302, row: 312, col: 25}]); tmp969 = tmp970 <= tmp971;  _aether.logStatement([{ofs: 9284, row: 312, col: 7}, {ofs: 9302, row: 312, col: 25}], _aether._userInfo, false);\n            if (tmp969) {\n                _aether.logStatementStart([{ofs: 9284, row: 312, col: 7}, {ofs: 9342, row: 312, col: 65}]); tmp968 = tmp969;  _aether.logStatement([{ofs: 9284, row: 312, col: 7}, {ofs: 9342, row: 312, col: 65}], _aether._userInfo, false);\n            } else {\n                tmp977 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n                tmp978 = 'now';\n                _aether.logStatementStart([{ofs: 9307, row: 312, col: 30}, {ofs: 9317, row: 312, col: 40}]); tmp975 = _aether.createAPIClone(_aether, tmp977[tmp978]());  _aether.logStatement([{ofs: 9307, row: 312, col: 30}, {ofs: 9317, row: 312, col: 40}], _aether._userInfo, false);\n                _aether.logStatementStart([{ofs: 9320, row: 312, col: 43}, {ofs: 9322, row: 312, col: 45}]); tmp976 = 10;  _aether.logStatement([{ofs: 9320, row: 312, col: 43}, {ofs: 9322, row: 312, col: 45}], _aether._userInfo, false);\n                _aether.logStatementStart([{ofs: 9307, row: 312, col: 30}, {ofs: 9322, row: 312, col: 45}]); tmp974 = tmp975 > tmp976;  _aether.logStatement([{ofs: 9307, row: 312, col: 30}, {ofs: 9322, row: 312, col: 45}], _aether._userInfo, false);\n                if (tmp974) {\n                    tmp983 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n                    tmp984 = 'pos';\n                    _aether.logStatementStart([{ofs: 9326, row: 312, col: 49}, {ofs: 9334, row: 312, col: 57}]); tmp981 = tmp983[tmp984];  _aether.logStatement([{ofs: 9326, row: 312, col: 49}, {ofs: 9334, row: 312, col: 57}], _aether._userInfo, false);\n                    tmp982 = 'x';\n                    _aether.logStatementStart([{ofs: 9326, row: 312, col: 49}, {ofs: 9336, row: 312, col: 59}]); tmp979 = tmp981[tmp982];  _aether.logStatement([{ofs: 9326, row: 312, col: 49}, {ofs: 9336, row: 312, col: 59}], _aether._userInfo, false);\n                    _aether.logStatementStart([{ofs: 9339, row: 312, col: 62}, {ofs: 9341, row: 312, col: 64}]); tmp980 = 65;  _aether.logStatement([{ofs: 9339, row: 312, col: 62}, {ofs: 9341, row: 312, col: 64}], _aether._userInfo, false);\n                    _aether.logStatementStart([{ofs: 9326, row: 312, col: 49}, {ofs: 9341, row: 312, col: 64}]); tmp968 = tmp979 > tmp980;  _aether.logStatement([{ofs: 9326, row: 312, col: 49}, {ofs: 9341, row: 312, col: 64}], _aether._userInfo, false);\n                } else {\n                    _aether.logStatementStart([{ofs: 9307, row: 312, col: 30}, {ofs: 9341, row: 312, col: 64}]); tmp968 = tmp974;  _aether.logStatement([{ofs: 9307, row: 312, col: 30}, {ofs: 9341, row: 312, col: 64}], _aether._userInfo, false);\n                }\n            }\n            if (tmp968) {\n                tmp985 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n                tmp986 = 'determineSayAndAction';\n                _aether.logStatementStart([{ofs: 9354, row: 313, col: 8}, {ofs: 9382, row: 313, col: 36}]); tmp987 = _aether.createAPIClone(_aether, tmp985[tmp986]());  _aether.logStatement([{ofs: 9354, row: 313, col: 8}, {ofs: 9382, row: 313, col: 36}], _aether._userInfo, false);\n                tmp988 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n                tmp989 = 'terrifyTargets';\n                tmp991 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n                tmp992 = 'getTerrifyTargets';\n                _aether.logStatementStart([{ofs: 9392, row: 314, col: 8}, {ofs: 9439, row: 314, col: 55}]); tmp990 = _aether.createAPIClone(_aether, tmp991[tmp992]());  _aether.logStatement([{ofs: 9392, row: 314, col: 8}, {ofs: 9439, row: 314, col: 55}], _aether._userInfo, false);\n                _aether.logStatementStart([{ofs: 9392, row: 314, col: 8}, {ofs: 9438, row: 314, col: 54}]); tmp988[tmp989] = tmp990;  _aether.logStatement([{ofs: 9392, row: 314, col: 8}, {ofs: 9438, row: 314, col: 54}], _aether._userInfo, false);\n                tmp993 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n                tmp994 = 'terrify';\n                _aether.logStatementStart([{ofs: 9448, row: 315, col: 8}, {ofs: 9462, row: 315, col: 22}]); tmp995 = _aether.createAPIClone(_aether, tmp993[tmp994]());  _aether.logStatement([{ofs: 9448, row: 315, col: 8}, {ofs: 9462, row: 315, col: 22}], _aether._userInfo, false);\n                _aether.logCallEnd(); return;\n            } else {\n                tmp997 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n                tmp998 = 'earlyJump';\n                _aether.logStatementStart([{ofs: 9498, row: 318, col: 12}, {ofs: 9512, row: 318, col: 26}]); tmp996 = tmp997[tmp998];  _aether.logStatement([{ofs: 9498, row: 318, col: 12}, {ofs: 9512, row: 318, col: 26}], _aether._userInfo, false);\n                if (tmp996) {\n                    tmp1002 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n                    tmp1003 = 'enemyHero';\n                    _aether.logStatementStart([{ofs: 9903, row: 324, col: 11}, {ofs: 9917, row: 324, col: 25}]); tmp1001 = tmp1002[tmp1003];  _aether.logStatement([{ofs: 9903, row: 324, col: 11}, {ofs: 9917, row: 324, col: 25}], _aether._userInfo, false);\n                    if (tmp1001) {\n                        tmp1006 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n                        tmp1007 = 'doesOpponentHaveRanged';\n                        _aether.logStatementStart([{ofs: 9921, row: 324, col: 29}, {ofs: 9950, row: 324, col: 58}]); tmp1004 = _aether.createAPIClone(_aether, tmp1006[tmp1007]());  _aether.logStatement([{ofs: 9921, row: 324, col: 29}, {ofs: 9950, row: 324, col: 58}], _aether._userInfo, false);\n                        _aether.logStatementStart([{ofs: 9955, row: 324, col: 63}, {ofs: 9956, row: 324, col: 64}]); tmp1005 = 1;  _aether.logStatement([{ofs: 9955, row: 324, col: 63}, {ofs: 9956, row: 324, col: 64}], _aether._userInfo, false);\n                        _aether.logStatementStart([{ofs: 9921, row: 324, col: 29}, {ofs: 9956, row: 324, col: 64}]); tmp1000 = tmp1004 === tmp1005;  _aether.logStatement([{ofs: 9921, row: 324, col: 29}, {ofs: 9956, row: 324, col: 64}], _aether._userInfo, false);\n                    } else {\n                        _aether.logStatementStart([{ofs: 9903, row: 324, col: 11}, {ofs: 9956, row: 324, col: 64}]); tmp1000 = tmp1001;  _aether.logStatement([{ofs: 9903, row: 324, col: 11}, {ofs: 9956, row: 324, col: 64}], _aether._userInfo, false);\n                    }\n                    if (tmp1000) {\n                        tmp1010 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n                        tmp1011 = 'distance';\n                        tmp1013 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n                        tmp1014 = 'enemyHero';\n                        _aether.logStatementStart([{ofs: 9974, row: 324, col: 82}, {ofs: 9988, row: 324, col: 96}]); tmp1012 = tmp1013[tmp1014];  _aether.logStatement([{ofs: 9974, row: 324, col: 82}, {ofs: 9988, row: 324, col: 96}], _aether._userInfo, false);\n                        _aether.logStatementStart([{ofs: 9960, row: 324, col: 68}, {ofs: 9989, row: 324, col: 97}]); tmp1008 = _aether.createAPIClone(_aether, tmp1010[tmp1011](_aether.restoreAPIClone(_aether, tmp1012)));  _aether.logStatement([{ofs: 9960, row: 324, col: 68}, {ofs: 9989, row: 324, col: 97}], _aether._userInfo, false);\n                        _aether.logStatementStart([{ofs: 9993, row: 324, col: 101}, {ofs: 9997, row: 324, col: 105}]); tmp1009 = 16.5;  _aether.logStatement([{ofs: 9993, row: 324, col: 101}, {ofs: 9997, row: 324, col: 105}], _aether._userInfo, false);\n                        _aether.logStatementStart([{ofs: 9960, row: 324, col: 68}, {ofs: 9997, row: 324, col: 105}]); tmp999 = tmp1008 <= tmp1009;  _aether.logStatement([{ofs: 9960, row: 324, col: 68}, {ofs: 9997, row: 324, col: 105}], _aether._userInfo, false);\n                    } else {\n                        _aether.logStatementStart([{ofs: 9903, row: 324, col: 11}, {ofs: 9997, row: 324, col: 105}]); tmp999 = tmp1000;  _aether.logStatement([{ofs: 9903, row: 324, col: 11}, {ofs: 9997, row: 324, col: 105}], _aether._userInfo, false);\n                    }\n                    if (tmp999) {\n                        tmp1015 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n                        tmp1016 = 'determineSayAndAction';\n                        _aether.logStatementStart([{ofs: 10013, row: 325, col: 12}, {ofs: 10041, row: 325, col: 40}]); tmp1017 = _aether.createAPIClone(_aether, tmp1015[tmp1016]());  _aether.logStatement([{ofs: 10013, row: 325, col: 12}, {ofs: 10041, row: 325, col: 40}], _aether._userInfo, false);\n                        tmp1018 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n                        tmp1019 = 'terrifyTargets';\n                        tmp1021 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n                        tmp1022 = 'getTerrifyTargets';\n                        _aether.logStatementStart([{ofs: 10055, row: 326, col: 12}, {ofs: 10102, row: 326, col: 59}]); tmp1020 = _aether.createAPIClone(_aether, tmp1021[tmp1022]());  _aether.logStatement([{ofs: 10055, row: 326, col: 12}, {ofs: 10102, row: 326, col: 59}], _aether._userInfo, false);\n                        _aether.logStatementStart([{ofs: 10055, row: 326, col: 12}, {ofs: 10101, row: 326, col: 58}]); tmp1018[tmp1019] = tmp1020;  _aether.logStatement([{ofs: 10055, row: 326, col: 12}, {ofs: 10101, row: 326, col: 58}], _aether._userInfo, false);\n                        tmp1023 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n                        tmp1024 = 'terrify';\n                        _aether.logStatementStart([{ofs: 10115, row: 327, col: 12}, {ofs: 10129, row: 327, col: 26}]); tmp1025 = _aether.createAPIClone(_aether, tmp1023[tmp1024]());  _aether.logStatement([{ofs: 10115, row: 327, col: 12}, {ofs: 10129, row: 327, col: 26}], _aether._userInfo, false);\n                        _aether.logCallEnd(); return;\n                    } else {\n                        tmp1029 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n                        tmp1030 = 'enemyHero';\n                        _aether.logStatementStart([{ofs: 10367, row: 334, col: 16}, {ofs: 10381, row: 334, col: 30}]); tmp1028 = tmp1029[tmp1030];  _aether.logStatement([{ofs: 10367, row: 334, col: 16}, {ofs: 10381, row: 334, col: 30}], _aether._userInfo, false);\n                        if (tmp1028) {\n                            tmp1033 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n                            tmp1034 = 'doesOpponentHaveRanged';\n                            _aether.logStatementStart([{ofs: 10385, row: 334, col: 34}, {ofs: 10414, row: 334, col: 63}]); tmp1031 = _aether.createAPIClone(_aether, tmp1033[tmp1034]());  _aether.logStatement([{ofs: 10385, row: 334, col: 34}, {ofs: 10414, row: 334, col: 63}], _aether._userInfo, false);\n                            _aether.logStatementStart([{ofs: 10419, row: 334, col: 68}, {ofs: 10420, row: 334, col: 69}]); tmp1032 = 2;  _aether.logStatement([{ofs: 10419, row: 334, col: 68}, {ofs: 10420, row: 334, col: 69}], _aether._userInfo, false);\n                            _aether.logStatementStart([{ofs: 10385, row: 334, col: 34}, {ofs: 10420, row: 334, col: 69}]); tmp1027 = tmp1031 === tmp1032;  _aether.logStatement([{ofs: 10385, row: 334, col: 34}, {ofs: 10420, row: 334, col: 69}], _aether._userInfo, false);\n                        } else {\n                            _aether.logStatementStart([{ofs: 10367, row: 334, col: 16}, {ofs: 10420, row: 334, col: 69}]); tmp1027 = tmp1028;  _aether.logStatement([{ofs: 10367, row: 334, col: 16}, {ofs: 10420, row: 334, col: 69}], _aether._userInfo, false);\n                        }\n                        if (tmp1027) {\n                            tmp1037 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n                            tmp1038 = 'distance';\n                            tmp1040 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n                            tmp1041 = 'enemyHero';\n                            _aether.logStatementStart([{ofs: 10438, row: 334, col: 87}, {ofs: 10452, row: 334, col: 101}]); tmp1039 = tmp1040[tmp1041];  _aether.logStatement([{ofs: 10438, row: 334, col: 87}, {ofs: 10452, row: 334, col: 101}], _aether._userInfo, false);\n                            _aether.logStatementStart([{ofs: 10424, row: 334, col: 73}, {ofs: 10453, row: 334, col: 102}]); tmp1035 = _aether.createAPIClone(_aether, tmp1037[tmp1038](_aether.restoreAPIClone(_aether, tmp1039)));  _aether.logStatement([{ofs: 10424, row: 334, col: 73}, {ofs: 10453, row: 334, col: 102}], _aether._userInfo, false);\n                            _aether.logStatementStart([{ofs: 10457, row: 334, col: 106}, {ofs: 10459, row: 334, col: 108}]); tmp1036 = 12;  _aether.logStatement([{ofs: 10457, row: 334, col: 106}, {ofs: 10459, row: 334, col: 108}], _aether._userInfo, false);\n                            _aether.logStatementStart([{ofs: 10424, row: 334, col: 73}, {ofs: 10459, row: 334, col: 108}]); tmp1026 = tmp1035 <= tmp1036;  _aether.logStatement([{ofs: 10424, row: 334, col: 73}, {ofs: 10459, row: 334, col: 108}], _aether._userInfo, false);\n                        } else {\n                            _aether.logStatementStart([{ofs: 10367, row: 334, col: 16}, {ofs: 10459, row: 334, col: 108}]); tmp1026 = tmp1027;  _aether.logStatement([{ofs: 10367, row: 334, col: 16}, {ofs: 10459, row: 334, col: 108}], _aether._userInfo, false);\n                        }\n                        if (tmp1026) {\n                            tmp1042 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n                            tmp1043 = 'determineSayAndAction';\n                            _aether.logStatementStart([{ofs: 10475, row: 335, col: 12}, {ofs: 10503, row: 335, col: 40}]); tmp1044 = _aether.createAPIClone(_aether, tmp1042[tmp1043]());  _aether.logStatement([{ofs: 10475, row: 335, col: 12}, {ofs: 10503, row: 335, col: 40}], _aether._userInfo, false);\n                            tmp1045 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n                            tmp1046 = 'terrifyTargets';\n                            tmp1048 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n                            tmp1049 = 'getTerrifyTargets';\n                            _aether.logStatementStart([{ofs: 10517, row: 336, col: 12}, {ofs: 10564, row: 336, col: 59}]); tmp1047 = _aether.createAPIClone(_aether, tmp1048[tmp1049]());  _aether.logStatement([{ofs: 10517, row: 336, col: 12}, {ofs: 10564, row: 336, col: 59}], _aether._userInfo, false);\n                            _aether.logStatementStart([{ofs: 10517, row: 336, col: 12}, {ofs: 10563, row: 336, col: 58}]); tmp1045[tmp1046] = tmp1047;  _aether.logStatement([{ofs: 10517, row: 336, col: 12}, {ofs: 10563, row: 336, col: 58}], _aether._userInfo, false);\n                            tmp1050 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n                            tmp1051 = 'terrify';\n                            _aether.logStatementStart([{ofs: 10577, row: 337, col: 12}, {ofs: 10591, row: 337, col: 26}]); tmp1052 = _aether.createAPIClone(_aether, tmp1050[tmp1051]());  _aether.logStatement([{ofs: 10577, row: 337, col: 12}, {ofs: 10591, row: 337, col: 26}], _aether._userInfo, false);\n                            _aether.logCallEnd(); return;\n                        } else {\n                            tmp1056 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n                            tmp1057 = 'enemyHero';\n                            _aether.logStatementStart([{ofs: 10639, row: 340, col: 16}, {ofs: 10653, row: 340, col: 30}]); tmp1055 = tmp1056[tmp1057];  _aether.logStatement([{ofs: 10639, row: 340, col: 16}, {ofs: 10653, row: 340, col: 30}], _aether._userInfo, false);\n                            if (tmp1055) {\n                                tmp1060 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n                                tmp1061 = 'doesOpponentHaveRanged';\n                                _aether.logStatementStart([{ofs: 10657, row: 340, col: 34}, {ofs: 10686, row: 340, col: 63}]); tmp1058 = _aether.createAPIClone(_aether, tmp1060[tmp1061]());  _aether.logStatement([{ofs: 10657, row: 340, col: 34}, {ofs: 10686, row: 340, col: 63}], _aether._userInfo, false);\n                                _aether.logStatementStart([{ofs: 10691, row: 340, col: 68}, {ofs: 10692, row: 340, col: 69}]); tmp1059 = 3;  _aether.logStatement([{ofs: 10691, row: 340, col: 68}, {ofs: 10692, row: 340, col: 69}], _aether._userInfo, false);\n                                _aether.logStatementStart([{ofs: 10657, row: 340, col: 34}, {ofs: 10692, row: 340, col: 69}]); tmp1054 = tmp1058 === tmp1059;  _aether.logStatement([{ofs: 10657, row: 340, col: 34}, {ofs: 10692, row: 340, col: 69}], _aether._userInfo, false);\n                            } else {\n                                _aether.logStatementStart([{ofs: 10639, row: 340, col: 16}, {ofs: 10692, row: 340, col: 69}]); tmp1054 = tmp1055;  _aether.logStatement([{ofs: 10639, row: 340, col: 16}, {ofs: 10692, row: 340, col: 69}], _aether._userInfo, false);\n                            }\n                            if (tmp1054) {\n                                tmp1064 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n                                tmp1065 = 'distance';\n                                tmp1067 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n                                tmp1068 = 'enemyHero';\n                                _aether.logStatementStart([{ofs: 10710, row: 340, col: 87}, {ofs: 10724, row: 340, col: 101}]); tmp1066 = tmp1067[tmp1068];  _aether.logStatement([{ofs: 10710, row: 340, col: 87}, {ofs: 10724, row: 340, col: 101}], _aether._userInfo, false);\n                                _aether.logStatementStart([{ofs: 10696, row: 340, col: 73}, {ofs: 10725, row: 340, col: 102}]); tmp1062 = _aether.createAPIClone(_aether, tmp1064[tmp1065](_aether.restoreAPIClone(_aether, tmp1066)));  _aether.logStatement([{ofs: 10696, row: 340, col: 73}, {ofs: 10725, row: 340, col: 102}], _aether._userInfo, false);\n                                _aether.logStatementStart([{ofs: 10729, row: 340, col: 106}, {ofs: 10731, row: 340, col: 108}]); tmp1063 = 12;  _aether.logStatement([{ofs: 10729, row: 340, col: 106}, {ofs: 10731, row: 340, col: 108}], _aether._userInfo, false);\n                                _aether.logStatementStart([{ofs: 10696, row: 340, col: 73}, {ofs: 10731, row: 340, col: 108}]); tmp1053 = tmp1062 <= tmp1063;  _aether.logStatement([{ofs: 10696, row: 340, col: 73}, {ofs: 10731, row: 340, col: 108}], _aether._userInfo, false);\n                            } else {\n                                _aether.logStatementStart([{ofs: 10639, row: 340, col: 16}, {ofs: 10731, row: 340, col: 108}]); tmp1053 = tmp1054;  _aether.logStatement([{ofs: 10639, row: 340, col: 16}, {ofs: 10731, row: 340, col: 108}], _aether._userInfo, false);\n                            }\n                            if (tmp1053) {\n                                tmp1069 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n                                tmp1070 = 'determineSayAndAction';\n                                _aether.logStatementStart([{ofs: 10747, row: 341, col: 12}, {ofs: 10775, row: 341, col: 40}]); tmp1071 = _aether.createAPIClone(_aether, tmp1069[tmp1070]());  _aether.logStatement([{ofs: 10747, row: 341, col: 12}, {ofs: 10775, row: 341, col: 40}], _aether._userInfo, false);\n                                tmp1072 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n                                tmp1073 = 'terrifyTargets';\n                                tmp1075 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n                                tmp1076 = 'getTerrifyTargets';\n                                _aether.logStatementStart([{ofs: 10789, row: 342, col: 12}, {ofs: 10836, row: 342, col: 59}]); tmp1074 = _aether.createAPIClone(_aether, tmp1075[tmp1076]());  _aether.logStatement([{ofs: 10789, row: 342, col: 12}, {ofs: 10836, row: 342, col: 59}], _aether._userInfo, false);\n                                _aether.logStatementStart([{ofs: 10789, row: 342, col: 12}, {ofs: 10835, row: 342, col: 58}]); tmp1072[tmp1073] = tmp1074;  _aether.logStatement([{ofs: 10789, row: 342, col: 12}, {ofs: 10835, row: 342, col: 58}], _aether._userInfo, false);\n                                tmp1077 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n                                tmp1078 = 'terrify';\n                                _aether.logStatementStart([{ofs: 10849, row: 343, col: 12}, {ofs: 10863, row: 343, col: 26}]); tmp1079 = _aether.createAPIClone(_aether, tmp1077[tmp1078]());  _aether.logStatement([{ofs: 10849, row: 343, col: 12}, {ofs: 10863, row: 343, col: 26}], _aether._userInfo, false);\n                                _aether.logCallEnd(); return;\n                            } else {\n                                ;\n                            }\n                        }\n                    }\n                } else {\n                    tmp1081 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n                    tmp1082 = 'recalculateBaseRace';\n                    _aether.logStatementStart([{ofs: 10913, row: 347, col: 12}, {ofs: 10939, row: 347, col: 38}]); tmp1080 = _aether.createAPIClone(_aether, tmp1081[tmp1082]());  _aether.logStatement([{ofs: 10913, row: 347, col: 12}, {ofs: 10939, row: 347, col: 38}], _aether._userInfo, false);\n                    if (tmp1080) {\n                        tmp1085 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n                        tmp1086 = 'enemyHero';\n                        _aether.logStatementStart([{ofs: 10954, row: 348, col: 11}, {ofs: 10968, row: 348, col: 25}]); tmp1084 = tmp1085[tmp1086];  _aether.logStatement([{ofs: 10954, row: 348, col: 11}, {ofs: 10968, row: 348, col: 25}], _aether._userInfo, false);\n                        if (tmp1084) {\n                            tmp1089 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n                            tmp1090 = 'distance';\n                            tmp1092 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n                            tmp1093 = 'enemyHero';\n                            _aether.logStatementStart([{ofs: 10986, row: 348, col: 43}, {ofs: 11000, row: 348, col: 57}]); tmp1091 = tmp1092[tmp1093];  _aether.logStatement([{ofs: 10986, row: 348, col: 43}, {ofs: 11000, row: 348, col: 57}], _aether._userInfo, false);\n                            _aether.logStatementStart([{ofs: 10972, row: 348, col: 29}, {ofs: 11001, row: 348, col: 58}]); tmp1087 = _aether.createAPIClone(_aether, tmp1089[tmp1090](_aether.restoreAPIClone(_aether, tmp1091)));  _aether.logStatement([{ofs: 10972, row: 348, col: 29}, {ofs: 11001, row: 348, col: 58}], _aether._userInfo, false);\n                            _aether.logStatementStart([{ofs: 11005, row: 348, col: 62}, {ofs: 11007, row: 348, col: 64}]); tmp1088 = 17;  _aether.logStatement([{ofs: 11005, row: 348, col: 62}, {ofs: 11007, row: 348, col: 64}], _aether._userInfo, false);\n                            _aether.logStatementStart([{ofs: 10972, row: 348, col: 29}, {ofs: 11007, row: 348, col: 64}]); tmp1083 = tmp1087 <= tmp1088;  _aether.logStatement([{ofs: 10972, row: 348, col: 29}, {ofs: 11007, row: 348, col: 64}], _aether._userInfo, false);\n                        } else {\n                            _aether.logStatementStart([{ofs: 10954, row: 348, col: 11}, {ofs: 11007, row: 348, col: 64}]); tmp1083 = tmp1084;  _aether.logStatement([{ofs: 10954, row: 348, col: 11}, {ofs: 11007, row: 348, col: 64}], _aether._userInfo, false);\n                        }\n                        if (tmp1083) {\n                            tmp1094 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n                            tmp1095 = 'determineSayAndAction';\n                            _aether.logStatementStart([{ofs: 11023, row: 349, col: 12}, {ofs: 11051, row: 349, col: 40}]); tmp1096 = _aether.createAPIClone(_aether, tmp1094[tmp1095]());  _aether.logStatement([{ofs: 11023, row: 349, col: 12}, {ofs: 11051, row: 349, col: 40}], _aether._userInfo, false);\n                            tmp1097 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n                            tmp1098 = 'terrifyTargets';\n                            tmp1100 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n                            tmp1101 = 'getTerrifyTargets';\n                            _aether.logStatementStart([{ofs: 11065, row: 350, col: 12}, {ofs: 11112, row: 350, col: 59}]); tmp1099 = _aether.createAPIClone(_aether, tmp1100[tmp1101]());  _aether.logStatement([{ofs: 11065, row: 350, col: 12}, {ofs: 11112, row: 350, col: 59}], _aether._userInfo, false);\n                            _aether.logStatementStart([{ofs: 11065, row: 350, col: 12}, {ofs: 11111, row: 350, col: 58}]); tmp1097[tmp1098] = tmp1099;  _aether.logStatement([{ofs: 11065, row: 350, col: 12}, {ofs: 11111, row: 350, col: 58}], _aether._userInfo, false);\n                            tmp1102 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n                            tmp1103 = 'terrify';\n                            _aether.logStatementStart([{ofs: 11125, row: 351, col: 12}, {ofs: 11139, row: 351, col: 26}]); tmp1104 = _aether.createAPIClone(_aether, tmp1102[tmp1103]());  _aether.logStatement([{ofs: 11125, row: 351, col: 12}, {ofs: 11139, row: 351, col: 26}], _aether._userInfo, false);\n                            _aether.logCallEnd(); return;\n                        } else {\n                            ;\n                        }\n                    } else {\n                        tmp1107 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n                        tmp1108 = 'baseRace';\n                        _aether.logStatementStart([{ofs: 11189, row: 355, col: 12}, {ofs: 11202, row: 355, col: 25}]); tmp1106 = tmp1107[tmp1108];  _aether.logStatement([{ofs: 11189, row: 355, col: 12}, {ofs: 11202, row: 355, col: 25}], _aether._userInfo, false);\n                        if (tmp1106) {\n                            tmp1111 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n                            tmp1112 = 'now';\n                            _aether.logStatementStart([{ofs: 11206, row: 355, col: 29}, {ofs: 11216, row: 355, col: 39}]); tmp1109 = _aether.createAPIClone(_aether, tmp1111[tmp1112]());  _aether.logStatement([{ofs: 11206, row: 355, col: 29}, {ofs: 11216, row: 355, col: 39}], _aether._userInfo, false);\n                            _aether.logStatementStart([{ofs: 11220, row: 355, col: 43}, {ofs: 11221, row: 355, col: 44}]); tmp1110 = 6;  _aether.logStatement([{ofs: 11220, row: 355, col: 43}, {ofs: 11221, row: 355, col: 44}], _aether._userInfo, false);\n                            _aether.logStatementStart([{ofs: 11206, row: 355, col: 29}, {ofs: 11221, row: 355, col: 44}]); tmp1105 = tmp1109 <= tmp1110;  _aether.logStatement([{ofs: 11206, row: 355, col: 29}, {ofs: 11221, row: 355, col: 44}], _aether._userInfo, false);\n                        } else {\n                            _aether.logStatementStart([{ofs: 11189, row: 355, col: 12}, {ofs: 11221, row: 355, col: 44}]); tmp1105 = tmp1106;  _aether.logStatement([{ofs: 11189, row: 355, col: 12}, {ofs: 11221, row: 355, col: 44}], _aether._userInfo, false);\n                        }\n                        if (tmp1105) {\n                            tmp1115 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n                            tmp1116 = 'isOpponentHeroRushing';\n                            _aether.logStatementStart([{ofs: 11236, row: 356, col: 11}, {ofs: 11262, row: 356, col: 37}]); tmp1114 = tmp1115[tmp1116];  _aether.logStatement([{ofs: 11236, row: 356, col: 11}, {ofs: 11262, row: 356, col: 37}], _aether._userInfo, false);\n                            if (tmp1114) {\n                                tmp1119 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n                                tmp1120 = 'doesOpponentHaveRanged';\n                                _aether.logStatementStart([{ofs: 11266, row: 356, col: 41}, {ofs: 11295, row: 356, col: 70}]); tmp1117 = _aether.createAPIClone(_aether, tmp1119[tmp1120]());  _aether.logStatement([{ofs: 11266, row: 356, col: 41}, {ofs: 11295, row: 356, col: 70}], _aether._userInfo, false);\n                                _aether.logStatementStart([{ofs: 11300, row: 356, col: 75}, {ofs: 11301, row: 356, col: 76}]); tmp1118 = 1;  _aether.logStatement([{ofs: 11300, row: 356, col: 75}, {ofs: 11301, row: 356, col: 76}], _aether._userInfo, false);\n                                _aether.logStatementStart([{ofs: 11266, row: 356, col: 41}, {ofs: 11301, row: 356, col: 76}]); tmp1113 = tmp1117 === tmp1118;  _aether.logStatement([{ofs: 11266, row: 356, col: 41}, {ofs: 11301, row: 356, col: 76}], _aether._userInfo, false);\n                            } else {\n                                _aether.logStatementStart([{ofs: 11236, row: 356, col: 11}, {ofs: 11301, row: 356, col: 76}]); tmp1113 = tmp1114;  _aether.logStatement([{ofs: 11236, row: 356, col: 11}, {ofs: 11301, row: 356, col: 76}], _aether._userInfo, false);\n                            }\n                            if (tmp1113) {\n                                tmp1123 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n                                tmp1124 = 'enemyHero';\n                                _aether.logStatementStart([{ofs: 11360, row: 358, col: 15}, {ofs: 11374, row: 358, col: 29}]); tmp1122 = tmp1123[tmp1124];  _aether.logStatement([{ofs: 11360, row: 358, col: 15}, {ofs: 11374, row: 358, col: 29}], _aether._userInfo, false);\n                                if (tmp1122) {\n                                    tmp1127 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n                                    tmp1128 = 'distance';\n                                    tmp1130 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n                                    tmp1131 = 'enemyHero';\n                                    _aether.logStatementStart([{ofs: 11392, row: 358, col: 47}, {ofs: 11406, row: 358, col: 61}]); tmp1129 = tmp1130[tmp1131];  _aether.logStatement([{ofs: 11392, row: 358, col: 47}, {ofs: 11406, row: 358, col: 61}], _aether._userInfo, false);\n                                    _aether.logStatementStart([{ofs: 11378, row: 358, col: 33}, {ofs: 11407, row: 358, col: 62}]); tmp1125 = _aether.createAPIClone(_aether, tmp1127[tmp1128](_aether.restoreAPIClone(_aether, tmp1129)));  _aether.logStatement([{ofs: 11378, row: 358, col: 33}, {ofs: 11407, row: 358, col: 62}], _aether._userInfo, false);\n                                    _aether.logStatementStart([{ofs: 11411, row: 358, col: 66}, {ofs: 11412, row: 358, col: 67}]); tmp1126 = 5;  _aether.logStatement([{ofs: 11411, row: 358, col: 66}, {ofs: 11412, row: 358, col: 67}], _aether._userInfo, false);\n                                    _aether.logStatementStart([{ofs: 11378, row: 358, col: 33}, {ofs: 11412, row: 358, col: 67}]); tmp1121 = tmp1125 <= tmp1126;  _aether.logStatement([{ofs: 11378, row: 358, col: 33}, {ofs: 11412, row: 358, col: 67}], _aether._userInfo, false);\n                                } else {\n                                    _aether.logStatementStart([{ofs: 11360, row: 358, col: 15}, {ofs: 11412, row: 358, col: 67}]); tmp1121 = tmp1122;  _aether.logStatement([{ofs: 11360, row: 358, col: 15}, {ofs: 11412, row: 358, col: 67}], _aether._userInfo, false);\n                                }\n                                if (tmp1121) {\n                                    tmp1132 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n                                    tmp1133 = 'determineSayAndAction';\n                                    _aether.logStatementStart([{ofs: 11432, row: 359, col: 16}, {ofs: 11460, row: 359, col: 44}]); tmp1134 = _aether.createAPIClone(_aether, tmp1132[tmp1133]());  _aether.logStatement([{ofs: 11432, row: 359, col: 16}, {ofs: 11460, row: 359, col: 44}], _aether._userInfo, false);\n                                    tmp1135 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n                                    tmp1136 = 'terrifyTargets';\n                                    tmp1138 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n                                    tmp1139 = 'getTerrifyTargets';\n                                    _aether.logStatementStart([{ofs: 11478, row: 360, col: 16}, {ofs: 11525, row: 360, col: 63}]); tmp1137 = _aether.createAPIClone(_aether, tmp1138[tmp1139]());  _aether.logStatement([{ofs: 11478, row: 360, col: 16}, {ofs: 11525, row: 360, col: 63}], _aether._userInfo, false);\n                                    _aether.logStatementStart([{ofs: 11478, row: 360, col: 16}, {ofs: 11524, row: 360, col: 62}]); tmp1135[tmp1136] = tmp1137;  _aether.logStatement([{ofs: 11478, row: 360, col: 16}, {ofs: 11524, row: 360, col: 62}], _aether._userInfo, false);\n                                    tmp1140 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n                                    tmp1141 = 'terrify';\n                                    _aether.logStatementStart([{ofs: 11542, row: 361, col: 16}, {ofs: 11556, row: 361, col: 30}]); tmp1142 = _aether.createAPIClone(_aether, tmp1140[tmp1141]());  _aether.logStatement([{ofs: 11542, row: 361, col: 16}, {ofs: 11556, row: 361, col: 30}], _aether._userInfo, false);\n                                    _aether.logCallEnd(); return;\n                                } else {\n                                    ;\n                                }\n                            } else {\n                                ;\n                            }\n                            tmp1145 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n                            tmp1146 = 'isOpponentHeroRushing';\n                            _aether.logStatementStart([{ofs: 11673, row: 366, col: 11}, {ofs: 11699, row: 366, col: 37}]); tmp1144 = tmp1145[tmp1146];  _aether.logStatement([{ofs: 11673, row: 366, col: 11}, {ofs: 11699, row: 366, col: 37}], _aether._userInfo, false);\n                            if (tmp1144) {\n                                tmp1149 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n                                tmp1150 = 'doesOpponentHaveRanged';\n                                _aether.logStatementStart([{ofs: 11703, row: 366, col: 41}, {ofs: 11732, row: 366, col: 70}]); tmp1147 = _aether.createAPIClone(_aether, tmp1149[tmp1150]());  _aether.logStatement([{ofs: 11703, row: 366, col: 41}, {ofs: 11732, row: 366, col: 70}], _aether._userInfo, false);\n                                _aether.logStatementStart([{ofs: 11735, row: 366, col: 73}, {ofs: 11736, row: 366, col: 74}]); tmp1148 = 1;  _aether.logStatement([{ofs: 11735, row: 366, col: 73}, {ofs: 11736, row: 366, col: 74}], _aether._userInfo, false);\n                                _aether.logStatementStart([{ofs: 11703, row: 366, col: 41}, {ofs: 11736, row: 366, col: 74}]); tmp1143 = tmp1147 > tmp1148;  _aether.logStatement([{ofs: 11703, row: 366, col: 41}, {ofs: 11736, row: 366, col: 74}], _aether._userInfo, false);\n                            } else {\n                                _aether.logStatementStart([{ofs: 11673, row: 366, col: 11}, {ofs: 11736, row: 366, col: 74}]); tmp1143 = tmp1144;  _aether.logStatement([{ofs: 11673, row: 366, col: 11}, {ofs: 11736, row: 366, col: 74}], _aether._userInfo, false);\n                            }\n                            if (tmp1143) {\n                                tmp1153 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n                                tmp1154 = 'enemyHero';\n                                _aether.logStatementStart([{ofs: 11755, row: 367, col: 15}, {ofs: 11769, row: 367, col: 29}]); tmp1152 = tmp1153[tmp1154];  _aether.logStatement([{ofs: 11755, row: 367, col: 15}, {ofs: 11769, row: 367, col: 29}], _aether._userInfo, false);\n                                if (tmp1152) {\n                                    tmp1157 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n                                    tmp1158 = 'distance';\n                                    tmp1160 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n                                    tmp1161 = 'enemyHero';\n                                    _aether.logStatementStart([{ofs: 11787, row: 367, col: 47}, {ofs: 11801, row: 367, col: 61}]); tmp1159 = tmp1160[tmp1161];  _aether.logStatement([{ofs: 11787, row: 367, col: 47}, {ofs: 11801, row: 367, col: 61}], _aether._userInfo, false);\n                                    _aether.logStatementStart([{ofs: 11773, row: 367, col: 33}, {ofs: 11802, row: 367, col: 62}]); tmp1155 = _aether.createAPIClone(_aether, tmp1157[tmp1158](_aether.restoreAPIClone(_aether, tmp1159)));  _aether.logStatement([{ofs: 11773, row: 367, col: 33}, {ofs: 11802, row: 367, col: 62}], _aether._userInfo, false);\n                                    _aether.logStatementStart([{ofs: 11806, row: 367, col: 66}, {ofs: 11808, row: 367, col: 68}]); tmp1156 = 17;  _aether.logStatement([{ofs: 11806, row: 367, col: 66}, {ofs: 11808, row: 367, col: 68}], _aether._userInfo, false);\n                                    _aether.logStatementStart([{ofs: 11773, row: 367, col: 33}, {ofs: 11808, row: 367, col: 68}]); tmp1151 = tmp1155 <= tmp1156;  _aether.logStatement([{ofs: 11773, row: 367, col: 33}, {ofs: 11808, row: 367, col: 68}], _aether._userInfo, false);\n                                } else {\n                                    _aether.logStatementStart([{ofs: 11755, row: 367, col: 15}, {ofs: 11808, row: 367, col: 68}]); tmp1151 = tmp1152;  _aether.logStatement([{ofs: 11755, row: 367, col: 15}, {ofs: 11808, row: 367, col: 68}], _aether._userInfo, false);\n                                }\n                                if (tmp1151) {\n                                    tmp1162 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n                                    tmp1163 = 'determineSayAndAction';\n                                    _aether.logStatementStart([{ofs: 11828, row: 368, col: 16}, {ofs: 11856, row: 368, col: 44}]); tmp1164 = _aether.createAPIClone(_aether, tmp1162[tmp1163]());  _aether.logStatement([{ofs: 11828, row: 368, col: 16}, {ofs: 11856, row: 368, col: 44}], _aether._userInfo, false);\n                                    tmp1165 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n                                    tmp1166 = 'terrifyTargets';\n                                    tmp1168 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n                                    tmp1169 = 'getTerrifyTargets';\n                                    _aether.logStatementStart([{ofs: 11874, row: 369, col: 16}, {ofs: 11921, row: 369, col: 63}]); tmp1167 = _aether.createAPIClone(_aether, tmp1168[tmp1169]());  _aether.logStatement([{ofs: 11874, row: 369, col: 16}, {ofs: 11921, row: 369, col: 63}], _aether._userInfo, false);\n                                    _aether.logStatementStart([{ofs: 11874, row: 369, col: 16}, {ofs: 11920, row: 369, col: 62}]); tmp1165[tmp1166] = tmp1167;  _aether.logStatement([{ofs: 11874, row: 369, col: 16}, {ofs: 11920, row: 369, col: 62}], _aether._userInfo, false);\n                                    tmp1170 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n                                    tmp1171 = 'terrify';\n                                    _aether.logStatementStart([{ofs: 11938, row: 370, col: 16}, {ofs: 11952, row: 370, col: 30}]); tmp1172 = _aether.createAPIClone(_aether, tmp1170[tmp1171]());  _aether.logStatement([{ofs: 11938, row: 370, col: 16}, {ofs: 11952, row: 370, col: 30}], _aether._userInfo, false);\n                                    _aether.logCallEnd(); return;\n                                } else {\n                                    ;\n                                }\n                            } else {\n                                tmp1176 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n                                tmp1177 = 'enemyHero';\n                                _aether.logStatementStart([{ofs: 12019, row: 375, col: 16}, {ofs: 12033, row: 375, col: 30}]); tmp1175 = tmp1176[tmp1177];  _aether.logStatement([{ofs: 12019, row: 375, col: 16}, {ofs: 12033, row: 375, col: 30}], _aether._userInfo, false);\n                                if (tmp1175) {\n                                    tmp1180 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n                                    tmp1181 = 'enemyHero';\n                                    _aether.logStatementStart([{ofs: 12037, row: 375, col: 34}, {ofs: 12051, row: 375, col: 48}]); tmp1178 = tmp1180[tmp1181];  _aether.logStatement([{ofs: 12037, row: 375, col: 34}, {ofs: 12051, row: 375, col: 48}], _aether._userInfo, false);\n                                    tmp1179 = 'target';\n                                    _aether.logStatementStart([{ofs: 12037, row: 375, col: 34}, {ofs: 12058, row: 375, col: 55}]); tmp1174 = tmp1178[tmp1179];  _aether.logStatement([{ofs: 12037, row: 375, col: 34}, {ofs: 12058, row: 375, col: 55}], _aether._userInfo, false);\n                                } else {\n                                    _aether.logStatementStart([{ofs: 12019, row: 375, col: 16}, {ofs: 12058, row: 375, col: 55}]); tmp1174 = tmp1175;  _aether.logStatement([{ofs: 12019, row: 375, col: 16}, {ofs: 12058, row: 375, col: 55}], _aether._userInfo, false);\n                                }\n                                if (tmp1174) {\n                                    tmp1188 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n                                    tmp1189 = 'enemyHero';\n                                    _aether.logStatementStart([{ofs: 12062, row: 375, col: 59}, {ofs: 12076, row: 375, col: 73}]); tmp1186 = tmp1188[tmp1189];  _aether.logStatement([{ofs: 12062, row: 375, col: 59}, {ofs: 12076, row: 375, col: 73}], _aether._userInfo, false);\n                                    tmp1187 = 'target';\n                                    _aether.logStatementStart([{ofs: 12062, row: 375, col: 59}, {ofs: 12083, row: 375, col: 80}]); tmp1184 = tmp1186[tmp1187];  _aether.logStatement([{ofs: 12062, row: 375, col: 59}, {ofs: 12083, row: 375, col: 80}], _aether._userInfo, false);\n                                    tmp1185 = 'type';\n                                    _aether.logStatementStart([{ofs: 12062, row: 375, col: 59}, {ofs: 12088, row: 375, col: 85}]); tmp1182 = tmp1184[tmp1185];  _aether.logStatement([{ofs: 12062, row: 375, col: 59}, {ofs: 12088, row: 375, col: 85}], _aether._userInfo, false);\n                                    _aether.logStatementStart([{ofs: 12092, row: 375, col: 89}, {ofs: 12098, row: 375, col: 95}]); tmp1183 = 'base';  _aether.logStatement([{ofs: 12092, row: 375, col: 89}, {ofs: 12098, row: 375, col: 95}], _aether._userInfo, false);\n                                    _aether.logStatementStart([{ofs: 12062, row: 375, col: 59}, {ofs: 12098, row: 375, col: 95}]); tmp1173 = tmp1182 != tmp1183;  _aether.logStatement([{ofs: 12062, row: 375, col: 59}, {ofs: 12098, row: 375, col: 95}], _aether._userInfo, false);\n                                } else {\n                                    _aether.logStatementStart([{ofs: 12019, row: 375, col: 16}, {ofs: 12098, row: 375, col: 95}]); tmp1173 = tmp1174;  _aether.logStatement([{ofs: 12019, row: 375, col: 16}, {ofs: 12098, row: 375, col: 95}], _aether._userInfo, false);\n                                }\n                                if (tmp1173) {\n                                    tmp1192 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n                                    tmp1193 = 'enemyHero';\n                                    _aether.logStatementStart([{ofs: 12117, row: 376, col: 15}, {ofs: 12131, row: 376, col: 29}]); tmp1191 = tmp1192[tmp1193];  _aether.logStatement([{ofs: 12117, row: 376, col: 15}, {ofs: 12131, row: 376, col: 29}], _aether._userInfo, false);\n                                    if (tmp1191) {\n                                        tmp1196 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n                                        tmp1197 = 'distance';\n                                        tmp1199 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n                                        tmp1200 = 'enemyHero';\n                                        _aether.logStatementStart([{ofs: 12149, row: 376, col: 47}, {ofs: 12163, row: 376, col: 61}]); tmp1198 = tmp1199[tmp1200];  _aether.logStatement([{ofs: 12149, row: 376, col: 47}, {ofs: 12163, row: 376, col: 61}], _aether._userInfo, false);\n                                        _aether.logStatementStart([{ofs: 12135, row: 376, col: 33}, {ofs: 12164, row: 376, col: 62}]); tmp1194 = _aether.createAPIClone(_aether, tmp1196[tmp1197](_aether.restoreAPIClone(_aether, tmp1198)));  _aether.logStatement([{ofs: 12135, row: 376, col: 33}, {ofs: 12164, row: 376, col: 62}], _aether._userInfo, false);\n                                        _aether.logStatementStart([{ofs: 12168, row: 376, col: 66}, {ofs: 12170, row: 376, col: 68}]); tmp1195 = 18;  _aether.logStatement([{ofs: 12168, row: 376, col: 66}, {ofs: 12170, row: 376, col: 68}], _aether._userInfo, false);\n                                        _aether.logStatementStart([{ofs: 12135, row: 376, col: 33}, {ofs: 12170, row: 376, col: 68}]); tmp1190 = tmp1194 <= tmp1195;  _aether.logStatement([{ofs: 12135, row: 376, col: 33}, {ofs: 12170, row: 376, col: 68}], _aether._userInfo, false);\n                                    } else {\n                                        _aether.logStatementStart([{ofs: 12117, row: 376, col: 15}, {ofs: 12170, row: 376, col: 68}]); tmp1190 = tmp1191;  _aether.logStatement([{ofs: 12117, row: 376, col: 15}, {ofs: 12170, row: 376, col: 68}], _aether._userInfo, false);\n                                    }\n                                    if (tmp1190) {\n                                        tmp1201 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n                                        tmp1202 = 'determineSayAndAction';\n                                        _aether.logStatementStart([{ofs: 12190, row: 377, col: 16}, {ofs: 12218, row: 377, col: 44}]); tmp1203 = _aether.createAPIClone(_aether, tmp1201[tmp1202]());  _aether.logStatement([{ofs: 12190, row: 377, col: 16}, {ofs: 12218, row: 377, col: 44}], _aether._userInfo, false);\n                                        tmp1204 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n                                        tmp1205 = 'terrifyTargets';\n                                        tmp1207 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n                                        tmp1208 = 'getTerrifyTargets';\n                                        _aether.logStatementStart([{ofs: 12236, row: 378, col: 16}, {ofs: 12283, row: 378, col: 63}]); tmp1206 = _aether.createAPIClone(_aether, tmp1207[tmp1208]());  _aether.logStatement([{ofs: 12236, row: 378, col: 16}, {ofs: 12283, row: 378, col: 63}], _aether._userInfo, false);\n                                        _aether.logStatementStart([{ofs: 12236, row: 378, col: 16}, {ofs: 12282, row: 378, col: 62}]); tmp1204[tmp1205] = tmp1206;  _aether.logStatement([{ofs: 12236, row: 378, col: 16}, {ofs: 12282, row: 378, col: 62}], _aether._userInfo, false);\n                                        tmp1209 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n                                        tmp1210 = 'terrify';\n                                        _aether.logStatementStart([{ofs: 12300, row: 379, col: 16}, {ofs: 12314, row: 379, col: 30}]); tmp1211 = _aether.createAPIClone(_aether, tmp1209[tmp1210]());  _aether.logStatement([{ofs: 12300, row: 379, col: 16}, {ofs: 12314, row: 379, col: 30}], _aether._userInfo, false);\n                                        _aether.logCallEnd(); return;\n                                    } else {\n                                        ;\n                                    }\n                                } else {\n                                    tmp1215 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n                                    tmp1216 = 'enemyHero';\n                                    _aether.logStatementStart([{ofs: 12380, row: 383, col: 16}, {ofs: 12394, row: 383, col: 30}]); tmp1214 = tmp1215[tmp1216];  _aether.logStatement([{ofs: 12380, row: 383, col: 16}, {ofs: 12394, row: 383, col: 30}], _aether._userInfo, false);\n                                    if (tmp1214) {\n                                        tmp1219 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n                                        tmp1220 = 'distance';\n                                        tmp1222 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n                                        tmp1223 = 'enemyHero';\n                                        _aether.logStatementStart([{ofs: 12412, row: 383, col: 48}, {ofs: 12426, row: 383, col: 62}]); tmp1221 = tmp1222[tmp1223];  _aether.logStatement([{ofs: 12412, row: 383, col: 48}, {ofs: 12426, row: 383, col: 62}], _aether._userInfo, false);\n                                        _aether.logStatementStart([{ofs: 12398, row: 383, col: 34}, {ofs: 12427, row: 383, col: 63}]); tmp1217 = _aether.createAPIClone(_aether, tmp1219[tmp1220](_aether.restoreAPIClone(_aether, tmp1221)));  _aether.logStatement([{ofs: 12398, row: 383, col: 34}, {ofs: 12427, row: 383, col: 63}], _aether._userInfo, false);\n                                        _aether.logStatementStart([{ofs: 12431, row: 383, col: 67}, {ofs: 12433, row: 383, col: 69}]); tmp1218 = 10;  _aether.logStatement([{ofs: 12431, row: 383, col: 67}, {ofs: 12433, row: 383, col: 69}], _aether._userInfo, false);\n                                        _aether.logStatementStart([{ofs: 12398, row: 383, col: 34}, {ofs: 12433, row: 383, col: 69}]); tmp1213 = tmp1217 >= tmp1218;  _aether.logStatement([{ofs: 12398, row: 383, col: 34}, {ofs: 12433, row: 383, col: 69}], _aether._userInfo, false);\n                                    } else {\n                                        _aether.logStatementStart([{ofs: 12380, row: 383, col: 16}, {ofs: 12433, row: 383, col: 69}]); tmp1213 = tmp1214;  _aether.logStatement([{ofs: 12380, row: 383, col: 16}, {ofs: 12433, row: 383, col: 69}], _aether._userInfo, false);\n                                    }\n                                    if (tmp1213) {\n                                        tmp1228 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n                                        tmp1229 = 'pos';\n                                        _aether.logStatementStart([{ofs: 12437, row: 383, col: 73}, {ofs: 12445, row: 383, col: 81}]); tmp1226 = tmp1228[tmp1229];  _aether.logStatement([{ofs: 12437, row: 383, col: 73}, {ofs: 12445, row: 383, col: 81}], _aether._userInfo, false);\n                                        tmp1227 = 'x';\n                                        _aether.logStatementStart([{ofs: 12437, row: 383, col: 73}, {ofs: 12447, row: 383, col: 83}]); tmp1224 = tmp1226[tmp1227];  _aether.logStatement([{ofs: 12437, row: 383, col: 73}, {ofs: 12447, row: 383, col: 83}], _aether._userInfo, false);\n                                        tmp1234 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n                                        tmp1235 = 'enemyHero';\n                                        _aether.logStatementStart([{ofs: 12450, row: 383, col: 86}, {ofs: 12464, row: 383, col: 100}]); tmp1232 = tmp1234[tmp1235];  _aether.logStatement([{ofs: 12450, row: 383, col: 86}, {ofs: 12464, row: 383, col: 100}], _aether._userInfo, false);\n                                        tmp1233 = 'pos';\n                                        _aether.logStatementStart([{ofs: 12450, row: 383, col: 86}, {ofs: 12468, row: 383, col: 104}]); tmp1230 = tmp1232[tmp1233];  _aether.logStatement([{ofs: 12450, row: 383, col: 86}, {ofs: 12468, row: 383, col: 104}], _aether._userInfo, false);\n                                        tmp1231 = 'x';\n                                        _aether.logStatementStart([{ofs: 12450, row: 383, col: 86}, {ofs: 12470, row: 383, col: 106}]); tmp1225 = tmp1230[tmp1231];  _aether.logStatement([{ofs: 12450, row: 383, col: 86}, {ofs: 12470, row: 383, col: 106}], _aether._userInfo, false);\n                                        _aether.logStatementStart([{ofs: 12437, row: 383, col: 73}, {ofs: 12470, row: 383, col: 106}]); tmp1212 = tmp1224 > tmp1225;  _aether.logStatement([{ofs: 12437, row: 383, col: 73}, {ofs: 12470, row: 383, col: 106}], _aether._userInfo, false);\n                                    } else {\n                                        _aether.logStatementStart([{ofs: 12380, row: 383, col: 16}, {ofs: 12470, row: 383, col: 106}]); tmp1212 = tmp1213;  _aether.logStatement([{ofs: 12380, row: 383, col: 16}, {ofs: 12470, row: 383, col: 106}], _aether._userInfo, false);\n                                    }\n                                    if (tmp1212) {\n                                        tmp1236 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n                                        tmp1237 = 'determineSayAndAction';\n                                        _aether.logStatementStart([{ofs: 12486, row: 384, col: 12}, {ofs: 12514, row: 384, col: 40}]); tmp1238 = _aether.createAPIClone(_aether, tmp1236[tmp1237]());  _aether.logStatement([{ofs: 12486, row: 384, col: 12}, {ofs: 12514, row: 384, col: 40}], _aether._userInfo, false);\n                                        tmp1239 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n                                        tmp1240 = 'terrifyTargets';\n                                        tmp1242 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n                                        tmp1243 = 'getTerrifyTargets';\n                                        _aether.logStatementStart([{ofs: 12528, row: 385, col: 12}, {ofs: 12575, row: 385, col: 59}]); tmp1241 = _aether.createAPIClone(_aether, tmp1242[tmp1243]());  _aether.logStatement([{ofs: 12528, row: 385, col: 12}, {ofs: 12575, row: 385, col: 59}], _aether._userInfo, false);\n                                        _aether.logStatementStart([{ofs: 12528, row: 385, col: 12}, {ofs: 12574, row: 385, col: 58}]); tmp1239[tmp1240] = tmp1241;  _aether.logStatement([{ofs: 12528, row: 385, col: 12}, {ofs: 12574, row: 385, col: 58}], _aether._userInfo, false);\n                                        tmp1244 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n                                        tmp1245 = 'terrify';\n                                        _aether.logStatementStart([{ofs: 12588, row: 386, col: 12}, {ofs: 12602, row: 386, col: 26}]); tmp1246 = _aether.createAPIClone(_aether, tmp1244[tmp1245]());  _aether.logStatement([{ofs: 12588, row: 386, col: 12}, {ofs: 12602, row: 386, col: 26}], _aether._userInfo, false);\n                                        _aether.logCallEnd(); return;\n                                    } else {\n                                        ;\n                                    }\n                                }\n                            }\n                        } else {\n                            tmp1247 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n                            tmp1248 = 'findTerrifyUnit';\n                            _aether.logStatementStart([{ofs: 12659, row: 391, col: 8}, {ofs: 12694, row: 391, col: 43}]); tUnit = _aether.createAPIClone(_aether, tmp1247[tmp1248]());  _aether.logStatement([{ofs: 12659, row: 391, col: 8}, {ofs: 12694, row: 391, col: 43}], _aether._userInfo, false);\n                            tmp1249 = tUnit;\n                            if (tmp1249) {\n                                tmp1250 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n                                tmp1251 = 'determineSayAndAction';\n                                _aether.logStatementStart([{ofs: 12727, row: 393, col: 12}, {ofs: 12755, row: 393, col: 40}]); tmp1252 = _aether.createAPIClone(_aether, tmp1250[tmp1251]());  _aether.logStatement([{ofs: 12727, row: 393, col: 12}, {ofs: 12755, row: 393, col: 40}], _aether._userInfo, false);\n                                tmp1253 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n                                tmp1254 = 'terrifyTargets';\n                                tmp1256 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n                                tmp1257 = 'getTerrifyTargets';\n                                _aether.logStatementStart([{ofs: 12769, row: 394, col: 12}, {ofs: 12816, row: 394, col: 59}]); tmp1255 = _aether.createAPIClone(_aether, tmp1256[tmp1257]());  _aether.logStatement([{ofs: 12769, row: 394, col: 12}, {ofs: 12816, row: 394, col: 59}], _aether._userInfo, false);\n                                _aether.logStatementStart([{ofs: 12769, row: 394, col: 12}, {ofs: 12815, row: 394, col: 58}]); tmp1253[tmp1254] = tmp1255;  _aether.logStatement([{ofs: 12769, row: 394, col: 12}, {ofs: 12815, row: 394, col: 58}], _aether._userInfo, false);\n                                tmp1258 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n                                tmp1259 = 'terrify';\n                                _aether.logStatementStart([{ofs: 12829, row: 395, col: 12}, {ofs: 12843, row: 395, col: 26}]); tmp1260 = _aether.createAPIClone(_aether, tmp1258[tmp1259]());  _aether.logStatement([{ofs: 12829, row: 395, col: 12}, {ofs: 12843, row: 395, col: 26}], _aether._userInfo, false);\n                                _aether.logCallEnd(); return;\n                            } else {\n                                ;\n                            }\n                        }\n                    }\n                }\n            }\n        } else {\n            ;\n        }\n        tmp1264 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n        tmp1265 = 'getCooldown';\n        _aether.logStatementStart([{ofs: 12925, row: 402, col: 20}, {ofs: 12933, row: 402, col: 28}]); tmp1266 = 'warcry';  _aether.logStatement([{ofs: 12925, row: 402, col: 20}, {ofs: 12933, row: 402, col: 28}], _aether._userInfo, false);\n        _aether.logStatementStart([{ofs: 12908, row: 402, col: 3}, {ofs: 12934, row: 402, col: 29}]); tmp1262 = _aether.createAPIClone(_aether, tmp1264[tmp1265](_aether.restoreAPIClone(_aether, tmp1266)));  _aether.logStatement([{ofs: 12908, row: 402, col: 3}, {ofs: 12934, row: 402, col: 29}], _aether._userInfo, false);\n        _aether.logStatementStart([{ofs: 12939, row: 402, col: 34}, {ofs: 12940, row: 402, col: 35}]); tmp1263 = 0;  _aether.logStatement([{ofs: 12939, row: 402, col: 34}, {ofs: 12940, row: 402, col: 35}], _aether._userInfo, false);\n        _aether.logStatementStart([{ofs: 12908, row: 402, col: 3}, {ofs: 12940, row: 402, col: 35}]); tmp1261 = tmp1262 === tmp1263;  _aether.logStatement([{ofs: 12908, row: 402, col: 3}, {ofs: 12940, row: 402, col: 35}], _aether._userInfo, false);\n        if (tmp1261) {\n            tmp1267 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n            tmp1268 = 'determineSayAndAction';\n            _aether.logStatementStart([{ofs: 12948, row: 403, col: 4}, {ofs: 12976, row: 403, col: 32}]); tmp1269 = _aether.createAPIClone(_aether, tmp1267[tmp1268]());  _aether.logStatement([{ofs: 12948, row: 403, col: 4}, {ofs: 12976, row: 403, col: 32}], _aether._userInfo, false);\n            tmp1270 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n            tmp1271 = 'warcry';\n            _aether.logStatementStart([{ofs: 12982, row: 404, col: 4}, {ofs: 12995, row: 404, col: 17}]); tmp1272 = _aether.createAPIClone(_aether, tmp1270[tmp1271]());  _aether.logStatement([{ofs: 12982, row: 404, col: 4}, {ofs: 12995, row: 404, col: 17}], _aether._userInfo, false);\n            _aether.logCallEnd(); return;\n        } else {\n            ;\n        }\n        tmp1273 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n        tmp1274 = 'determineSayAndAction';\n        _aether.logStatementStart([{ofs: 13012, row: 408, col: 0}, {ofs: 13040, row: 408, col: 28}]); tmp1275 = _aether.createAPIClone(_aether, tmp1273[tmp1274]());  _aether.logStatement([{ofs: 13012, row: 408, col: 0}, {ofs: 13040, row: 408, col: 28}], _aether._userInfo, false);\n        _aether.logCallEnd(); return;\n    };\n    tmp0 = 'chooseAction';\n    __global[tmp0] = tmp1;\n}(this));"
         },
         "programmable-librarian": {
-          "chooseAction": "..."
+          "chooseAction": "var __interceptThis=(function(){var G=this;return function($this,sandbox){if($this==G){return sandbox;}return $this;};})();\nreturn (function (__global) {\n    var tmp0, tmp1;\n    tmp1 = function () {\n        'use strict'; _aether.logCallStart(_aether._userInfo); var friends, enemies, enemy, friend, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8, tmp9, tmp10, tmp11, tmp12, tmp13, tmp14, tmp15, tmp16;  for(var __argIndexer = 0; __argIndexer < arguments.length; ++__argIndexer) arguments[__argIndexer] = _aether.createAPIClone(_aether, arguments[__argIndexer]);\n        _aether.logCallEnd(); return;\n        _aether.logCallEnd(); return;\n        tmp2 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n        tmp3 = 'getFriends';\n        _aether.logStatementStart([{ofs: 380, row: 8, col: 0}, {ofs: 412, row: 8, col: 32}]); friends = _aether.createAPIClone(_aether, tmp2[tmp3]());  _aether.logStatement([{ofs: 380, row: 8, col: 0}, {ofs: 412, row: 8, col: 32}], _aether._userInfo, false);\n        tmp4 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n        tmp5 = 'getEnemies';\n        _aether.logStatementStart([{ofs: 413, row: 9, col: 0}, {ofs: 445, row: 9, col: 32}]); enemies = _aether.createAPIClone(_aether, tmp4[tmp5]());  _aether.logStatement([{ofs: 413, row: 9, col: 0}, {ofs: 445, row: 9, col: 32}], _aether._userInfo, false);\n        tmp9 = enemies;\n        tmp10 = 'length';\n        _aether.logStatementStart([{ofs: 450, row: 10, col: 4}, {ofs: 464, row: 10, col: 18}]); tmp7 = tmp9[tmp10];  _aether.logStatement([{ofs: 450, row: 10, col: 4}, {ofs: 464, row: 10, col: 18}], _aether._userInfo, false);\n        _aether.logStatementStart([{ofs: 469, row: 10, col: 23}, {ofs: 470, row: 10, col: 24}]); tmp8 = 0;  _aether.logStatement([{ofs: 469, row: 10, col: 23}, {ofs: 470, row: 10, col: 24}], _aether._userInfo, false);\n        _aether.logStatementStart([{ofs: 450, row: 10, col: 4}, {ofs: 470, row: 10, col: 24}]); tmp6 = tmp7 === tmp8;  _aether.logStatement([{ofs: 450, row: 10, col: 4}, {ofs: 470, row: 10, col: 24}], _aether._userInfo, false);\n        if (tmp6) {\n            _aether.logCallEnd(); return;\n        } else {\n            ;\n        }\n        tmp11 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n        tmp12 = 'getNearest';\n        tmp13 = enemies;\n        _aether.logStatementStart([{ofs: 515, row: 11, col: 0}, {ofs: 552, row: 11, col: 37}]); enemy = _aether.createAPIClone(_aether, tmp11[tmp12](_aether.restoreAPIClone(_aether, tmp13)));  _aether.logStatement([{ofs: 515, row: 11, col: 0}, {ofs: 552, row: 11, col: 37}], _aether._userInfo, false);\n        tmp14 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n        tmp15 = 'getNearest';\n        tmp16 = friends;\n        _aether.logStatementStart([{ofs: 553, row: 12, col: 0}, {ofs: 591, row: 12, col: 38}]); friend = _aether.createAPIClone(_aether, tmp14[tmp15](_aether.restoreAPIClone(_aether, tmp16)));  _aether.logStatement([{ofs: 553, row: 12, col: 0}, {ofs: 591, row: 12, col: 38}], _aether._userInfo, false);\n    };\n    tmp0 = 'chooseAction';\n    __global[tmp0] = tmp1;\n}(this));"
         },
         "ogre-base": {
           "chooseAction": "if(!this.builtHero) {\n    //var hero = 'ironjaw';  // An unstoppable, jumping melee hero.\n    var hero = 'yugargen';  // A shrinking, growing, poisonous spellcaster.\n    this.builtHero = this.build(hero);\n    return;\n}\n\nvar enemies = this.getEnemies();\nvar buildOrder = null;\nvar nearest = null;\nvar nearestX = 0;\nvar enemy;\nvar inCommand = this.built[0].health <= 0 || this.built[0].action == 'move';\nvar hasHero = false;\nvar archerCount = 0;\nfor(var i = 0; i < enemies.length; ++i) {\n    enemy = enemies[i];\n    if(enemy.type == 'librarian') {\n        buildOrder = ['thrower', 'munchkin'];\n        this.say(\"Destroy \" + enemy.id, {target: enemy});\n        hasHero = true;\n        break;\n    }\n    if(enemy.type == 'knight') {\n        buildOrder = ['thrower', 'thrower', 'thrower', 'thrower', 'munchkin', 'thrower', 'thrower'];\n        if(enemy.action != 'shield' && (enemy.pos.x > 40 || enemy.health < 130)) {\n            this.say(\"Slay \" + enemy.id, {target: enemy});\n            hasHero = true;\n        }\n    }\n    if(enemy.type == 'archer')\n        ++archerCount;\n    if(enemy.pos.x > nearestX && (enemy.type != 'knight' || enemy.action != 'shield')) {\n        nearest = enemy;\n        nearestX = enemy.pos.x;\n    }\n}\nif(nearest && enemy != nearest && inCommand && hasHero) {\n    this.say(\"I guess let's fight kill \" + nearest.id, {target: nearest});\n}\nif(!buildOrder)\n    buildOrder = ['munchkin', 'thrower', 'munchkin'];\nif(archerCount > 1)\n    buildOrder = ['munchkin', 'thrower'];\nvar type = buildOrder[this.built.length % buildOrder.length];\nthis.build(type);\n"
@@ -567,294 +731,28 @@ responses =
           "chooseAction": "var enemies = this.getEnemies();\nvar enemy = this.getNearest(enemies);\nif(!enemy) return;\n\n\n\nif(this.now() < 12.00) {\n    //if(this.now() > 5 && this.now() < 8)\n    //    this.say(\"Move to\", {targetPos: {x: 76, y: 48}});\n    //else if(this.now() < 5)\n        this.say(\"Defend!\", {targetPos: {x: 60, y: 33}});\n    //this.say(\"Defend!\");\n\n    if(this.distance({x:enemy.pos.x, y:enemy.pos.y}) < 6)\n        this.attack(enemy);\n    else\n        this.move({x: 65, y: 32});\n    return;\n}\n\n\n\nthis.say(\"Attack!\");\nif(!this.getCooldown('stomp')) {\n    this.say(\"BaaaDOOOSH!!!\");\n    this.stomp();\n    return;\n}\nif(!this.getCooldown('throw') && enemy.type != 'soldier' && this.pos.x < 48) {\n    this.throw(enemy);\n    return;\n}\nfor(var i = 0; i < enemies.length; ++i) {\n    enemy = enemies[i];\n    if(this.distance(enemy) > 30) continue;\n    if (enemy.type === 'librarian' || enemy.type === 'tharin' || enemy.type === 'archer') {\n        if(!this.getCooldown('jump')) {\n            var diff = Vector.subtract(enemy.pos, this.pos);\n            diff = Vector.multiply(Vector.normalize(diff), 30);\n            var to = Vector.add(this.pos, diff);\n            this.jumpTo(to);\n            this.say(\"Obliterate \" + enemy.id, {target: enemy});\n        }\n        else if(!this.getCooldown('stomp')) {\n            this.say(\"BaDOOSH\");\n            this.stomp();\n        }\n        else {\n            this.attack(enemy);\n        }\n        return;\n    }\n}\n\nenemy = this.getNearest(enemies);\nif (enemy && this.distance(enemy) < 20) {\n    this.attack(enemy);\n}\nelse {\n    this.move({x: 10, y: 30});\n}"
         }
       },
+      "teamSpells": {
+        "ogres": [
+          "programmable-brawler/chooseAction",
+          "programmable-shaman/chooseAction",
+          "ogre-base/chooseAction"
+        ],
+        "humans": [
+          "programmable-librarian/chooseAction",
+          "programmable-tharin/chooseAction",
+          "human-base/chooseAction"
+        ]
+      },
       "submittedCodeLanguage": "javascript",
       "playtime": 1786,
       "codeLanguage": "javascript"
     }
   ]
 
-employersResponse = [
-  {
-    "_id": "52af5b805c813fc5b9000006",
-    "levelID": "gridmancer",
-    "levelName": "Gridmancer",
-    "code": {
-      "captain-anya": {
-        "plan": "// Fill the empty space with the minimum number of rectangles.\nvar grid = this.getNavGrid().grid;\nvar tileSize = 4;\nvar rects = {};\n\nfunction coordString(x, y) { return x+','+y; }\nfunction fourRectsHere(x, y) { return rects[coordString(x-tileSize,y)] && rects[coordString(x,y-tileSize)] && rects[coordString(x-tileSize,y-tileSize)] && rects[coordString(x,y)]; }\n\nfor(var y = 0; y < grid.length; y += tileSize) {\n    for(var x = 0; x < grid[0].length; x += tileSize) {\n        var occupied = grid[y][x].length > 0;\n        if(!occupied) {\n            var xcord = x + tileSize / 2;\n            var ycord = y + tileSize / 2;\n            this.addRect(xcord, ycord, tileSize, tileSize);\n            rects[coordString(xcord,ycord)] = true;\n            var coord = coordString(xcord,ycord);\n            // this.say(coord);\n            if (fourRectsHere(xcord,ycord)) {\n                delete rects[coordString(xcord,ycord)];\n                delete rects[coordString(xcord-tileSize, ycord)];\n                delete rects[coordString(xcord-tileSize, ycord-tileSize)];\n                delete rects[coordString(xcord, ycord-tileSize)];\n                this.removeRect(xcord, ycord);\n                this.removeRect(xcord - tileSize, ycord);\n                this.removeRect(xcord, ycord - tileSize);\n                this.removeRect(xcord - tileSize, ycord - tileSize);\n                this.addRect(x, y, tileSize*2, tileSize*2);\n            }\n            this.wait(0.1);\n        }\n    }\n}\n"
-      },
-      "thoktar": {
-        "plan": "# Fill the empty space with the minimum number of rectangles.\n# (Rectangles should not overlap each other or walls.)\n# The grid size is 1 meter, but the smallest wall/floor tile is 4 meters.\n# Check the blue guide button at the top for more info.\n# Make sure to sign up on the home page to save your code.\n\ngrid = self.getNavGrid().grid\ntileSize = 4\nfor y in range(0,grid.length,tileSize):\n    for x in range(0,grid[0].length,tileSize):\n        occupied = grid[y][x].length > 0\n        if not occupied:\n            self.addRect(x + tileSize / 2, y + tileSize / 2, tileSize, tileSize)\n            self.wait()  # Hover over the timeline to help debug!\n\n\n"
-      }
-    },
-    "submittedCodeLanguage": "javascript",
-    "playtime": 138,
-    "codeLanguage": "python"
-  },
-  {
-    "_id": "53026594cd9f9595b818d651",
-    "team": "me",
-    "levelID": "brawlwood",
-    "levelName": "Brawlwood",
-    "submitted": false,
-    "code": {
-      "programmable-artillery": {
-        "chooseAction": "// This code is shared across all your Artillery.\n// Artillery are expensive, slow, and deadly, with high\n// area-of-effect damage that hurts foes and friends alike.\n\nvar targetEnemy, enemy;\nvar enemies = this.getEnemies();\nfor(var i = 0; i < enemies.length; ++i) {\n    enemy = enemies[i];\n    if(enemy.type === 'munchkin') {\n        targetEnemy = enemy;\n        break;\n    }\n}\n\nif(!targetEnemy)\n    targetEnemy = this.getNearestEnemy();\nif(targetEnemy)\n    this.attackXY(targetEnemy.pos.x, targetEnemy.pos.y);\nelse\n    this.move({x: 70, y: 70});",
-        "hear": "// When the artillery hears a say() message, this hear() method will be called.\nif(speaker.team !== this.team) return;\n\n// You can add code to respond to the message here."
-      },
-      "programmable-soldier": {
-        "chooseAction": "// This code is shared across all your Soldiers.\n// Soldiers are low damage, high health melee units.\n\nvar enemy = this.getNearestEnemy();\nif(enemy && enemy.type != 'burl')\n    this.attack(enemy);\nelse {\n    this.move({x: 70, y: 70});\n}",
-        "hear": "// When the soldier hears a say() message, this hear() method will be called.\nif(speaker.team !== this.team) return;\n\n// You can add code to respond to the message here."
-      },
-      "s-arrow-tower": {
-        "chooseAction": "// This code is shared by both your Arrow Towers.\n// Don't let your towers die lest the ogres claim 250 gold!\n\nvar enemy = this.getNearestEnemy();\nif(enemy && this.distance(enemy) < this.attackRange) {\n    this.say(\"Die, \" + enemy.id + \".\");\n    this.attack(enemy);\n}"
-      },
-      "programmable-archer": {
-        "chooseAction": "// This code is shared across all your Archers.\n// Archers are vulnerable but deadly ranged units.\n\nvar enemy = this.getNearestEnemy();\nif(enemy) {\n    this.attack(enemy);\n}\nelse\n    this.move({x: 70, y: 70});",
-        "hear": "// When the archer hears a say() message, this hear() method will be called.\nif(speaker.team !== this.team) return;\n\n// You can add code to respond to the message here."
-      },
-      "human-base": {
-        "chooseAction": "// This is the code for your base. Decide which unit to build each frame.\n// Units you build will go into the this.built array.\n// If you don't have enough gold, this.build() won't build anything.\n// You start with 100 gold and receive 2 gold per second.\n// Kill enemies, especially towers and brawlers, to earn more gold.\n// Destroy the enemy base within 90 seconds!\n\nvar type = 'soldier';\nif(this.built.length === 4)\n    type = 'artillery';\nelse if(this.built.length % 3 === 1)\n    type = 'archer';\n\n// if(this.gold >= this.buildables[type].goldCost) {\n    //this.say('Unit #' + this.built.length + ' will be a ' + type);\n    this.build(type);\n// }",
-        "hear": "// When the base hears a say() message, this hear() method will be called.\nif(speaker.team !== this.team) return;\n\n// You can add code to respond to the message here."
-      }
-    },
-    "submittedCodeLanguage": "javascript",
-    "playtime": 0,
-    "codeLanguage": "javascript"
-  },
-  {
-    "_id": "5317530cc269d400000543c7",
-    "submitted": false,
-    "code": {
-      "muul": {
-        "chooseAction": "..."
-      },
-      "nazgareth": {
-        "chooseAction": "// Shamans are spellcasters with a weak magic attack\n// plus two useful spells: 'regen' and 'shrink'.\n\nvar enemy = this.getNearestEnemy();\nif (!enemy)\n    this.move({x: 10, y: 25});\nelse if (!enemy.hasEffect('shrink')) {\n    this.castShrink(enemy);\n    if(this.distance(enemy) <= 30)\n        this.say(\"Shrink, vile \" + enemy.type + \" \" + enemy.id);\n}\nelse {\n    this.attack(enemy);\n}"
-      },
-      "ironjaw": {
-        "chooseAction": "var enemies = this.getEnemies();\nvar enemy = this.getNearest(enemies);\nif (enemy) {\n    if(!this.getCooldown('jump')) {\n        this.jumpTo(enemy.pos);\n        this.say(\"Hi \" + enemy.type + \" \" + enemy.id);\n    }\n    else {\n        this.attack(enemy);\n    }\n}\nelse {\n    this.move({x: 10, y: 30});\n}"
-      },
-      "programmable-shaman": {
-        "hear": "// When the shaman hears a say() message, this hear() method will be called.\nif(speaker.team !== this.team) return;\n\n// You can add code to respond to the message here.",
-        "chooseAction": "// This code is shared across all your Shamans.\n// Shamans are expensive spellcasters with a weak magic attack\n// plus two crippling spells: 'slow' and 'shrink'.\n\nvar enemy = this.getNearestEnemy();\nif (!enemy)\n    this.move({x: 10, y: 10});\nelse if (!enemy.hasEffect('shrink')) {\n    this.castShrink(enemy);\n    if(this.distance(enemy) <= 30)\n        this.say(\"Shrink, vile \" + enemy.type + \" \" + enemy.id);\n}\nelse {\n    this.attack(enemy);\n}"
-      },
-      "programmable-thrower": {
-        "hear": "// When the thrower hears a say() message, this hear() method will be called.\nif(speaker.team !== this.team) return;\n\n// You can add code to respond to the message here.",
-        "chooseAction": "// This code is shared across all your Throwers.\n// You can use this.buildIndex to have Throwers do different things.\n// Throwers are vulnerable but deadly ranged units.\n\nvar enemy = this.getNearestEnemy();\nif (enemy) {\n    this.attack(enemy);\n}\nelse {\n    this.move({x: 10, y: 10});\n}"
-      },
-      "programmable-munchkin": {
-        "hear": "// When the munchkin hears a say() message, this hear() method will be called.\nif(speaker.team !== this.team) return;\n\n// You can add code to respond to the message here.",
-        "chooseAction": "// This code is shared across all your Munchkins.\n// You can use this.buildIndex to have Munchkins do different things.\n// Munchkins are weak but cheap, fast melee units.\n\nvar enemy = this.getNearestEnemy();\nif (enemy && enemy.type !== 'burl') {\n    this.attack(enemy);\n}\nelse {\n    this.move({x: 10, y: 10});\n}"
-      },
-      "ogre-base": {
-        "hear": "// When the base hears a say() message, this hear() method will be called.\nif(speaker.team !== this.team) return;\n\n// You can add code to respond to the message here.",
-        "chooseAction": "// This is the code for your base. Decide which unit to build each frame.\n// Units you build will go into the this.built array.\n// Destroy the enemy base within 90 seconds!\n// Check out the Guide at the top for more info.\n\nif(!this.builtHero) {\n    // Choose your hero!\n    // var heroType = 'brawler';\n    var heroType = 'shaman';\n    this.builtHero = this.build(heroType);\n    return;\n}\n\nvar buildOrder = ['munchkin', 'munchkin', 'thrower'];\nvar type = buildOrder[this.built.length % buildOrder.length];\n//this.say('Unit #' + this.built.length + ' will be a ' + type);\nthis.build(type);"
-      },
-      "poult": {
-        "chooseAction": "// Shamans are spellcasters with a weak magic attack\n// plus two useful spells: 'regen' and 'shrink'.\n\nvar enemy = this.getNearestEnemy();\nif (!enemy)\n    this.move({x: 10, y: 25});\nelse if (!enemy.hasEffect('shrink')) {\n    this.castShrink(enemy);\n    if(this.distance(enemy) <= 30)\n        this.say(\"Shrink, vile \" + enemy.type + \" \" + enemy.id);\n}\nelse {\n    this.attack(enemy);\n}"
-      },
-      "aoliantak": {
-        "chooseAction": "..."
-      },
-      "programmable-brawler": {
-        "chooseAction": "var enemies = this.getEnemies();\nvar enemy = this.getNearest(enemies);\nif (enemy) {\n    if(!this.getCooldown('jump')) {\n        this.jumpTo(enemy.pos);\n        this.say(\"Hi \" + enemy.type + \" \" + enemy.id);\n    }\n    else {\n        this.attack(enemy);\n    }\n}\nelse {\n    this.move({x: 10, y: 30});\n}"
-      }
-    },
-    "levelID": "dungeon-arena",
-    "levelName": "Dungeon Arena",
-    "submittedCodeLanguage": "javascript",
-    "playtime": 0,
-    "codeLanguage": "javascript"
-  },
-  {
-    "_id": "5358429413f1278605f03ab8",
-    "team": "ogres",
-    "levelID": "greed",
-    "levelName": "Greed",
-    "code": {
-      "ogre-base": {
-        "chooseAction": "// This code runs once per frame. Build units and command peons!\n// Destroy the human base within 180 seconds.\n// Run over 4000 statements per call and chooseAction will run less often.\n// Check out the green Guide button at the top for more info.\n\nvar base = this;\n\n/////// 1. Command peons to grab coins and gems. ///////\n// You can only command peons, not fighting units.\n// You win by gathering gold more efficiently to make a larger army.\n// Click on a unit to see its API.\nvar items = base.getItems();\nvar peons = base.getByType('peon');\nfor (var peonIndex = 0; peonIndex < peons.length; peonIndex++) {\n    var peon = peons[peonIndex];\n    var item = peon.getNearest(items);\n    if (item)\n        base.command(peon, 'move', item.pos);\n}\n\n\n/////// 2. Decide which unit to build this frame. ///////\n// Peons can gather gold; other units auto-attack the enemy base.\n// You can only build one unit per frame, if you have enough gold.\nvar type;\nif (base.built.length === 0)\n    type = 'peon';\nelse\n    type = 'ogre';\nif (base.gold >= base.buildables[type].goldCost)\n    base.build(type);\n\n\n// 'peon': Peons gather gold and do not fight.\n// 'munchkin': Light melee unit.\n// 'ogre': Heavy melee unit.\n// 'shaman': Support spellcaster.\n// 'fangrider': High damage ranged attacker.\n// 'brawler': Mythically expensive super melee unit.\n// See the buildables documentation below for costs and the guide for more info."
-      },
-      "well": {
-        "chooseAction": "if(!this.inventorySystem) this.inventorySystem = this.world.getSystem('Inventory');\n// Cap at 120 coins for rendering performance reasons.\n// As many as ~420 by stalemate with default code, but one greedy collector -> ~70 tops.\nif(this.inventorySystem.collectables.length < 120) {\n    var x = Math.random();\n    var type = 'silver';\n    if (x < 0.05) type = 'gem';\n    else if (x < 0.15) type = 'gold';\n    else if (x < 0.35) type = 'copper';\n    this.build(type);\n}\n\nif(!this.causeFall) this.causeFall = function causeFall(target) {\n    target.addEffect({name: 'fall', duration: 1.5, reverts: false, factor: 0.1, targetProperty: 'scaleFactor'}, this);\n    target.maxAcceleration = 0;\n    target.addCurrentEvent('fall');\n    target.fellAt = this.now();\n};\n\nfor (var i = 0; i < this.inventorySystem.collectors.length; ++i) {\n    var thang = this.inventorySystem.collectors[i];\n    if ((thang.type == 'peasant' || thang.type == 'peon') &&\n        (thang.pos.x < -3 || thang.pos.x > 88 || thang.pos.y < -5 || thang.pos.y > 80)) {\n        if (thang.maxAcceleration)\n            this.causeFall(thang);\n        else if (thang.fellAt && thang.fellAt + 1.25 < this.now()) {\n            thang.setExists(false);\n            thang.fellAt = null;\n        }\n    }\n}"
-      }
-    },
-    "totalScore": 16.724090931727677,
-    "submitted": true,
-    "submittedCodeLanguage": "javascript",
-    "playtime": 3837,
-    "codeLanguage": "javascript"
-  },
-  {
-    "_id": "53177f6da508f6e7b3463fef",
-    "team": "humans",
-    "levelID": "dungeon-arena",
-    "levelName": "Dungeon Arena",
-    "submitted": true,
-    "totalScore": 11.782554190268042,
-    "code": {
-      "hushbaum-1": {
-        "chooseAction": "..."
-      },
-      "librarian": {
-        "chooseAction": "..."
-      },
-      "tharin-1": {
-        "chooseAction": "var friends = this.getFriends();\nvar nearest = this.getNearest(friends);\nif(this.distance(nearest) > 5) {\n    this.move(nearest.pos);\n}\nelse {\n    this.warcry();\n}"
-      },
-      "hushbaum": {
-        "chooseAction": "var enemy = this.getNearestEnemy();\nif (enemy) {\n    if (!enemy.hasEffect('slow')) {\n        this.say(\"Not so fast, \" + enemy.type + \" \" + enemy.id);\n        this.castSlow(enemy);\n    }\n    else {\n        this.attack(enemy);\n    }\n}\nelse {\n    this.move({x: 70, y: 30});\n}\n"
-      },
-      "anya": {
-        "chooseAction": "var enemy = this.getNearestEnemy();\nif (enemy)\n    this.attack(enemy);"
-      },
-      "tharin": {
-        "chooseAction": "var enemies = this.getEnemies();\nvar enemy = this.getNearest(enemies);\nif (!this.getCooldown('warcry')) {\n    this.warcry();\n}\nelse if (enemy) {\n    this.attack(enemy);\n}\nelse {\n    this.move({x: 10, y: 30});\n}\n"
-      },
-      "programmable-librarian": {
-        "chooseAction": "// The Librarian is a spellcaster with a fireball attack\n// plus three useful spells: 'slow', 'regen', and 'haste'.\n// Slow makes a target move and attack at half speed for 5s.\n// Regen makes a target heal 10 hp/s for 10s.\n// Haste speeds up a target by 4x for 5s, once per match.\n\nvar friends = this.getFriends();\nvar enemies = this.getEnemies();\nif (enemies.length === 0) return;  // Chill if all enemies are dead.\nvar enemy = this.getNearest(enemies);\nvar friend = this.getNearest(friends);\n\n// Which one do you do at any given time? Only the last called action happens.\n//if(this.canCast('slow', enemy)) this.castSlow(enemy);\n//if(this.canCast('regen', friend)) this.castRegen(friend);\n//if(this.canCast('haste', friend)) this.castHaste(friend);\n//this.attack(enemy);\n\n// You can also command your troops with this.say():\n//this.say(\"Defend!\", {targetPos: {x: 30, y: 30}}));\n//this.say(\"Attack!\", {target: enemy});\n//this.say(\"Move!\", {targetPos: {x: 50, y: 40});"
-      },
-      "programmable-tharin": {
-        "chooseAction": "// Tharin is a melee fighter with shield, warcry, and terrify skills.\n// this.shield() lets him take one-third damage while defending.\n// this.warcry() gives allies within 10m 30% haste for 5s, every 10s.\n// this.terrify() sends foes within 30m fleeing for 5s, once per match.\n\nvar friends = this.getFriends();\nvar enemies = this.getEnemies();\nif (enemies.length === 0) return;  // Chill if all enemies are dead.\nvar enemy = this.getNearest(enemies);\nvar friend = this.getNearest(friends);\n\n// Which one do you do at any given time? Only the last called action happens.\n//if(!this.getCooldown('warcry')) this.warcry();\n//if(!this.getCooldown('terrify')) this.terrify();\n//this.shield();\n//this.attack(enemy);\n\n// You can also command your troops with this.say():\n//this.say(\"Defend!\", {targetPos: {x: 30, y: 30}}));\n//this.say(\"Attack!\", {target: enemy});\n//this.say(\"Move!\", {targetPos: {x: 40, y: 40});\n\n// You can store state on this across frames:\n//this.lastHealth = this.health;"
-      },
-      "human-base": {
-        "chooseAction": "// This is the code for your base. Decide which unit to build each frame.\n// Units you build will go into the this.built array.\n// Destroy the enemy base within 60 seconds!\n// Check out the Guide at the top for more info.\n\n// CHOOSE YOUR HERO! You can only build one hero.\nvar hero;\n//hero = 'tharin';  // A fierce knight with battlecry abilities.\n//hero = 'hushbaum';  // A fiery spellcaster hero.\n\nif(hero && !this.builtHero) {\n    this.builtHero = this.build(hero);\n    return;\n}\n\n// Soldiers are hard-to-kill, low damage melee units with 2s build cooldown.\n// Archers are fragile but deadly ranged units with 2.5s build cooldown.\nvar buildOrder = ['soldier', 'archer', 'soldier', 'soldier', 'archer'];\nvar type = buildOrder[this.built.length % buildOrder.length];\n//this.say('Unit #' + this.built.length + ' will be a ' + type);\nthis.build(type);"
-      }
-    },
-    "submittedCodeLanguage": "javascript",
-    "playtime": 1,
-    "codeLanguage": "javascript"
-  },
-  {
-    "_id": "5318b6aa7aeef7843bba3357",
-    "team": "ogres",
-    "levelID": "dungeon-arena",
-    "levelName": "Dungeon Arena",
-    "submitted": true,
-    "totalScore": 34.28623946920249,
-    "code": {
-      "human-base": {
-        "chooseAction": "// This is the code for your base. Decide which unit to build each frame.\n// Units you build will go into the this.built array.\n// Destroy the enemy base within 60 seconds!\n// Check out the Guide at the top for more info.\n\n// CHOOSE YOUR HERO! You can only build one hero.\nvar hero;\nhero = 'tharin';  // A fierce knight with battlecry abilities.\n//hero = 'hushbaum';  // A fiery spellcaster hero.\n\nif(hero && !this.builtHero) {\n    this.builtHero = this.build(hero);\n    return;\n}\n\n// Soldiers are hard-to-kill, low damage melee units with 2s build cooldown.\n// Archers are fragile but deadly ranged units with 2.5s build cooldown.\nvar type;\nif (this.built.length > 50) {\n    type = this.built.length & 1 ? 'archer' : 'soldier';\n} else {\n    type = 'soldier';\n}\n//this.say('Unit #' + this.built.length + ' will be a ' + type);\nthis.build(type);"
-      },
-      "programmable-tharin": {
-        "chooseAction": "var enemies = this.getEnemies();\nvar target = enemies[0];\n\nif (this.now() < 0.2) {\n    this.attack(target);\n    this.say(\"attack\", {target: target});\n    return;\n}\n\nthis.say(\"attack\", {target: target});\nthis.attack(target);\nif (this.pos.x > 40 && !this.getCooldown('terrify')) {\n    this.terrify();\n    return;\n} else if (!this.getCooldown('warcry')) {\n    this.warcry();\n}\nthis.say(\"attack\", {target: target});"
-      },
-      "programmable-librarian": {
-        "chooseAction": "// The Librarian is a spellcaster with a fireball attack\n// plus three useful spells: 'slow', 'regen', and 'haste'.\n// Slow makes a target move and attack at half speed for 5s.\n// Regen makes a target heal 10 hp/s for 10s.\n// Haste speeds up a target by 4x for 5s, once per match.\n\nvar friends = this.getFriends();\nvar enemies = this.getEnemies();\nif (enemies.length === 0) return;  // Chill if all enemies are dead.\nvar enemy = this.getNearest(enemies);\nvar friend = this.getNearest(friends);\n\n// Which one do you do at any given time? Only the last called action happens.\n//if(this.canCast('slow', enemy)) this.castSlow(enemy);\n//if(this.canCast('regen', friend)) this.castRegen(friend);\n//if(this.canCast('haste', friend)) this.castHaste(friend);\n//this.attack(enemy);\n\n// You can also command your troops with this.say():\n//this.say(\"Defend!\", {targetPos: {x: 30, y: 30}}));\n//this.say(\"Attack!\", {target: enemy});\n//this.say(\"Move!\", {targetPos: {x: 50, y: 40});"
-      },
-      "programmable-shaman": {
-        "chooseAction": "// Shamans are spellcasters with a weak magic attack\n// and three spells: 'shrink', 'grow', and 'poison-cloud'.\n// Shrink: target has 2/3 health, 1.5x speed for 5s.\n// Grow: target has double health, half speed for 5s.\n// Once per match, she can cast poison cloud, which does\n// 5 poison dps for 10s to enemies in a 10m radius.\n\nvar friends = this.getFriends();\nvar enemies = this.getEnemies();\nif (enemies.length === 0) return;  // Chill if all enemies are dead.\nvar enemy = this.getNearest(enemies);\nvar friend = this.getNearest(friends);\n\n// Which one do you do at any given time? Only the last called action happens.\nif(this.canCast('shrink', enemy)) this.castShrink(enemy);\n// if(this.canCast('grow', friend)) this.castGrow(friend);\n//if(this.canCast('poison-cloud', enemy)) this.castPoisonCloud(enemy);\n// this.attack(enemy);\n\n// You can also command your troops with this.say():\n//this.say(\"Defend!\", {targetPos: {x: 60, y: 30}}));\n//this.say(\"Attack!\", {target: enemy});\n//this.say(\"Move!\", {targetPos: {x: 50, y: 40}); "
-      },
-      "programmable-brawler": {
-        "chooseAction": "// The Brawler is a huge melee hero with mighty mass.\n// this.throw() hurls an enemy behind him.\n// this.jumpTo() leaps to a target within 20m every 10s.\n// this.stomp() knocks everyone away, once per match.\n\nvar friends = this.getFriends();\nvar enemies = this.getEnemies();\nif (enemies.length === 0) return;  // Chill if all enemies are dead.\nvar enemy = this.getNearest(enemies);\nvar friend = this.getNearest(friends);\n\n// Which one do you do at any given time? Only the last called action happens.\nif(!this.getCooldown('jump')) this.jumpTo(enemy.pos);\n// if(!this.getCooldown('stomp')) return this.stomp();\n// if(!this.getCooldown('throw')) this.throw(enemy);\n// this.attack(enemy);\n\n// You can also command your troops with this.say():\n//this.say(\"Defend!\", {targetPos: {x: 60, y: 30}}));\n//this.say(\"Attack!\", {target: enemy});\n//this.say(\"Move!\", {targetPos: {x: 50, y: 40});\n\n// You can store state on this across frames:\n//this.lastHealth = this.health;"
-      },
-      "ironjaw": {
-        "chooseAction": "// var enemies = this.getEnemies();\n// var enemy = this.getNearest(enemies);\n// if (enemy) {\n//     if(!this.getCooldown('jump')) {\n//         this.jumpTo(enemy.pos);\n//         this.say(\"Hi \" + enemy.type + \" \" + enemy.id);\n//     }\n//     else {\n//         this.attack(enemy);\n//     }\n// }\n// else {\n//     this.move({x: 10, y: 30});\n// }"
-      },
-      "nazgareth": {
-        "chooseAction": "// // Shamans are spellcasters with a weak magic attack\n// // plus two useful spells: 'regen' and 'shrink'.\n\n// var enemy = this.getNearestEnemy();\n// if (!enemy)\n//     this.move({x: 10, y: 25});\n// else if (!enemy.hasEffect('shrink')) {\n//     this.castShrink(enemy);\n//     if(this.distance(enemy) <= 30)\n//         this.say(\"Shrink, vile \" + enemy.type + \" \" + enemy.id);\n// }\n// else {\n//     this.attack(enemy);\n// }"
-      },
-      "ogre-base": {
-        "chooseAction": "// This is the code for your base. Decide which unit to build each frame.\n// Units you build will go into the this.built array.\n// Destroy the enemy base within 60 seconds!\n// Check out the Guide at the top for more info.\n\n// Choose your hero! You can only build one hero.\nvar hero;\n// hero = 'ironjaw';  // A leaping juggernaut hero, type 'brawler'.\nhero = 'yugargen';  // A devious spellcaster hero, type 'shaman'.\nif(hero && !this.builtHero) {\n    this.builtHero = this.build(hero);\n    return;\n}\n\n// Munchkins are weak melee units with 1.25s build cooldown.\n// Throwers are fragile, deadly ranged units with 2.5s build cooldown.\nvar buildOrder = ['munchkin', 'munchkin', 'munchkin', 'thrower'];\nvar type = buildOrder[this.built.length % buildOrder.length];\n//this.say('Unit #' + this.built.length + ' will be a ' + type);\nthis.build(type);"
-      },
-      "muul": {
-        "chooseAction": "..."
-      }
-    },
-    "submittedCodeLanguage": "javascript",
-    "playtime": 0,
-    "codeLanguage": "javascript"
-  },
-  {
-    "_id": "52fd11c8e5c2b9000060bd48",
-    "team": "ogres",
-    "levelID": "brawlwood",
-    "levelName": "Brawlwood",
-    "submitted": true,
-    "totalScore": -10.697956636178176,
-    "code": {
-      "ogre-base": {
-        "hear": "// When the base hears a say() message, this hear() method will be called.\nif(speaker.team !== this.team) return;\n\n// You can add code to respond to the message here.",
-        "chooseAction": "// This is the code for your base. Decide which unit to build each frame.\n// Units you build will go into the this.built array.\n// If you don't have enough gold, this.build() won't build anything.\n// You start with 100 gold and receive 2 gold per second.\n// Kill enemies, especially towers and brawlers, to earn more gold.\n// Destroy the enemy base within 90 seconds!\n// Check out the Guide just up and to the left for more info.\n\n// var type = 'munchkin';\n// if(this.built.length % 5 === 3)\n    type = 'shaman';\n// else if(this.built.length % 3 === 1)\n//     type = 'thrower';\n\n//this.say('Unit #' + this.built.length + ' will be a ' + type);\nthis.build(type);\n"
-      },
-      "programmable-munchkin": {
-        "hear": "// When the munchkin hears a say() message, this hear() method will be called.\nif(speaker.team !== this.team) return;\n\n// You can add code to respond to the message here.",
-        "chooseAction": "// This code is shared across all your Munchkins.\n// You can use this.buildIndex to have Munchkins do different things.\n// Munchkins are weak but cheap, fast melee units.\n\nvar enemy = this.getNearestEnemy();\nif (enemy && enemy.type !== 'burl') {\n    this.attack(enemy);\n}\nelse {\n    this.move({x: 10, y: 10});\n}"
-      },
-      "programmable-thrower": {
-        "hear": "// When the thrower hears a say() message, this hear() method will be called.\nif(speaker.team !== this.team) return;\n\n// You can add code to respond to the message here.",
-        "chooseAction": "// This code is shared across all your Throwers.\n// You can use this.buildIndex to have Throwers do different things.\n// Throwers are vulnerable but deadly ranged units.\n\nvar enemy = this.getNearestEnemy();\nif (enemy) {\n    this.attack(enemy);\n}\nelse {\n    this.move({x: 10, y: 10});\n}"
-      },
-      "n-beam-tower": {
-        "chooseAction": "// This code is shared by both your Beam Towers.\n// Don't let your towers die lest the humans claim 250 gold!\n// You probably don't need to change this basic strategy.\n\nvar enemy = this.getNearestEnemy();\nif (enemy && this.distance(enemy) < this.attackRange) {\n    this.say(\"Die, \" + enemy.id + \"!\");\n    this.attack(enemy);\n}"
-      },
-      "programmable-shaman": {
-        "hear": "// When the shaman hears a say() message, this hear() method will be called.\nif(speaker.team !== this.team) return;\n\n// You can add code to respond to the message here.",
-        "chooseAction": "// This code is shared across all your Shamans.\n// Shamans are expensive spellcasters with a weak magic attack\n// plus two crippling spells: 'slow' and 'shrink'.\n\nvar enemy = this.getNearestEnemy();\nif (!enemy)\n    this.move({x: 10, y: 10});\nelse if (!enemy.hasEffect('shrink')) {\n    this.castShrink(enemy);\n    if(this.distance(enemy) <= 30)\n        this.say(\"Shrink, vile \" + enemy.type + \" \" + enemy.id);\n}\nelse {\n    this.attack(enemy);\n}"
-      }
-    },
-    "submittedCodeLanguage": "javascript",
-    "playtime": 0,
-    "codeLanguage": "javascript"
-  },
-  {
-    "_id": "53570b7a1bfa9bba14b5e045",
-    "team": "humans",
-    "levelID": "greed",
-    "levelName": "Greed",
-    "code": {
-      "well": {
-        "chooseAction": "if(!this.inventorySystem) this.inventorySystem = this.world.getSystem('Inventory');\n// Cap at 120 coins for rendering performance reasons.\n// As many as ~420 by stalemate with default code, but one greedy collector -> ~70 tops.\nif(this.inventorySystem.collectables.length < 120) {\n    var x = Math.random();\n    var type = 'silver';\n    if (x < 0.05) type = 'gem';\n    else if (x < 0.15) type = 'gold';\n    else if (x < 0.35) type = 'copper';\n    this.build(type);\n}\n\nif(!this.causeFall) this.causeFall = function causeFall(target) {\n    target.addEffect({name: 'fall', duration: 1.5, reverts: false, factor: 0.1, targetProperty: 'scaleFactor'}, this);\n    target.maxAcceleration = 0;\n    target.addCurrentEvent('fall');\n    target.fellAt = this.now();\n};\n\nfor (var i = 0; i < this.inventorySystem.collectors.length; ++i) {\n    var thang = this.inventorySystem.collectors[i];\n    if ((thang.type == 'peasant' || thang.type == 'peon') &&\n        (thang.pos.x < -3 || thang.pos.x > 88 || thang.pos.y < -5 || thang.pos.y > 80)) {\n        if (thang.maxAcceleration)\n            this.causeFall(thang);\n        else if (thang.fellAt && thang.fellAt + 1.25 < this.now()) {\n            thang.setExists(false);\n            thang.fellAt = null;\n        }\n    }\n}"
-      },
-      "human-base": {
-        "chooseAction": "// This code runs once per frame. Build units and command peons!\n// Destroy the human base within 180 seconds.\n// Run over 4000 statements per call and chooseAction will run less often.\n// Check out the green Guide button at the top for more info.\n\nvar base = this;\n\n/////// 1. Command peons to grab coins and gems. ///////\n// You can only command peons, not fighting units.\n// You win by gathering gold more efficiently to make a larger army.\n// Click on a unit to see its API.\nvar items = base.getItems();\nvar peons = base.getByType('peasant');\nfor (var peonIndex = 0; peonIndex < peons.length; peonIndex++) {\n    var peon = peons[peonIndex];\n    var item = peon.getNearest(items);\n    if (item)\n        base.command(peon, 'move', item.pos);\n}\n\n\n/////// 2. Decide which unit to build this frame. ///////\n// Peons can gather gold; other units auto-attack the enemy base.\n// You can only build one unit per frame, if you have enough gold.\nvar type;\nif (base.built.length === 0)\n    type = 'peasant';\nelse\n    type = 'soldier';\nif (base.gold >= base.buildables[type].goldCost)\n    base.build(type);\n\n\n// 'peon': Peons gather gold and do not fight.\n// 'munchkin': Light melee unit.\n// 'ogre': Heavy melee unit.\n// 'shaman': Support spellcaster.\n// 'fangrider': High damage ranged attacker.\n// 'brawler': Mythically expensive super melee unit.\n// See the buildables documentation below for costs and the guide for more info."
-      }
-    },
-    "submitted": true,
-    "totalScore": 29.46867296924995,
-    "submittedCodeLanguage": "javascript",
-    "playtime": 6295,
-    "codeLanguage": "javascript"
-  },
-  {
-    "_id": "52fd11adae7dc8000099b788",
-    "team": "humans",
-    "levelID": "brawlwood",
-    "levelName": "Brawlwood",
-    "submitted": true,
-    "totalScore": 14.50139221733582,
-    "code": {
-      "programmable-artillery": {
-        "chooseAction": "// This code is shared across all your Artillery.\n// Artillery are expensive, slow, and deadly, with high\n// area-of-effect damage that hurts foes and friends alike.\n\nvar targetEnemy, enemy;\nvar enemies = this.getEnemies();\nfor(var i = 0; i < enemies.length; ++i) {\n    enemy = enemies[i];\n    if(enemy.type === 'munchkin') {\n        targetEnemy = enemy;\n        break;\n    }\n}\n\nif(!targetEnemy)\n    targetEnemy = this.getNearestEnemy();\nif(targetEnemy)\n    this.attackXY(targetEnemy.pos.x, targetEnemy.pos.y);\nelse\n    this.move({x: 70, y: 70});",
-        "hear": "// When the artillery hears a say() message, this hear() method will be called.\nif(speaker.team !== this.team) return;\n\n// You can add code to respond to the message here."
-      },
-      "programmable-soldier": {
-        "chooseAction": "// This code is shared across all your Soldiers.\n// Soldiers are basic, fast melee units.\n\nvar enemy = this.getNearestEnemy();\nif(enemy && enemy.type != 'burl')\n    this.attack(enemy);\nelse {\n    var targetPos = {x: 70, y: 70};\n    if(this.now() < 10)\n        targetPos = {x: 40, y: 40};\n    this.move(targetPos);\n}",
-        "hear": "// When the soldier hears a say() message, this hear() method will be called.\nif(speaker.team !== this.team) return;\n\n// You can add code to respond to the message here."
-      },
-      "programmable-archer": {
-        "chooseAction": "// This code is shared across all your Archers.\n// Archers are vulnerable but deadly ranged units.\n\nif(this.lastEnemy && !this.lastEnemy.dead) {\n    this.attack(this.lastEnemy);\n    return;\n}\n\nvar enemy = this.getNearestEnemy();\nif(enemy) {\n    this.attack(enemy);\n    if(this.distance(enemy) < this.attackRange) {\n        this.lastEnemy = enemy;\n    }\n}\nelse\n    this.move({x: 70, y: 70});",
-        "hear": "// When the archer hears a say() message, this hear() method will be called.\nif(speaker.team !== this.team) return;\n\n// You can add code to respond to the message here."
-      },
-      "human-base": {
-        "chooseAction": "// This is the code for your base. Decide which unit to build each frame.\n// Units you build will go into the this.built array.\n// If you don't have enough gold, this.build() won't build anything.\n// You start with 100 gold and receive 2 gold per second.\n// Kill enemies, especially towers and brawlers, to earn more gold.\n// Destroy the enemy base within 90 seconds!\n\nvar type = 'soldier';\nif(this.built.length === 4)\n    type = 'artillery';\nelse if(this.built.length % 3 === 1)\n    type = 'archer';\n\n\nif(this.gold >= this.buildables[type].goldCost) {\n    //this.say('Unit #' + this.built.length + ' will be a ' + type);\n    this.build(type);\n}",
-        "hear": "// When the base hears a say() message, this hear() method will be called.\nif(speaker.team !== this.team) return;\n\n// You can add code to respond to the message here."
-      },
-      "s-arrow-tower": {
-        "chooseAction": "// This code is shared by both your Arrow Towers.\n// Don't let your towers die lest the ogres claim 250 gold!\n\nvar enemy = this.getNearestEnemy();\nif(enemy && this.distance(enemy) < this.attackRange) {\n    this.say(\"Die, \" + enemy.id + \".\");\n    this.attack(enemy);\n}"
-      }
-    },
-    "submittedCodeLanguage": "javascript",
-    "playtime": 0,
-    "codeLanguage": "javascript"
-  }
-]
-
 module.exports = ->
   me.isAdmin = -> false
   me.set('permissions', ['employer'])
   v = new ProfileView({}, 'joe')
-  jasmine.Ajax.requests.mostRecent()
   for url, responseBody of responses
     requests = jasmine.Ajax.requests.filter(url)
     if not requests.length
@@ -862,5 +760,5 @@ module.exports = ->
       continue
     request = requests[0]
     request.response({status: 200, responseText: JSON.stringify(responseBody)})
-#  v.$el = v.$el.find('.main-content-area')
+  #  v.$el = v.$el.find('.main-content-area')
   v

From 079d336881d89b480c8989065cd48c62059e02c2 Mon Sep 17 00:00:00 2001
From: Nick Winter <livelily@gmail.com>
Date: Thu, 17 Jul 2014 16:36:59 -0700
Subject: [PATCH 35/58] Stopped .nano from overriding Bootstrap's column width
 for component docs page.

---
 app/styles/docs/components.sass | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/app/styles/docs/components.sass b/app/styles/docs/components.sass
index 73979ded2..9283eda41 100644
--- a/app/styles/docs/components.sass
+++ b/app/styles/docs/components.sass
@@ -15,8 +15,11 @@
       .doc-name
         color: rgb(139, 69, 19)
 
+    .index-column
+      width: 25%
   
     .documentation-column
+      width: 75%
   
       .specialList
         list-style-type: none

From 0e042ee61cf9bc0881d703b328c804530c4e43bb Mon Sep 17 00:00:00 2001
From: Scott Erickson <sderickson@gmail.com>
Date: Thu, 17 Jul 2014 17:16:32 -0700
Subject: [PATCH 36/58] Refactoring View to RootView. Refactoring some
 RootViews to be routed manually.

---
 app/lib/Router.coffee                               | 13 +++++++++++++
 app/views/AboutView.coffee                          |  6 ++++++
 app/views/{admin_view.coffee => AdminView.coffee}   |  4 ++--
 app/views/{cla_view.coffee => CLAView.coffee}       |  4 ++--
 app/views/CommunityView.coffee                      |  6 ++++++
 app/views/about_view.coffee                         |  6 ------
 app/views/account/settings_view.coffee              |  4 ++--
 app/views/admin/candidates_view.coffee              |  4 ++--
 app/views/admin/clas_view.coffee                    |  4 ++--
 app/views/admin/employer_list_view.coffee           |  4 ++--
 app/views/admin/level_sessions_view.coffee          |  4 ++--
 app/views/admin/users_view.coffee                   |  4 ++--
 app/views/community_view.coffee                     |  6 ------
 ...adventurer_view.coffee => AdventurerView.coffee} |  2 +-
 ...ambassador_view.coffee => AmbassadorView.coffee} |  2 +-
 .../{archmage_view.coffee => ArchmageView.coffee}   |  2 +-
 .../{artisan_view.coffee => ArtisanView.coffee}     |  2 +-
 ...class_view.coffee => ContributeClassView.coffee} |  4 ++--
 .../{diplomat_view.coffee => DiplomatView.coffee}   |  2 +-
 .../MainContributeView.coffee}                      |  4 ++--
 .../{scribe_view.coffee => ScribeView.coffee}       |  2 +-
 app/views/editor/achievement/edit.coffee            |  4 ++--
 app/views/editor/article/edit.coffee                |  4 ++--
 app/views/editor/article/preview.coffee             |  4 ++--
 app/views/editor/level/edit.coffee                  |  4 ++--
 app/views/editor/thang/edit.coffee                  |  4 ++--
 app/views/editor_view.coffee                        |  4 ++--
 app/views/employers_view.coffee                     |  4 ++--
 app/views/error_view.coffee                         |  4 ++--
 app/views/home_view.coffee                          |  4 ++--
 app/views/kinds/SearchView.coffee                   |  4 ++--
 app/views/legal_view.coffee                         |  4 ++--
 app/views/not_found.coffee                          |  4 ++--
 app/views/play/ladder_home.coffee                   |  4 ++--
 app/views/play/level_view.coffee                    |  4 ++--
 app/views/play/spectate_view.coffee                 |  4 ++--
 app/views/play_view.coffee                          |  4 ++--
 app/views/sprite_parser_test_view.coffee            |  4 ++--
 app/views/teachers_view.coffee                      |  4 ++--
 39 files changed, 87 insertions(+), 74 deletions(-)
 create mode 100644 app/views/AboutView.coffee
 rename app/views/{admin_view.coffee => AdminView.coffee} (90%)
 rename app/views/{cla_view.coffee => CLAView.coffee} (88%)
 create mode 100644 app/views/CommunityView.coffee
 delete mode 100644 app/views/about_view.coffee
 delete mode 100644 app/views/community_view.coffee
 rename app/views/contribute/{adventurer_view.coffee => AdventurerView.coffee} (76%)
 rename app/views/contribute/{ambassador_view.coffee => AmbassadorView.coffee} (76%)
 rename app/views/contribute/{archmage_view.coffee => ArchmageView.coffee} (95%)
 rename app/views/contribute/{artisan_view.coffee => ArtisanView.coffee} (92%)
 rename app/views/contribute/{contribute_class_view.coffee => ContributeClassView.coffee} (93%)
 rename app/views/contribute/{diplomat_view.coffee => DiplomatView.coffee} (75%)
 rename app/views/{contribute_view.coffee => contribute/MainContributeView.coffee} (56%)
 rename app/views/contribute/{scribe_view.coffee => ScribeView.coffee} (86%)

diff --git a/app/lib/Router.coffee b/app/lib/Router.coffee
index 31fcf6a85..17dab5309 100644
--- a/app/lib/Router.coffee
+++ b/app/lib/Router.coffee
@@ -8,6 +8,19 @@ module.exports = class CocoRouter extends Backbone.Router
     Backbone.Mediator.subscribe 'router:navigate', @onNavigate, @
 
   routes:
+    'about': go('AboutView')
+    'admin': go('AdminView')
+    'cla': go('CLAView')
+    'community': go('CommunityView')
+    
+    'contribute': go('contribute/MainContributeView')
+    'contribute/adventurer': go('contribute/AdventurerView')
+    'contribute/ambassador': go('contribute/AmbassadorView')
+    'contribute/archmage': go('contribute/ArchmageView')
+    'contribute/artisan': go('contribute/ArtisanView')
+    'contribute/diplomat': go('contribute/DiplomatView')
+    'contribute/scribe': go('contribute/ScribeView')
+  
     # every abnormal view gets listed here
     '': 'home'
     'preview': 'home'
diff --git a/app/views/AboutView.coffee b/app/views/AboutView.coffee
new file mode 100644
index 000000000..b93e9bdc6
--- /dev/null
+++ b/app/views/AboutView.coffee
@@ -0,0 +1,6 @@
+RootView = require 'views/kinds/RootView'
+template = require 'templates/about'
+
+module.exports = class AboutView extends RootView
+  id: 'about-view'
+  template: template
diff --git a/app/views/admin_view.coffee b/app/views/AdminView.coffee
similarity index 90%
rename from app/views/admin_view.coffee
rename to app/views/AdminView.coffee
index 6b0aadcc9..5c23d2ab1 100644
--- a/app/views/admin_view.coffee
+++ b/app/views/AdminView.coffee
@@ -1,8 +1,8 @@
 {backboneFailure, genericFailure} = require 'lib/errors'
-View = require 'views/kinds/RootView'
+RootView = require 'views/kinds/RootView'
 template = require 'templates/admin'
 
-module.exports = class AdminView extends View
+module.exports = class AdminView extends RootView
   id: 'admin-view'
   template: template
 
diff --git a/app/views/cla_view.coffee b/app/views/CLAView.coffee
similarity index 88%
rename from app/views/cla_view.coffee
rename to app/views/CLAView.coffee
index 93f03aa56..08664992f 100644
--- a/app/views/cla_view.coffee
+++ b/app/views/CLAView.coffee
@@ -1,8 +1,8 @@
-View = require 'views/kinds/RootView'
+RootView = require 'views/kinds/RootView'
 template = require 'templates/cla'
 {me} = require 'lib/auth'
 
-module.exports = class CLAView extends View
+module.exports = class CLAView extends RootView
   id: 'cla-view'
   template: template
 
diff --git a/app/views/CommunityView.coffee b/app/views/CommunityView.coffee
new file mode 100644
index 000000000..15d28300a
--- /dev/null
+++ b/app/views/CommunityView.coffee
@@ -0,0 +1,6 @@
+RootView = require 'views/kinds/RootView'
+template = require 'templates/community'
+
+module.exports = class CommunityView extends RootView
+  id: 'community-view'
+  template: template
diff --git a/app/views/about_view.coffee b/app/views/about_view.coffee
deleted file mode 100644
index 76988aba8..000000000
--- a/app/views/about_view.coffee
+++ /dev/null
@@ -1,6 +0,0 @@
-View = require 'views/kinds/RootView'
-template = require 'templates/about'
-
-module.exports = class AboutView extends View
-  id: 'about-view'
-  template: template
diff --git a/app/views/account/settings_view.coffee b/app/views/account/settings_view.coffee
index 4f6622232..39a335488 100644
--- a/app/views/account/settings_view.coffee
+++ b/app/views/account/settings_view.coffee
@@ -1,4 +1,4 @@
-View = require 'views/kinds/RootView'
+RootView = require 'views/kinds/RootView'
 template = require 'templates/account/settings'
 {me} = require 'lib/auth'
 forms = require 'lib/forms'
@@ -8,7 +8,7 @@ AuthModalView = require 'views/modal/auth_modal'
 WizardSettingsView = require './wizard_settings_view'
 JobProfileView = require './job_profile_view'
 
-module.exports = class SettingsView extends View
+module.exports = class SettingsView extends RootView
   id: 'account-settings-view'
   template: template
   changedFields: [] # DOM input fields
diff --git a/app/views/admin/candidates_view.coffee b/app/views/admin/candidates_view.coffee
index 2946b161d..c91f16efd 100644
--- a/app/views/admin/candidates_view.coffee
+++ b/app/views/admin/candidates_view.coffee
@@ -1,4 +1,4 @@
-View = require 'views/kinds/RootView'
+RootView = require 'views/kinds/RootView'
 template = require 'templates/admin/candidates'
 app = require 'application'
 User = require 'models/User'
@@ -15,7 +15,7 @@ class UserRemarksCollection extends CocoCollection
   url: '/db/user.remark?project=contact,contactName,user'
   model: UserRemark
 
-module.exports = class EmployersView extends View
+module.exports = class EmployersView extends RootView
   id: "admin-candidates-view"
   template: template
 
diff --git a/app/views/admin/clas_view.coffee b/app/views/admin/clas_view.coffee
index 96828e23e..a384215ed 100644
--- a/app/views/admin/clas_view.coffee
+++ b/app/views/admin/clas_view.coffee
@@ -1,7 +1,7 @@
-View = require 'views/kinds/RootView'
+RootView = require 'views/kinds/RootView'
 template = require 'templates/admin/clas'
 
-module.exports = class CLAsView extends View
+module.exports = class CLAsView extends RootView
   id: 'admin-clas-view'
   template: template
   startsLoading: true
diff --git a/app/views/admin/employer_list_view.coffee b/app/views/admin/employer_list_view.coffee
index b2ec64d77..32c08cd22 100644
--- a/app/views/admin/employer_list_view.coffee
+++ b/app/views/admin/employer_list_view.coffee
@@ -1,4 +1,4 @@
-View = require 'views/kinds/RootView'
+RootView = require 'views/kinds/RootView'
 template = require 'templates/admin/employer_list'
 app = require 'application'
 User = require 'models/User'
@@ -10,7 +10,7 @@ class EmployersCollection extends CocoCollection
   url: '/db/user/x/employers'
   model: User
 
-module.exports = class EmployersView extends View
+module.exports = class EmployersView extends RootView
   id: 'employers-view'
   template: template
 
diff --git a/app/views/admin/level_sessions_view.coffee b/app/views/admin/level_sessions_view.coffee
index cca854cc3..aca163686 100644
--- a/app/views/admin/level_sessions_view.coffee
+++ b/app/views/admin/level_sessions_view.coffee
@@ -1,4 +1,4 @@
-View = require 'views/kinds/RootView'
+RootView = require 'views/kinds/RootView'
 template = require 'templates/admin/level_sessions'
 LevelSession = require 'models/LevelSession'
 
@@ -7,7 +7,7 @@ class LevelSessionCollection extends Backbone.Collection
   url: '/db/level_session/x/active'
   model: LevelSession
 
-module.exports = class LevelSessionsView extends View
+module.exports = class LevelSessionsView extends RootView
   id: 'admin-level-sessions-view'
   template: template
 
diff --git a/app/views/admin/users_view.coffee b/app/views/admin/users_view.coffee
index fa4aa1ba9..7ff58de72 100644
--- a/app/views/admin/users_view.coffee
+++ b/app/views/admin/users_view.coffee
@@ -1,8 +1,8 @@
-View = require 'views/kinds/RootView'
+RootView = require 'views/kinds/RootView'
 template = require 'templates/admin/users'
 User = require 'models/User'
 
-module.exports = class UsersView extends View
+module.exports = class UsersView extends RootView
   # TODO: Pagination, choosing filters on the page itself.
 
   id: 'admin-users-view'
diff --git a/app/views/community_view.coffee b/app/views/community_view.coffee
deleted file mode 100644
index 69a140269..000000000
--- a/app/views/community_view.coffee
+++ /dev/null
@@ -1,6 +0,0 @@
-View = require 'views/kinds/RootView'
-template = require 'templates/community'
-
-module.exports = class CommunityView extends View
-  id: 'community-view'
-  template: template
diff --git a/app/views/contribute/adventurer_view.coffee b/app/views/contribute/AdventurerView.coffee
similarity index 76%
rename from app/views/contribute/adventurer_view.coffee
rename to app/views/contribute/AdventurerView.coffee
index deda5add5..9ad6a87f4 100644
--- a/app/views/contribute/adventurer_view.coffee
+++ b/app/views/contribute/AdventurerView.coffee
@@ -1,4 +1,4 @@
-ContributeClassView = require 'views/contribute/contribute_class_view'
+ContributeClassView = require './ContributeClassView'
 template = require 'templates/contribute/adventurer'
 {me} = require 'lib/auth'
 
diff --git a/app/views/contribute/ambassador_view.coffee b/app/views/contribute/AmbassadorView.coffee
similarity index 76%
rename from app/views/contribute/ambassador_view.coffee
rename to app/views/contribute/AmbassadorView.coffee
index 73c35bf96..4ac62b277 100644
--- a/app/views/contribute/ambassador_view.coffee
+++ b/app/views/contribute/AmbassadorView.coffee
@@ -1,4 +1,4 @@
-ContributeClassView = require 'views/contribute/contribute_class_view'
+ContributeClassView = require './ContributeClassView'
 template = require 'templates/contribute/ambassador'
 {me} = require 'lib/auth'
 
diff --git a/app/views/contribute/archmage_view.coffee b/app/views/contribute/ArchmageView.coffee
similarity index 95%
rename from app/views/contribute/archmage_view.coffee
rename to app/views/contribute/ArchmageView.coffee
index e29a9be5c..dd21e40ae 100644
--- a/app/views/contribute/archmage_view.coffee
+++ b/app/views/contribute/ArchmageView.coffee
@@ -1,4 +1,4 @@
-ContributeClassView = require 'views/contribute/contribute_class_view'
+ContributeClassView = require './ContributeClassView'
 template = require 'templates/contribute/archmage'
 
 module.exports = class ArchmageView extends ContributeClassView
diff --git a/app/views/contribute/artisan_view.coffee b/app/views/contribute/ArtisanView.coffee
similarity index 92%
rename from app/views/contribute/artisan_view.coffee
rename to app/views/contribute/ArtisanView.coffee
index 7094dba98..40aa5bba0 100644
--- a/app/views/contribute/artisan_view.coffee
+++ b/app/views/contribute/ArtisanView.coffee
@@ -1,4 +1,4 @@
-ContributeClassView = require 'views/contribute/contribute_class_view'
+ContributeClassView = require './ContributeClassView'
 template = require 'templates/contribute/artisan'
 {me} = require 'lib/auth'
 
diff --git a/app/views/contribute/contribute_class_view.coffee b/app/views/contribute/ContributeClassView.coffee
similarity index 93%
rename from app/views/contribute/contribute_class_view.coffee
rename to app/views/contribute/ContributeClassView.coffee
index 3da551ffb..7b403d466 100644
--- a/app/views/contribute/contribute_class_view.coffee
+++ b/app/views/contribute/ContributeClassView.coffee
@@ -1,11 +1,11 @@
 SignupModalView = require 'views/modal/signup_modal'
-View = require 'views/kinds/RootView'
+RootView = require 'views/kinds/RootView'
 {me} = require 'lib/auth'
 contributorSignupAnonymousTemplate = require 'templates/contribute/contributor_signup_anonymous'
 contributorSignupTemplate = require 'templates/contribute/contributor_signup'
 contributorListTemplate = require 'templates/contribute/contributor_list'
 
-module.exports = class ContributeClassView extends View
+module.exports = class ContributeClassView extends RootView
   navPrefix: '/contribute'
 
   events:
diff --git a/app/views/contribute/diplomat_view.coffee b/app/views/contribute/DiplomatView.coffee
similarity index 75%
rename from app/views/contribute/diplomat_view.coffee
rename to app/views/contribute/DiplomatView.coffee
index 00b3dd7a7..32572cce0 100644
--- a/app/views/contribute/diplomat_view.coffee
+++ b/app/views/contribute/DiplomatView.coffee
@@ -1,4 +1,4 @@
-ContributeClassView = require 'views/contribute/contribute_class_view'
+ContributeClassView = require './ContributeClassView'
 template = require 'templates/contribute/diplomat'
 {me} = require 'lib/auth'
 
diff --git a/app/views/contribute_view.coffee b/app/views/contribute/MainContributeView.coffee
similarity index 56%
rename from app/views/contribute_view.coffee
rename to app/views/contribute/MainContributeView.coffee
index fa772c75a..930870110 100644
--- a/app/views/contribute_view.coffee
+++ b/app/views/contribute/MainContributeView.coffee
@@ -1,7 +1,7 @@
-ContributeClassView = require 'views/contribute/contribute_class_view'
+ContributeClassView = require 'views/contribute/ContributeClassView'
 template = require 'templates/contribute/contribute'
 
-module.exports = class ContributeView extends ContributeClassView
+module.exports = class MainContributeView extends ContributeClassView
   id: 'contribute-view'
   template: template
   navPrefix: ''
diff --git a/app/views/contribute/scribe_view.coffee b/app/views/contribute/ScribeView.coffee
similarity index 86%
rename from app/views/contribute/scribe_view.coffee
rename to app/views/contribute/ScribeView.coffee
index d52d0106b..bcaa5f648 100644
--- a/app/views/contribute/scribe_view.coffee
+++ b/app/views/contribute/ScribeView.coffee
@@ -1,4 +1,4 @@
-ContributeClassView = require 'views/contribute/contribute_class_view'
+ContributeClassView = require './ContributeClassView'
 template = require 'templates/contribute/scribe'
 {me} = require 'lib/auth'
 
diff --git a/app/views/editor/achievement/edit.coffee b/app/views/editor/achievement/edit.coffee
index ce65446dd..8f4379777 100644
--- a/app/views/editor/achievement/edit.coffee
+++ b/app/views/editor/achievement/edit.coffee
@@ -1,9 +1,9 @@
-View = require 'views/kinds/RootView'
+RootView = require 'views/kinds/RootView'
 template = require 'templates/editor/achievement/edit'
 Achievement = require 'models/Achievement'
 ConfirmModal = require 'views/modal/confirm'
 
-module.exports = class AchievementEditView extends View
+module.exports = class AchievementEditView extends RootView
   id: 'editor-achievement-edit-view'
   template: template
   startsLoading: true
diff --git a/app/views/editor/article/edit.coffee b/app/views/editor/article/edit.coffee
index ae9083a2a..70450103f 100644
--- a/app/views/editor/article/edit.coffee
+++ b/app/views/editor/article/edit.coffee
@@ -1,11 +1,11 @@
-View = require 'views/kinds/RootView'
+RootView = require 'views/kinds/RootView'
 VersionHistoryView = require './versions_view'
 template = require 'templates/editor/article/edit'
 Article = require 'models/Article'
 SaveVersionModal = require 'views/modal/save_version_modal'
 PatchesView = require 'views/editor/patches_view'
 
-module.exports = class ArticleEditView extends View
+module.exports = class ArticleEditView extends RootView
   id: 'editor-article-edit-view'
   template: template
   startsLoading: true
diff --git a/app/views/editor/article/preview.coffee b/app/views/editor/article/preview.coffee
index ef4d3455b..9426454bf 100644
--- a/app/views/editor/article/preview.coffee
+++ b/app/views/editor/article/preview.coffee
@@ -1,6 +1,6 @@
-View = require 'views/kinds/RootView'
+RootView = require 'views/kinds/RootView'
 template = require 'templates/editor/article/preview'
 
-module.exports = class PreviewView extends View
+module.exports = class PreviewView extends RootView
   id: 'editor-article-preview-view'
   template: template
diff --git a/app/views/editor/level/edit.coffee b/app/views/editor/level/edit.coffee
index 7e893d748..d597f0bfd 100644
--- a/app/views/editor/level/edit.coffee
+++ b/app/views/editor/level/edit.coffee
@@ -1,4 +1,4 @@
-View = require 'views/kinds/RootView'
+RootView = require 'views/kinds/RootView'
 template = require 'templates/editor/level/edit'
 Level = require 'models/Level'
 LevelSystem = require 'models/LevelSystem'
@@ -18,7 +18,7 @@ PatchesView = require 'views/editor/patches_view'
 VersionHistoryView = require './versions_view'
 ErrorView = require '../../error_view'
 
-module.exports = class EditorLevelView extends View
+module.exports = class EditorLevelView extends RootView
   id: 'editor-level-view'
   template: template
   cache: false
diff --git a/app/views/editor/thang/edit.coffee b/app/views/editor/thang/edit.coffee
index d21272e6a..b5ea43653 100644
--- a/app/views/editor/thang/edit.coffee
+++ b/app/views/editor/thang/edit.coffee
@@ -5,7 +5,7 @@ CocoSprite = require 'lib/surface/CocoSprite'
 Camera = require 'lib/surface/Camera'
 DocumentFiles = require 'collections/DocumentFiles'
 
-View = require 'views/kinds/RootView'
+RootView = require 'views/kinds/RootView'
 ThangComponentEditView = require 'views/editor/components/main'
 VersionHistoryView = require './versions_view'
 ColorsTabView = require './colors_tab_view'
@@ -16,7 +16,7 @@ template = require 'templates/editor/thang/edit'
 
 CENTER = {x: 200, y: 300}
 
-module.exports = class ThangTypeEditView extends View
+module.exports = class ThangTypeEditView extends RootView
   id: 'editor-thang-type-edit-view'
   template: template
   startsLoading: true
diff --git a/app/views/editor_view.coffee b/app/views/editor_view.coffee
index aafe00eb1..7536d5ebc 100644
--- a/app/views/editor_view.coffee
+++ b/app/views/editor_view.coffee
@@ -1,6 +1,6 @@
-View = require 'views/kinds/RootView'
+RootView = require 'views/kinds/RootView'
 template = require 'templates/editor'
 
-module.exports = class EditorView extends View
+module.exports = class EditorView extends RootView
   id: 'editor-nav-view'
   template: template
diff --git a/app/views/employers_view.coffee b/app/views/employers_view.coffee
index 03ba35c85..9bbfa1ef6 100644
--- a/app/views/employers_view.coffee
+++ b/app/views/employers_view.coffee
@@ -1,4 +1,4 @@
-View = require 'views/kinds/RootView'
+RootView = require 'views/kinds/RootView'
 template = require 'templates/employers'
 app = require 'application'
 User = require 'models/User'
@@ -15,7 +15,7 @@ class UserRemarksCollection extends CocoCollection
   url: '/db/user.remark?project=contact,contactName,user'
   model: UserRemark
 
-module.exports = class EmployersView extends View
+module.exports = class EmployersView extends RootView
   id: 'employers-view'
   template: template
 
diff --git a/app/views/error_view.coffee b/app/views/error_view.coffee
index 3ed6db5fd..f7b0ba04b 100644
--- a/app/views/error_view.coffee
+++ b/app/views/error_view.coffee
@@ -1,6 +1,6 @@
-View = require 'views/kinds/RootView'
+RootView = require 'views/kinds/RootView'
 template = require 'templates/error'
 
-module.exports = class ErrorView extends View
+module.exports = class ErrorView extends RootView
   id: 'error-view'
   template: template
diff --git a/app/views/home_view.coffee b/app/views/home_view.coffee
index 40eb72e88..dcc3dee69 100644
--- a/app/views/home_view.coffee
+++ b/app/views/home_view.coffee
@@ -1,4 +1,4 @@
-View = require 'views/kinds/RootView'
+RootView = require 'views/kinds/RootView'
 template = require 'templates/home'
 WizardSprite = require 'lib/surface/WizardSprite'
 ThangType = require 'models/ThangType'
@@ -6,7 +6,7 @@ Simulator = require 'lib/simulator/Simulator'
 {me} = require '/lib/auth'
 application  = require 'application'
 
-module.exports = class HomeView extends View
+module.exports = class HomeView extends RootView
   id: 'home-view'
   template: template
 
diff --git a/app/views/kinds/SearchView.coffee b/app/views/kinds/SearchView.coffee
index 91b04d4d5..7fdd4cad6 100644
--- a/app/views/kinds/SearchView.coffee
+++ b/app/views/kinds/SearchView.coffee
@@ -1,4 +1,4 @@
-View = require 'views/kinds/RootView'
+RootView = require 'views/kinds/RootView'
 template = require 'templates/kinds/search'
 forms = require 'lib/forms'
 app = require 'application'
@@ -12,7 +12,7 @@ class SearchCollection extends Backbone.Collection
     else @url += 'true'
     @url += "&term=#{term}" if @term
 
-module.exports = class SearchView extends View
+module.exports = class SearchView extends RootView
   template: template
   className: 'search-view'
 
diff --git a/app/views/legal_view.coffee b/app/views/legal_view.coffee
index 09ae6f2c3..2dd36473d 100644
--- a/app/views/legal_view.coffee
+++ b/app/views/legal_view.coffee
@@ -1,6 +1,6 @@
-View = require 'views/kinds/RootView'
+RootView = require 'views/kinds/RootView'
 template = require 'templates/legal'
 
-module.exports = class LegalView extends View
+module.exports = class LegalView extends RootView
   id: 'legal-view'
   template: template
diff --git a/app/views/not_found.coffee b/app/views/not_found.coffee
index 95e94921b..11d94cb42 100644
--- a/app/views/not_found.coffee
+++ b/app/views/not_found.coffee
@@ -1,6 +1,6 @@
-View = require 'views/kinds/RootView'
+RootView = require 'views/kinds/RootView'
 template = require 'templates/not_found'
 
-module.exports = class NotFoundView extends View
+module.exports = class NotFoundView extends RootView
   id: 'not-found-view'
   template: template
diff --git a/app/views/play/ladder_home.coffee b/app/views/play/ladder_home.coffee
index 1508697c9..502bbd877 100644
--- a/app/views/play/ladder_home.coffee
+++ b/app/views/play/ladder_home.coffee
@@ -1,4 +1,4 @@
-View = require 'views/kinds/RootView'
+RootView = require 'views/kinds/RootView'
 template = require 'templates/play/ladder_home'
 LevelSession = require 'models/LevelSession'
 CocoCollection = require 'collections/CocoCollection'
@@ -11,7 +11,7 @@ class LevelSessionsCollection extends CocoCollection
     super()
     @url = "/db/user/#{me.id}/level.sessions?project=state.complete,levelID"
 
-module.exports = class LadderHomeView extends View
+module.exports = class LadderHomeView extends RootView
   id: 'ladder-home-view'
   template: template
 
diff --git a/app/views/play/level_view.coffee b/app/views/play/level_view.coffee
index 3527df5e5..010479b5f 100644
--- a/app/views/play/level_view.coffee
+++ b/app/views/play/level_view.coffee
@@ -1,4 +1,4 @@
-View = require 'views/kinds/RootView'
+RootView = require 'views/kinds/RootView'
 template = require 'templates/play/level'
 {me} = require 'lib/auth'
 ThangType = require 'models/ThangType'
@@ -35,7 +35,7 @@ InfiniteLoopModal = require './level/modal/infinite_loop_modal'
 
 PROFILE_ME = false
 
-module.exports = class PlayLevelView extends View
+module.exports = class PlayLevelView extends RootView
   id: 'level-view'
   template: template
   cache: false
diff --git a/app/views/play/spectate_view.coffee b/app/views/play/spectate_view.coffee
index 340978693..de9cab929 100644
--- a/app/views/play/spectate_view.coffee
+++ b/app/views/play/spectate_view.coffee
@@ -1,4 +1,4 @@
-View = require 'views/kinds/RootView'
+RootView = require 'views/kinds/RootView'
 template = require 'templates/play/spectate'
 {me} = require 'lib/auth'
 ThangType = require 'models/ThangType'
@@ -33,7 +33,7 @@ InfiniteLoopModal = require './level/modal/infinite_loop_modal'
 
 PROFILE_ME = false
 
-module.exports = class SpectateLevelView extends View
+module.exports = class SpectateLevelView extends RootView
   id: 'spectate-level-view'
   template: template
   cache: false
diff --git a/app/views/play_view.coffee b/app/views/play_view.coffee
index c6679a3f4..202bd32a3 100644
--- a/app/views/play_view.coffee
+++ b/app/views/play_view.coffee
@@ -1,4 +1,4 @@
-View = require 'views/kinds/RootView'
+RootView = require 'views/kinds/RootView'
 template = require 'templates/play'
 LevelSession = require 'models/LevelSession'
 CocoCollection = require 'collections/CocoCollection'
@@ -11,7 +11,7 @@ class LevelSessionsCollection extends CocoCollection
     super()
     @url = "/db/user/#{me.id}/level.sessions?project=state.complete,levelID"
 
-module.exports = class PlayView extends View
+module.exports = class PlayView extends RootView
   id: 'play-view'
   template: template
 
diff --git a/app/views/sprite_parser_test_view.coffee b/app/views/sprite_parser_test_view.coffee
index ece70743e..80369fc45 100644
--- a/app/views/sprite_parser_test_view.coffee
+++ b/app/views/sprite_parser_test_view.coffee
@@ -1,11 +1,11 @@
-View = require 'views/kinds/RootView'
+RootView = require 'views/kinds/RootView'
 template = require 'templates/editor/thang/sprite_parser_test'
 SpriteParser = require 'lib/sprites/SpriteParser'
 mixed_samples = require 'lib/sprites/parser_samples'
 samples = require 'lib/sprites/parser_samples_artillery'
 ThangType = require 'models/ThangType'
 
-module.exports = class SpriteParserTestView extends View
+module.exports = class SpriteParserTestView extends RootView
   id: 'sprite-parser-test-view'
   template: template
 
diff --git a/app/views/teachers_view.coffee b/app/views/teachers_view.coffee
index 783f1391e..25d4ec958 100644
--- a/app/views/teachers_view.coffee
+++ b/app/views/teachers_view.coffee
@@ -1,6 +1,6 @@
-View = require 'views/kinds/RootView'
+RootView = require 'views/kinds/RootView'
 template = require 'templates/teachers'
 
-module.exports = class TeachersView extends View
+module.exports = class TeachersView extends RootView
   id: 'teachers-view'
   template: template

From e18b4de583b2bc6265f965f60811b2e2ddfeb85e Mon Sep 17 00:00:00 2001
From: Scott Erickson <sderickson@gmail.com>
Date: Thu, 17 Jul 2014 17:20:11 -0700
Subject: [PATCH 37/58] Refactoring View to CocoView.

---
 app/views/editor/level/add_thangs_view.coffee                 | 4 ++--
 app/views/editor/level/component/edit.coffee                  | 4 ++--
 app/views/editor/level/components_tab_view.coffee             | 4 ++--
 app/views/editor/level/scripts_tab_view.coffee                | 4 ++--
 app/views/editor/level/settings_tab_view.coffee               | 4 ++--
 app/views/editor/level/system/edit.coffee                     | 4 ++--
 app/views/editor/level/systems_tab_view.coffee                | 4 ++--
 app/views/editor/level/thang/edit.coffee                      | 4 ++--
 app/views/editor/level/thangs_tab_view.coffee                 | 4 ++--
 app/views/play/level/control_bar_view.coffee                  | 4 ++--
 app/views/play/level/goals_view.coffee                        | 4 ++--
 app/views/play/level/gold_view.coffee                         | 4 ++--
 app/views/play/level/hud_view.coffee                          | 4 ++--
 app/views/play/level/level_chat_view.coffee                   | 4 ++--
 app/views/play/level/level_loading_view.coffee                | 4 ++--
 app/views/play/level/playback_view.coffee                     | 4 ++--
 app/views/play/level/thang_avatar_view.coffee                 | 4 ++--
 app/views/play/level/tome/cast_button_view.coffee             | 4 ++--
 app/views/play/level/tome/problem_alert_view.coffee           | 4 ++--
 app/views/play/level/tome/spell_debug_view.coffee             | 4 ++--
 app/views/play/level/tome/spell_list_entry_thangs_view.coffee | 4 ++--
 app/views/play/level/tome/spell_list_entry_view.coffee        | 4 ++--
 app/views/play/level/tome/spell_list_view.coffee              | 4 ++--
 app/views/play/level/tome/spell_palette_entry_view.coffee     | 4 ++--
 app/views/play/level/tome/spell_palette_view.coffee           | 4 ++--
 app/views/play/level/tome/spell_toolbar_view.coffee           | 4 ++--
 app/views/play/level/tome/spell_view.coffee                   | 4 ++--
 app/views/play/level/tome/thang_list_entry_view.coffee        | 4 ++--
 app/views/play/level/tome/thang_list_view.coffee              | 4 ++--
 app/views/play/level/tome/tome_view.coffee                    | 4 ++--
 30 files changed, 60 insertions(+), 60 deletions(-)

diff --git a/app/views/editor/level/add_thangs_view.coffee b/app/views/editor/level/add_thangs_view.coffee
index 7a7070b17..e41f42967 100644
--- a/app/views/editor/level/add_thangs_view.coffee
+++ b/app/views/editor/level/add_thangs_view.coffee
@@ -1,4 +1,4 @@
-View = require 'views/kinds/CocoView'
+CocoView = require 'views/kinds/CocoView'
 add_thangs_template = require 'templates/editor/level/add_thangs'
 ThangType = require 'models/ThangType'
 CocoCollection = require 'collections/CocoCollection'
@@ -10,7 +10,7 @@ class ThangTypeSearchCollection extends CocoCollection
   addTerm: (term) ->
     @url += "&term=#{term}" if term
 
-module.exports = class AddThangsView extends View
+module.exports = class AddThangsView extends CocoView
   id: 'add-thangs-column'
   className: 'add-thangs-palette thangs-column'
   template: add_thangs_template
diff --git a/app/views/editor/level/component/edit.coffee b/app/views/editor/level/component/edit.coffee
index a7bc51149..9e36530ba 100644
--- a/app/views/editor/level/component/edit.coffee
+++ b/app/views/editor/level/component/edit.coffee
@@ -1,11 +1,11 @@
-View = require 'views/kinds/CocoView'
+CocoView = require 'views/kinds/CocoView'
 template = require 'templates/editor/level/component/edit'
 LevelComponent = require 'models/LevelComponent'
 VersionHistoryView = require 'views/editor/component/versions_view'
 PatchesView = require 'views/editor/patches_view'
 SaveVersionModal = require 'views/modal/save_version_modal'
 
-module.exports = class LevelComponentEditView extends View
+module.exports = class LevelComponentEditView extends CocoView
   id: 'editor-level-component-edit-view'
   template: template
   editableSettings: ['name', 'description', 'system', 'codeLanguage', 'dependencies', 'propertyDocumentation', 'i18n']
diff --git a/app/views/editor/level/components_tab_view.coffee b/app/views/editor/level/components_tab_view.coffee
index 27f91ae87..03c9bb2cf 100644
--- a/app/views/editor/level/components_tab_view.coffee
+++ b/app/views/editor/level/components_tab_view.coffee
@@ -1,4 +1,4 @@
-View = require 'views/kinds/CocoView'
+CocoView = require 'views/kinds/CocoView'
 template = require 'templates/editor/level/components_tab'
 LevelComponent = require 'models/LevelComponent'
 LevelComponentEditView = require './component/edit'
@@ -8,7 +8,7 @@ class LevelComponentCollection extends Backbone.Collection
   url: '/db/level.component'
   model: LevelComponent
 
-module.exports = class ComponentsTabView extends View
+module.exports = class ComponentsTabView extends CocoView
   id: 'editor-level-components-tab-view'
   template: template
   className: 'tab-pane'
diff --git a/app/views/editor/level/scripts_tab_view.coffee b/app/views/editor/level/scripts_tab_view.coffee
index 7a3e96c65..ae6813cbf 100644
--- a/app/views/editor/level/scripts_tab_view.coffee
+++ b/app/views/editor/level/scripts_tab_view.coffee
@@ -1,10 +1,10 @@
-View = require 'views/kinds/CocoView'
+CocoView = require 'views/kinds/CocoView'
 template = require 'templates/editor/level/scripts_tab'
 Level = require 'models/Level'
 Surface = require 'lib/surface/Surface'
 nodes = require './treema_nodes'
 
-module.exports = class ScriptsTabView extends View
+module.exports = class ScriptsTabView extends CocoView
   id: 'editor-level-scripts-tab-view'
   template: template
   className: 'tab-pane'
diff --git a/app/views/editor/level/settings_tab_view.coffee b/app/views/editor/level/settings_tab_view.coffee
index b3f99150c..ec163d84e 100644
--- a/app/views/editor/level/settings_tab_view.coffee
+++ b/app/views/editor/level/settings_tab_view.coffee
@@ -1,11 +1,11 @@
-View = require 'views/kinds/CocoView'
+CocoView = require 'views/kinds/CocoView'
 template = require 'templates/editor/level/settings_tab'
 Level = require 'models/Level'
 Surface = require 'lib/surface/Surface'
 nodes = require './treema_nodes'
 {me} = require 'lib/auth'
 
-module.exports = class SettingsTabView extends View
+module.exports = class SettingsTabView extends CocoView
   id: 'editor-level-settings-tab-view'
   className: 'tab-pane'
   template: template
diff --git a/app/views/editor/level/system/edit.coffee b/app/views/editor/level/system/edit.coffee
index f9e9646db..de5877bda 100644
--- a/app/views/editor/level/system/edit.coffee
+++ b/app/views/editor/level/system/edit.coffee
@@ -1,11 +1,11 @@
-View = require 'views/kinds/CocoView'
+CocoView = require 'views/kinds/CocoView'
 template = require 'templates/editor/level/system/edit'
 LevelSystem = require 'models/LevelSystem'
 VersionHistoryView = require 'views/editor/system/versions_view'
 PatchesView = require 'views/editor/patches_view'
 SaveVersionModal = require 'views/modal/save_version_modal'
 
-module.exports = class LevelSystemEditView extends View
+module.exports = class LevelSystemEditView extends CocoView
   id: 'editor-level-system-edit-view'
   template: template
   editableSettings: ['name', 'description', 'codeLanguage', 'dependencies', 'propertyDocumentation', 'i18n']
diff --git a/app/views/editor/level/systems_tab_view.coffee b/app/views/editor/level/systems_tab_view.coffee
index a3b6df3f2..4b4988755 100644
--- a/app/views/editor/level/systems_tab_view.coffee
+++ b/app/views/editor/level/systems_tab_view.coffee
@@ -1,4 +1,4 @@
-View = require 'views/kinds/CocoView'
+CocoView = require 'views/kinds/CocoView'
 template = require 'templates/editor/level/systems_tab'
 Level = require 'models/Level'
 LevelSystem = require 'models/LevelSystem'
@@ -7,7 +7,7 @@ LevelSystemNewView = require './system/new'
 LevelSystemAddView = require './system/add'
 {ThangTypeNode} = require './treema_nodes'
 
-module.exports = class SystemsTabView extends View
+module.exports = class SystemsTabView extends CocoView
   id: 'editor-level-systems-tab-view'
   template: template
   className: 'tab-pane'
diff --git a/app/views/editor/level/thang/edit.coffee b/app/views/editor/level/thang/edit.coffee
index 01eb9c1d1..4dd5b1549 100644
--- a/app/views/editor/level/thang/edit.coffee
+++ b/app/views/editor/level/thang/edit.coffee
@@ -1,9 +1,9 @@
-View = require 'views/kinds/CocoView'
+CocoView = require 'views/kinds/CocoView'
 template = require 'templates/editor/level/thang/edit'
 ThangComponentEditView = require 'views/editor/components/main'
 ThangType = require 'models/ThangType'
 
-module.exports = class LevelThangEditView extends View
+module.exports = class LevelThangEditView extends CocoView
   ###
   In the level editor, is the bar at the top when editing a single thang.
   Everything below is part of the ThangComponentEditView, which is shared with the
diff --git a/app/views/editor/level/thangs_tab_view.coffee b/app/views/editor/level/thangs_tab_view.coffee
index a1b92966a..2fa4cb64c 100644
--- a/app/views/editor/level/thangs_tab_view.coffee
+++ b/app/views/editor/level/thangs_tab_view.coffee
@@ -1,4 +1,4 @@
-View = require 'views/kinds/CocoView'
+CocoView = require 'views/kinds/CocoView'
 AddThangsView = require './add_thangs_view'
 thangs_template = require 'templates/editor/level/thangs_tab'
 Level = require 'models/Level'
@@ -24,7 +24,7 @@ class ThangTypeSearchCollection extends CocoCollection
   url: '/db/thang.type?project=original,name,version,slug,kind,components'
   model: ThangType
 
-module.exports = class ThangsTabView extends View
+module.exports = class ThangsTabView extends CocoView
   id: 'editor-level-thangs-tab-view'
   className: 'tab-pane active'
   template: thangs_template
diff --git a/app/views/play/level/control_bar_view.coffee b/app/views/play/level/control_bar_view.coffee
index 7a1dd58ec..18102be0f 100644
--- a/app/views/play/level/control_bar_view.coffee
+++ b/app/views/play/level/control_bar_view.coffee
@@ -1,11 +1,11 @@
-View = require 'views/kinds/CocoView'
+CocoView = require 'views/kinds/CocoView'
 template = require 'templates/play/level/control_bar'
 
 DocsModal = require './modal/docs_modal'
 MultiplayerModal = require './modal/multiplayer_modal'
 ReloadModal = require './modal/reload_modal'
 
-module.exports = class ControlBarView extends View
+module.exports = class ControlBarView extends CocoView
   id: 'control-bar-view'
   template: template
 
diff --git a/app/views/play/level/goals_view.coffee b/app/views/play/level/goals_view.coffee
index e55d881b8..1264ada34 100644
--- a/app/views/play/level/goals_view.coffee
+++ b/app/views/play/level/goals_view.coffee
@@ -1,4 +1,4 @@
-View = require 'views/kinds/CocoView'
+CocoView = require 'views/kinds/CocoView'
 template = require 'templates/play/level/goals'
 {me} = require 'lib/auth'
 utils = require 'lib/utils'
@@ -8,7 +8,7 @@ stateIconMap =
   success: 'icon-ok'
   failure: 'icon-remove'
 
-module.exports = class GoalsView extends View
+module.exports = class GoalsView extends CocoView
   id: 'goals-view'
   template: template
 
diff --git a/app/views/play/level/gold_view.coffee b/app/views/play/level/gold_view.coffee
index 42ef28572..479fe8966 100644
--- a/app/views/play/level/gold_view.coffee
+++ b/app/views/play/level/gold_view.coffee
@@ -1,8 +1,8 @@
-View = require 'views/kinds/CocoView'
+CocoView = require 'views/kinds/CocoView'
 template = require 'templates/play/level/gold'
 teamTemplate = require 'templates/play/level/team_gold'
 
-module.exports = class GoldView extends View
+module.exports = class GoldView extends CocoView
   id: 'gold-view'
   template: template
 
diff --git a/app/views/play/level/hud_view.coffee b/app/views/play/level/hud_view.coffee
index 75bc68346..a730bedf9 100644
--- a/app/views/play/level/hud_view.coffee
+++ b/app/views/play/level/hud_view.coffee
@@ -1,10 +1,10 @@
-View = require 'views/kinds/CocoView'
+CocoView = require 'views/kinds/CocoView'
 template = require 'templates/play/level/hud'
 prop_template = require 'templates/play/level/hud_prop'
 action_template = require 'templates/play/level/hud_action'
 DialogueAnimator = require './dialogue_animator'
 
-module.exports = class HUDView extends View
+module.exports = class HUDView extends CocoView
   id: 'thang-hud'
   template: template
   dialogueMode: false
diff --git a/app/views/play/level/level_chat_view.coffee b/app/views/play/level/level_chat_view.coffee
index c581563da..5c4fe650a 100644
--- a/app/views/play/level/level_chat_view.coffee
+++ b/app/views/play/level/level_chat_view.coffee
@@ -1,9 +1,9 @@
-View = require 'views/kinds/CocoView'
+CocoView = require 'views/kinds/CocoView'
 template = require 'templates/play/level/chat'
 {me} = require 'lib/auth'
 LevelBus = require 'lib/LevelBus'
 
-module.exports = class LevelChatView extends View
+module.exports = class LevelChatView extends CocoView
   id: 'level-chat-view'
   template: template
   open: false
diff --git a/app/views/play/level/level_loading_view.coffee b/app/views/play/level/level_loading_view.coffee
index 2ed460796..6c40e9de9 100644
--- a/app/views/play/level/level_loading_view.coffee
+++ b/app/views/play/level/level_loading_view.coffee
@@ -1,7 +1,7 @@
-View = require 'views/kinds/CocoView'
+CocoView = require 'views/kinds/CocoView'
 template = require 'templates/play/level/level_loading'
 
-module.exports = class LevelLoadingView extends View
+module.exports = class LevelLoadingView extends CocoView
   id: 'level-loading-view'
   template: template
 
diff --git a/app/views/play/level/playback_view.coffee b/app/views/play/level/playback_view.coffee
index ecaab7080..f089e3c25 100644
--- a/app/views/play/level/playback_view.coffee
+++ b/app/views/play/level/playback_view.coffee
@@ -1,11 +1,11 @@
-View = require 'views/kinds/CocoView'
+CocoView = require 'views/kinds/CocoView'
 template = require 'templates/play/level/playback'
 {me} = require 'lib/auth'
 
 EditorConfigModal = require './modal/editor_config_modal'
 KeyboardShortcutsModal = require './modal/keyboard_shortcuts_modal'
 
-module.exports = class PlaybackView extends View
+module.exports = class PlaybackView extends CocoView
   id: 'playback-view'
   template: template
 
diff --git a/app/views/play/level/thang_avatar_view.coffee b/app/views/play/level/thang_avatar_view.coffee
index 054fb0d1a..90ea72be1 100644
--- a/app/views/play/level/thang_avatar_view.coffee
+++ b/app/views/play/level/thang_avatar_view.coffee
@@ -1,8 +1,8 @@
-View = require 'views/kinds/CocoView'
+CocoView = require 'views/kinds/CocoView'
 template = require 'templates/play/level/thang_avatar'
 ThangType = require 'models/ThangType'
 
-module.exports = class ThangAvatarView extends View
+module.exports = class ThangAvatarView extends CocoView
   className: 'thang-avatar-view'
   template: template
 
diff --git a/app/views/play/level/tome/cast_button_view.coffee b/app/views/play/level/tome/cast_button_view.coffee
index 1eb85c79f..fe82e4c28 100644
--- a/app/views/play/level/tome/cast_button_view.coffee
+++ b/app/views/play/level/tome/cast_button_view.coffee
@@ -1,8 +1,8 @@
-View = require 'views/kinds/CocoView'
+CocoView = require 'views/kinds/CocoView'
 template = require 'templates/play/level/tome/cast_button'
 {me} = require 'lib/auth'
 
-module.exports = class CastButtonView extends View
+module.exports = class CastButtonView extends CocoView
   id: 'cast-button-view'
   template: template
 
diff --git a/app/views/play/level/tome/problem_alert_view.coffee b/app/views/play/level/tome/problem_alert_view.coffee
index 2a77e1632..1756b2775 100644
--- a/app/views/play/level/tome/problem_alert_view.coffee
+++ b/app/views/play/level/tome/problem_alert_view.coffee
@@ -1,8 +1,8 @@
-View = require 'views/kinds/CocoView'
+CocoView = require 'views/kinds/CocoView'
 template = require 'templates/play/level/tome/problem_alert'
 {me} = require 'lib/auth'
 
-module.exports = class ProblemAlertView extends View
+module.exports = class ProblemAlertView extends CocoView
   className: 'problem-alert'
   template: template
 
diff --git a/app/views/play/level/tome/spell_debug_view.coffee b/app/views/play/level/tome/spell_debug_view.coffee
index 54fceb2f5..63e01f1b7 100644
--- a/app/views/play/level/tome/spell_debug_view.coffee
+++ b/app/views/play/level/tome/spell_debug_view.coffee
@@ -1,4 +1,4 @@
-View = require 'views/kinds/CocoView'
+CocoView = require 'views/kinds/CocoView'
 template = require 'templates/play/level/tome/spell_debug'
 Range = ace.require('ace/range').Range
 TokenIterator = ace.require('ace/token_iterator').TokenIterator
@@ -9,7 +9,7 @@ serializedClasses =
   Ellipse: require 'lib/world/ellipse'
   LineSegment: require 'lib/world/line_segment'
 
-module.exports = class DebugView extends View
+module.exports = class DebugView extends CocoView
   className: 'spell-debug-view'
   template: template
 
diff --git a/app/views/play/level/tome/spell_list_entry_thangs_view.coffee b/app/views/play/level/tome/spell_list_entry_thangs_view.coffee
index 43f54f2cd..eeba83590 100644
--- a/app/views/play/level/tome/spell_list_entry_thangs_view.coffee
+++ b/app/views/play/level/tome/spell_list_entry_thangs_view.coffee
@@ -1,8 +1,8 @@
-View = require 'views/kinds/CocoView'
+CocoView = require 'views/kinds/CocoView'
 ThangAvatarView = require 'views/play/level/thang_avatar_view'
 template = require 'templates/play/level/tome/spell_list_entry_thangs'
 
-module.exports = class SpellListEntryThangsView extends View
+module.exports = class SpellListEntryThangsView extends CocoView
   className: 'spell-list-entry-thangs-view'
   template: template
 
diff --git a/app/views/play/level/tome/spell_list_entry_view.coffee b/app/views/play/level/tome/spell_list_entry_view.coffee
index cd39559a8..05f18b23a 100644
--- a/app/views/play/level/tome/spell_list_entry_view.coffee
+++ b/app/views/play/level/tome/spell_list_entry_view.coffee
@@ -1,11 +1,11 @@
 # TODO: This still needs a way to send problem states to its Thang
 
-View = require 'views/kinds/CocoView'
+CocoView = require 'views/kinds/CocoView'
 ThangAvatarView = require 'views/play/level/thang_avatar_view'
 SpellListEntryThangsView = require 'views/play/level/tome/spell_list_entry_thangs_view'
 template = require 'templates/play/level/tome/spell_list_entry'
 
-module.exports = class SpellListEntryView extends View
+module.exports = class SpellListEntryView extends CocoView
   tagName: 'div'  #'li'
   className: 'spell-list-entry-view'
   template: template
diff --git a/app/views/play/level/tome/spell_list_view.coffee b/app/views/play/level/tome/spell_list_view.coffee
index f18eacb9b..9212bd04f 100644
--- a/app/views/play/level/tome/spell_list_view.coffee
+++ b/app/views/play/level/tome/spell_list_view.coffee
@@ -4,12 +4,12 @@
 
 # TODO: showTopDivider should change when we reorder
 
-View = require 'views/kinds/CocoView'
+CocoView = require 'views/kinds/CocoView'
 template = require 'templates/play/level/tome/spell_list'
 {me} = require 'lib/auth'
 SpellListEntryView = require './spell_list_entry_view'
 
-module.exports = class SpellListView extends View
+module.exports = class SpellListView extends CocoView
   className: 'spell-list-view'
   id: 'spell-list-view'
   template: template
diff --git a/app/views/play/level/tome/spell_palette_entry_view.coffee b/app/views/play/level/tome/spell_palette_entry_view.coffee
index 1996b1972..e09116876 100644
--- a/app/views/play/level/tome/spell_palette_entry_view.coffee
+++ b/app/views/play/level/tome/spell_palette_entry_view.coffee
@@ -1,10 +1,10 @@
-View = require 'views/kinds/CocoView'
+CocoView = require 'views/kinds/CocoView'
 template = require 'templates/play/level/tome/spell_palette_entry'
 {me} = require 'lib/auth'
 filters = require 'lib/image_filter'
 DocFormatter = require './doc_formatter'
 
-module.exports = class SpellPaletteEntryView extends View
+module.exports = class SpellPaletteEntryView extends CocoView
   tagName: 'div'  # Could also try <code> instead of <div>, but would need to adjust colors
   className: 'spell-palette-entry-view'
   template: template
diff --git a/app/views/play/level/tome/spell_palette_view.coffee b/app/views/play/level/tome/spell_palette_view.coffee
index 4482da630..89914fb3e 100644
--- a/app/views/play/level/tome/spell_palette_view.coffee
+++ b/app/views/play/level/tome/spell_palette_view.coffee
@@ -1,4 +1,4 @@
-View = require 'views/kinds/CocoView'
+CocoView = require 'views/kinds/CocoView'
 template = require 'templates/play/level/tome/spell_palette'
 {me} = require 'lib/auth'
 filters = require 'lib/image_filter'
@@ -8,7 +8,7 @@ EditorConfigModal = require '../modal/editor_config_modal'
 
 N_ROWS = 4
 
-module.exports = class SpellPaletteView extends View
+module.exports = class SpellPaletteView extends CocoView
   id: 'spell-palette-view'
   template: template
   controlsEnabled: true
diff --git a/app/views/play/level/tome/spell_toolbar_view.coffee b/app/views/play/level/tome/spell_toolbar_view.coffee
index a3f86db10..39916d56c 100644
--- a/app/views/play/level/tome/spell_toolbar_view.coffee
+++ b/app/views/play/level/tome/spell_toolbar_view.coffee
@@ -1,7 +1,7 @@
-View = require 'views/kinds/CocoView'
+CocoView = require 'views/kinds/CocoView'
 template = require 'templates/play/level/tome/spell_toolbar'
 
-module.exports = class SpellToolbarView extends View
+module.exports = class SpellToolbarView extends CocoView
   className: 'spell-toolbar-view'
   template: template
   progressHoverDelay: 500
diff --git a/app/views/play/level/tome/spell_view.coffee b/app/views/play/level/tome/spell_view.coffee
index a92b708f5..3f6ec643d 100644
--- a/app/views/play/level/tome/spell_view.coffee
+++ b/app/views/play/level/tome/spell_view.coffee
@@ -1,4 +1,4 @@
-View = require 'views/kinds/CocoView'
+CocoView = require 'views/kinds/CocoView'
 template = require 'templates/play/level/tome/spell'
 {me} = require 'lib/auth'
 filters = require 'lib/image_filter'
@@ -8,7 +8,7 @@ SpellDebugView = require './spell_debug_view'
 SpellToolbarView = require './spell_toolbar_view'
 LevelComponent = require 'models/LevelComponent'
 
-module.exports = class SpellView extends View
+module.exports = class SpellView extends CocoView
   id: 'spell-view'
   className: 'shown'
   template: template
diff --git a/app/views/play/level/tome/thang_list_entry_view.coffee b/app/views/play/level/tome/thang_list_entry_view.coffee
index 79d9bfa27..06756c898 100644
--- a/app/views/play/level/tome/thang_list_entry_view.coffee
+++ b/app/views/play/level/tome/thang_list_entry_view.coffee
@@ -1,13 +1,13 @@
 # TODO: be useful to add error indicator states to the spellsPopoverTemplate
 # TODO: reordering based on errors isn't working yet
 
-View = require 'views/kinds/CocoView'
+CocoView = require 'views/kinds/CocoView'
 ThangAvatarView = require 'views/play/level/thang_avatar_view'
 template = require 'templates/play/level/tome/thang_list_entry'
 spellsPopoverTemplate = require 'templates/play/level/tome/thang_list_entry_spells'
 {me} = require 'lib/auth'
 
-module.exports = class ThangListEntryView extends View
+module.exports = class ThangListEntryView extends CocoView
   tagName: 'div'  #'li'
   className: 'thang-list-entry-view'
   template: template
diff --git a/app/views/play/level/tome/thang_list_view.coffee b/app/views/play/level/tome/thang_list_view.coffee
index a931e06e7..9f34e2977 100644
--- a/app/views/play/level/tome/thang_list_view.coffee
+++ b/app/views/play/level/tome/thang_list_view.coffee
@@ -1,12 +1,12 @@
 # The ThangListView lives in the code area behind the SpellView, so that when you don't have a spell, you can select any Thang.
 # It just ha a bunch of ThangListEntryViews (which are mostly ThangAvatarViews) in a few sections.
 
-View = require 'views/kinds/CocoView'
+CocoView = require 'views/kinds/CocoView'
 template = require 'templates/play/level/tome/thang_list'
 {me} = require 'lib/auth'
 ThangListEntryView = require './thang_list_entry_view'
 
-module.exports = class ThangListView extends View
+module.exports = class ThangListView extends CocoView
   className: 'thang-list-view'
   id: 'thang-list-view'
   template: template
diff --git a/app/views/play/level/tome/tome_view.coffee b/app/views/play/level/tome/tome_view.coffee
index d709797e7..3ef45258c 100644
--- a/app/views/play/level/tome/tome_view.coffee
+++ b/app/views/play/level/tome/tome_view.coffee
@@ -27,7 +27,7 @@
 # The SpellListView shows spells to which your team has read or readwrite access.
 # It doubles as a Thang selector, since it's there when nothing is selected.
 
-View = require 'views/kinds/CocoView'
+CocoView = require 'views/kinds/CocoView'
 template = require 'templates/play/level/tome/tome'
 {me} = require 'lib/auth'
 Spell = require './spell'
@@ -38,7 +38,7 @@ CastButtonView = require './cast_button_view'
 
 window.SHIM_WORKER_PATH = '/javascripts/workers/catiline_worker_shim.js'
 
-module.exports = class TomeView extends View
+module.exports = class TomeView extends CocoView
   id: 'tome-view'
   template: template
   controlsEnabled: true

From 59b723b890ab856105bf2bc3491fb15cefd8563a Mon Sep 17 00:00:00 2001
From: Scott Erickson <sderickson@gmail.com>
Date: Thu, 17 Jul 2014 17:22:26 -0700
Subject: [PATCH 38/58] Refactoring View to ModalView.

---
 app/views/editor/level/component/new.coffee                | 4 ++--
 app/views/editor/level/fork_view.coffee                    | 4 ++--
 app/views/editor/level/modal/world_select.coffee           | 4 ++--
 app/views/editor/level/system/add.coffee                   | 4 ++--
 app/views/editor/level/system/new.coffee                   | 4 ++--
 app/views/modal/auth_modal.coffee                          | 4 ++--
 app/views/modal/contact_modal.coffee                       | 4 ++--
 app/views/modal/diplomat_suggestion_modal.coffee           | 4 ++--
 app/views/modal/employer_signup_modal.coffee               | 4 ++--
 app/views/modal/model_modal.coffee                         | 4 ++--
 app/views/modal/recover_modal.coffee                       | 4 ++--
 app/views/modal/wizard_settings_modal.coffee               | 4 ++--
 app/views/play/ladder/play_modal.coffee                    | 4 ++--
 app/views/play/level/modal/docs_modal.coffee               | 4 ++--
 app/views/play/level/modal/editor_config_modal.coffee      | 4 ++--
 app/views/play/level/modal/infinite_loop_modal.coffee      | 4 ++--
 app/views/play/level/modal/keyboard_shortcuts_modal.coffee | 4 ++--
 app/views/play/level/modal/multiplayer_modal.coffee        | 4 ++--
 app/views/play/level/modal/reload_modal.coffee             | 4 ++--
 app/views/play/level/modal/victory_modal.coffee            | 4 ++--
 20 files changed, 40 insertions(+), 40 deletions(-)

diff --git a/app/views/editor/level/component/new.coffee b/app/views/editor/level/component/new.coffee
index a1f2985ce..314cf2c86 100644
--- a/app/views/editor/level/component/new.coffee
+++ b/app/views/editor/level/component/new.coffee
@@ -1,10 +1,10 @@
-View = require 'views/kinds/ModalView'
+ModalView = require 'views/kinds/ModalView'
 template = require 'templates/editor/level/component/new'
 LevelComponent = require 'models/LevelComponent'
 forms = require 'lib/forms'
 {me} = require 'lib/auth'
 
-module.exports = class LevelComponentNewView extends View
+module.exports = class LevelComponentNewView extends ModalView
   id: 'editor-level-component-new-modal'
   template: template
   instant: false
diff --git a/app/views/editor/level/fork_view.coffee b/app/views/editor/level/fork_view.coffee
index 522a21b1c..2b3f7cfea 100644
--- a/app/views/editor/level/fork_view.coffee
+++ b/app/views/editor/level/fork_view.coffee
@@ -1,9 +1,9 @@
-View = require 'views/kinds/ModalView'
+ModalView = require 'views/kinds/ModalView'
 template = require 'templates/editor/level/fork'
 forms = require 'lib/forms'
 Level = require 'models/Level'
 
-module.exports = class LevelForkView extends View
+module.exports = class LevelForkView extends ModalView
   id: 'editor-level-fork-modal'
   template: template
   instant: false
diff --git a/app/views/editor/level/modal/world_select.coffee b/app/views/editor/level/modal/world_select.coffee
index adbbd11d3..4274a76ec 100644
--- a/app/views/editor/level/modal/world_select.coffee
+++ b/app/views/editor/level/modal/world_select.coffee
@@ -1,9 +1,9 @@
-View = require 'views/kinds/ModalView'
+ModalView = require 'views/kinds/ModalView'
 template = require 'templates/editor/level/modal/world_select'
 Surface = require 'lib/surface/Surface'
 ThangType = require 'models/ThangType'
 
-module.exports = class WorldSelectModal extends View
+module.exports = class WorldSelectModal extends ModalView
   id: 'select-point-modal'
   template: template
   modalWidthPercent: 80
diff --git a/app/views/editor/level/system/add.coffee b/app/views/editor/level/system/add.coffee
index 28a362809..f0c3b7490 100644
--- a/app/views/editor/level/system/add.coffee
+++ b/app/views/editor/level/system/add.coffee
@@ -1,4 +1,4 @@
-View = require 'views/kinds/ModalView'
+ModalView = require 'views/kinds/ModalView'
 template = require 'templates/editor/level/system/add'
 availableSystemTemplate = require 'templates/editor/level/system/available_system'
 LevelSystem = require 'models/LevelSystem'
@@ -8,7 +8,7 @@ class LevelSystemSearchCollection extends CocoCollection
   url: '/db/level_system'
   model: LevelSystem
 
-module.exports = class LevelSystemAddView extends View
+module.exports = class LevelSystemAddView extends ModalView
   id: 'editor-level-system-add-modal'
   template: template
   instant: true
diff --git a/app/views/editor/level/system/new.coffee b/app/views/editor/level/system/new.coffee
index 1ddd8d158..86b959f01 100644
--- a/app/views/editor/level/system/new.coffee
+++ b/app/views/editor/level/system/new.coffee
@@ -1,10 +1,10 @@
-View = require 'views/kinds/ModalView'
+ModalView = require 'views/kinds/ModalView'
 template = require 'templates/editor/level/system/new'
 LevelSystem = require 'models/LevelSystem'
 forms = require 'lib/forms'
 {me} = require 'lib/auth'
 
-module.exports = class LevelSystemNewView extends View
+module.exports = class LevelSystemNewView extends ModalView
   id: 'editor-level-system-new-modal'
   template: template
   instant: false
diff --git a/app/views/modal/auth_modal.coffee b/app/views/modal/auth_modal.coffee
index 9d32de0ae..ead7af8b9 100644
--- a/app/views/modal/auth_modal.coffee
+++ b/app/views/modal/auth_modal.coffee
@@ -1,11 +1,11 @@
-View = require 'views/kinds/ModalView'
+ModalView = require 'views/kinds/ModalView'
 template = require 'templates/modal/auth'
 {loginUser, createUser, me} = require 'lib/auth'
 forms = require 'lib/forms'
 User = require 'models/User'
 application  = require 'application'
 
-module.exports = class AuthModalView extends View
+module.exports = class AuthModalView extends ModalView
   id: 'auth-modal'
   template: template
   mode: 'login' # or 'signup'
diff --git a/app/views/modal/contact_modal.coffee b/app/views/modal/contact_modal.coffee
index 0851c9ee9..c8a6db460 100644
--- a/app/views/modal/contact_modal.coffee
+++ b/app/views/modal/contact_modal.coffee
@@ -1,4 +1,4 @@
-View = require 'views/kinds/ModalView'
+ModalView = require 'views/kinds/ModalView'
 template = require 'templates/modal/contact'
 
 forms = require 'lib/forms'
@@ -18,7 +18,7 @@ contactSchema =
       type: 'string'
       minLength: 1
 
-module.exports = class ContactView extends View
+module.exports = class ContactView extends ModalView
   id: 'contact-modal'
   template: template
   closeButton: true
diff --git a/app/views/modal/diplomat_suggestion_modal.coffee b/app/views/modal/diplomat_suggestion_modal.coffee
index 48312ad36..c0abed5e7 100644
--- a/app/views/modal/diplomat_suggestion_modal.coffee
+++ b/app/views/modal/diplomat_suggestion_modal.coffee
@@ -1,9 +1,9 @@
-View = require 'views/kinds/ModalView'
+ModalView = require 'views/kinds/ModalView'
 template = require 'templates/modal/diplomat_suggestion'
 {me} = require 'lib/auth'
 forms = require 'lib/forms'
 
-module.exports = class DiplomatSuggestionView extends View
+module.exports = class DiplomatSuggestionView extends ModalView
   id: 'diplomat-suggestion-modal'
   template: template
 
diff --git a/app/views/modal/employer_signup_modal.coffee b/app/views/modal/employer_signup_modal.coffee
index 5355e26c9..db766d979 100644
--- a/app/views/modal/employer_signup_modal.coffee
+++ b/app/views/modal/employer_signup_modal.coffee
@@ -1,11 +1,11 @@
-View = require 'views/kinds/ModalView'
+ModalView = require 'views/kinds/ModalView'
 template = require 'templates/modal/employer_signup_modal'
 forms = require 'lib/forms'
 User = require 'models/User'
 auth = require 'lib/auth'
 me = auth.me
 
-module.exports = class EmployerSignupView extends View
+module.exports = class EmployerSignupView extends ModalView
   id: 'employer-signup'
   template: template
   closeButton: true
diff --git a/app/views/modal/model_modal.coffee b/app/views/modal/model_modal.coffee
index 50b0cdd8a..a5fbc5ce5 100644
--- a/app/views/modal/model_modal.coffee
+++ b/app/views/modal/model_modal.coffee
@@ -1,7 +1,7 @@
-View = require 'views/kinds/ModalView'
+ModalView = require 'views/kinds/ModalView'
 template = require 'templates/modal/model'
 
-module.exports = class ModelModal extends View
+module.exports = class ModelModal extends ModalView
   id: 'model-modal'
   template: template
   plain: true
diff --git a/app/views/modal/recover_modal.coffee b/app/views/modal/recover_modal.coffee
index c65fc1f8a..5f8e9a17d 100644
--- a/app/views/modal/recover_modal.coffee
+++ b/app/views/modal/recover_modal.coffee
@@ -1,4 +1,4 @@
-View = require 'views/kinds/ModalView'
+ModalView = require 'views/kinds/ModalView'
 template = require 'templates/modal/recover'
 forms = require 'lib/forms'
 {genericFailure} = require 'lib/errors'
@@ -9,7 +9,7 @@ filterKeyboardEvents = (allowedEvents, func) ->
     return unless e.keyCode in allowedEvents or not e.keyCode
     return func(splat...)
 
-module.exports = class RecoverModalView extends View
+module.exports = class RecoverModalView extends ModalView
   id: 'recover-modal'
   template: template
 
diff --git a/app/views/modal/wizard_settings_modal.coffee b/app/views/modal/wizard_settings_modal.coffee
index 12732b28e..d8527ee74 100644
--- a/app/views/modal/wizard_settings_modal.coffee
+++ b/app/views/modal/wizard_settings_modal.coffee
@@ -1,4 +1,4 @@
-View = require 'views/kinds/ModalView'
+ModalView = require 'views/kinds/ModalView'
 template = require 'templates/modal/wizard_settings'
 WizardSprite = require 'lib/surface/WizardSprite'
 ThangType = require 'models/ThangType'
@@ -6,7 +6,7 @@ ThangType = require 'models/ThangType'
 forms = require 'lib/forms'
 User = require 'models/User'
 
-module.exports = class WizardSettingsModal extends View
+module.exports = class WizardSettingsModal extends ModalView
   id: 'wizard-settings-modal'
   template: template
   closesOnClickOutside: false
diff --git a/app/views/play/ladder/play_modal.coffee b/app/views/play/ladder/play_modal.coffee
index 41bf1e22b..0d7494950 100644
--- a/app/views/play/ladder/play_modal.coffee
+++ b/app/views/play/ladder/play_modal.coffee
@@ -1,11 +1,11 @@
-View = require 'views/kinds/ModalView'
+ModalView = require 'views/kinds/ModalView'
 template = require 'templates/play/ladder/play_modal'
 ThangType = require 'models/ThangType'
 {me} = require 'lib/auth'
 LeaderboardCollection = require 'collections/LeaderboardCollection'
 {teamDataFromLevel} = require './utils'
 
-module.exports = class LadderPlayModal extends View
+module.exports = class LadderPlayModal extends ModalView
   id: 'ladder-play-modal'
   template: template
   closeButton: true
diff --git a/app/views/play/level/modal/docs_modal.coffee b/app/views/play/level/modal/docs_modal.coffee
index 9970b8916..a046df051 100644
--- a/app/views/play/level/modal/docs_modal.coffee
+++ b/app/views/play/level/modal/docs_modal.coffee
@@ -1,11 +1,11 @@
-View = require 'views/kinds/ModalView'
+ModalView = require 'views/kinds/ModalView'
 template = require 'templates/play/level/modal/docs'
 Article = require 'models/Article'
 utils = require 'lib/utils'
 
 # let's implement this once we have the docs database schema set up
 
-module.exports = class DocsModal extends View
+module.exports = class DocsModal extends ModalView
   template: template
   id: 'docs-modal'
 
diff --git a/app/views/play/level/modal/editor_config_modal.coffee b/app/views/play/level/modal/editor_config_modal.coffee
index 5f8fd878f..c7dc162d1 100644
--- a/app/views/play/level/modal/editor_config_modal.coffee
+++ b/app/views/play/level/modal/editor_config_modal.coffee
@@ -1,8 +1,8 @@
-View = require 'views/kinds/ModalView'
+ModalView = require 'views/kinds/ModalView'
 template = require 'templates/play/level/modal/editor_config'
 {me} = require 'lib/auth'
 
-module.exports = class EditorConfigModal extends View
+module.exports = class EditorConfigModal extends ModalView
   id: 'level-editor-config-modal'
   template: template
   aceConfig: {}
diff --git a/app/views/play/level/modal/infinite_loop_modal.coffee b/app/views/play/level/modal/infinite_loop_modal.coffee
index ff89e229f..6436c7667 100644
--- a/app/views/play/level/modal/infinite_loop_modal.coffee
+++ b/app/views/play/level/modal/infinite_loop_modal.coffee
@@ -1,7 +1,7 @@
-View = require 'views/kinds/ModalView'
+ModalView = require 'views/kinds/ModalView'
 template = require 'templates/play/level/modal/infinite_loop'
 
-module.exports = class InfiniteLoopModal extends View
+module.exports = class InfiniteLoopModal extends ModalView
   id: '#infinite-loop-modal'
   template: template
 
diff --git a/app/views/play/level/modal/keyboard_shortcuts_modal.coffee b/app/views/play/level/modal/keyboard_shortcuts_modal.coffee
index 816bd3f10..41c15df9d 100644
--- a/app/views/play/level/modal/keyboard_shortcuts_modal.coffee
+++ b/app/views/play/level/modal/keyboard_shortcuts_modal.coffee
@@ -1,7 +1,7 @@
-View = require 'views/kinds/ModalView'
+ModalView = require 'views/kinds/ModalView'
 template = require 'templates/play/level/modal/keyboard_shortcuts'
 
-module.exports = class KeyboardShortcutsModal extends View
+module.exports = class KeyboardShortcutsModal extends ModalView
   id: 'keyboard-shortcuts-modal'
   template: template
 
diff --git a/app/views/play/level/modal/multiplayer_modal.coffee b/app/views/play/level/modal/multiplayer_modal.coffee
index c7e02b157..6645ca2f3 100644
--- a/app/views/play/level/modal/multiplayer_modal.coffee
+++ b/app/views/play/level/modal/multiplayer_modal.coffee
@@ -1,9 +1,9 @@
-View = require 'views/kinds/ModalView'
+ModalView = require 'views/kinds/ModalView'
 template = require 'templates/play/level/modal/multiplayer'
 {me} = require 'lib/auth'
 LadderSubmissionView = require 'views/play/common/ladder_submission_view'
 
-module.exports = class MultiplayerModal extends View
+module.exports = class MultiplayerModal extends ModalView
   id: 'level-multiplayer-modal'
   template: template
 
diff --git a/app/views/play/level/modal/reload_modal.coffee b/app/views/play/level/modal/reload_modal.coffee
index f8b454f1c..f7089e05c 100644
--- a/app/views/play/level/modal/reload_modal.coffee
+++ b/app/views/play/level/modal/reload_modal.coffee
@@ -1,9 +1,9 @@
-View = require 'views/kinds/ModalView'
+ModalView = require 'views/kinds/ModalView'
 template = require 'templates/play/level/modal/reload'
 
 # let's implement this once we have the docs database schema set up
 
-module.exports = class ReloadModal extends View
+module.exports = class ReloadModal extends ModalView
   id: '#reload-code-modal'
   template: template
 
diff --git a/app/views/play/level/modal/victory_modal.coffee b/app/views/play/level/modal/victory_modal.coffee
index 6ee9cabef..03c8d72d8 100644
--- a/app/views/play/level/modal/victory_modal.coffee
+++ b/app/views/play/level/modal/victory_modal.coffee
@@ -1,11 +1,11 @@
-View = require 'views/kinds/ModalView'
+ModalView = require 'views/kinds/ModalView'
 template = require 'templates/play/level/modal/victory'
 {me} = require 'lib/auth'
 LadderSubmissionView = require 'views/play/common/ladder_submission_view'
 LevelFeedback = require 'models/LevelFeedback'
 utils = require 'lib/utils'
 
-module.exports = class VictoryModal extends View
+module.exports = class VictoryModal extends ModalView
   id: 'level-victory-modal'
   template: template
 

From 2d7b6eb1452f30f03b48298f52249baff61eb6ff Mon Sep 17 00:00:00 2001
From: Nick Winter <livelily@gmail.com>
Date: Thu, 17 Jul 2014 20:12:59 -0700
Subject: [PATCH 39/58] Updated code language logos. Added code language blurb
 i18n tags.

---
 .../images/common/code_languages/c_icon.png   | Bin 0 -> 3108 bytes
 .../common/code_languages/clojure_icon.png    | Bin 0 -> 3094 bytes
 .../code_languages/clojure_small.png}         | Bin
 .../code_languages/coffeescript_icon.png      | Bin 0 -> 3018 bytes
 .../code_languages/coffeescript_small.png}    | Bin
 .../images/common/code_languages/cpp_icon.png | Bin 0 -> 3093 bytes
 .../common/code_languages/csharp_icon.png     | Bin 0 -> 3077 bytes
 .../images/common/code_languages/go_icon.png  | Bin 0 -> 2983 bytes
 .../images/common/code_languages/io_icon.png  | Bin 0 -> 4113 bytes
 .../code_languages/io_small.png}              | Bin
 .../common/code_languages/java_icon.png       | Bin 0 -> 3105 bytes
 .../common/code_languages/javascript_icon.png | Bin 0 -> 3976 bytes
 .../code_languages/javascript_small.png}      | Bin
 .../images/common/code_languages/lua_icon.png | Bin 0 -> 2917 bytes
 .../code_languages/lua_small.png}             | Bin
 .../images/common/code_languages/php_icon.png | Bin 0 -> 3020 bytes
 .../common/code_languages/python_icon.png     | Bin 0 -> 3008 bytes
 .../code_languages/python_small.png}          | Bin
 .../common/code_languages/ruby_icon.png       | Bin 0 -> 3073 bytes
 .../common/code_languages/swift_icon.png      | Bin 0 -> 2961 bytes
 app/locale/en.coffee                          |   6 ++++
 app/styles/home.sass                          |  17 ++++++++---
 app/styles/play/ladder/ladder_tab.sass        |   5 ++--
 app/styles/play/ladder/my_matches_tab.sass    |   5 ++--
 app/styles/play/ladder/play_modal.sass        |  10 +++----
 app/styles/play/level/tome/spell_palette.sass |  28 +++++++++++-------
 app/templates/home.jade                       |  12 ++++----
 app/templates/play/ladder/ladder_tab.jade     |   4 +--
 app/templates/play/ladder/my_matches_tab.jade |   2 +-
 app/templates/play/ladder/play_modal.jade     |   8 ++---
 app/views/home_view.coffee                    |   2 +-
 31 files changed, 59 insertions(+), 40 deletions(-)
 create mode 100755 app/assets/images/common/code_languages/c_icon.png
 create mode 100755 app/assets/images/common/code_languages/clojure_icon.png
 rename app/assets/images/{pages/home/language_logo_clojure.png => common/code_languages/clojure_small.png} (100%)
 create mode 100755 app/assets/images/common/code_languages/coffeescript_icon.png
 rename app/assets/images/{pages/home/language_logo_coffeescript.png => common/code_languages/coffeescript_small.png} (100%)
 create mode 100755 app/assets/images/common/code_languages/cpp_icon.png
 create mode 100755 app/assets/images/common/code_languages/csharp_icon.png
 create mode 100755 app/assets/images/common/code_languages/go_icon.png
 create mode 100644 app/assets/images/common/code_languages/io_icon.png
 rename app/assets/images/{pages/home/language_logo_io.png => common/code_languages/io_small.png} (100%)
 create mode 100755 app/assets/images/common/code_languages/java_icon.png
 create mode 100644 app/assets/images/common/code_languages/javascript_icon.png
 rename app/assets/images/{pages/home/language_logo_javascript.png => common/code_languages/javascript_small.png} (100%)
 create mode 100755 app/assets/images/common/code_languages/lua_icon.png
 rename app/assets/images/{pages/home/language_logo_lua.png => common/code_languages/lua_small.png} (100%)
 create mode 100755 app/assets/images/common/code_languages/php_icon.png
 create mode 100755 app/assets/images/common/code_languages/python_icon.png
 rename app/assets/images/{pages/home/language_logo_python.png => common/code_languages/python_small.png} (100%)
 create mode 100755 app/assets/images/common/code_languages/ruby_icon.png
 create mode 100755 app/assets/images/common/code_languages/swift_icon.png

diff --git a/app/assets/images/common/code_languages/c_icon.png b/app/assets/images/common/code_languages/c_icon.png
new file mode 100755
index 0000000000000000000000000000000000000000..99cd55241df4b94612ea0f61f6984561304c52cf
GIT binary patch
literal 3108
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

literal 0
HcmV?d00001

diff --git a/app/assets/images/common/code_languages/clojure_icon.png b/app/assets/images/common/code_languages/clojure_icon.png
new file mode 100755
index 0000000000000000000000000000000000000000..7152f84c0ca9f772194cf8da1a4ae67426686d9a
GIT binary patch
literal 3094
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

literal 0
HcmV?d00001

diff --git a/app/assets/images/pages/home/language_logo_clojure.png b/app/assets/images/common/code_languages/clojure_small.png
similarity index 100%
rename from app/assets/images/pages/home/language_logo_clojure.png
rename to app/assets/images/common/code_languages/clojure_small.png
diff --git a/app/assets/images/common/code_languages/coffeescript_icon.png b/app/assets/images/common/code_languages/coffeescript_icon.png
new file mode 100755
index 0000000000000000000000000000000000000000..502db9b06bc3af2ad3060afe03588aba55619110
GIT binary patch
literal 3018
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
M07*qoM6N<$f)%@!EC2ui

literal 0
HcmV?d00001

diff --git a/app/assets/images/pages/home/language_logo_coffeescript.png b/app/assets/images/common/code_languages/coffeescript_small.png
similarity index 100%
rename from app/assets/images/pages/home/language_logo_coffeescript.png
rename to app/assets/images/common/code_languages/coffeescript_small.png
diff --git a/app/assets/images/common/code_languages/cpp_icon.png b/app/assets/images/common/code_languages/cpp_icon.png
new file mode 100755
index 0000000000000000000000000000000000000000..c3067378cca155e9e81de53c6adf38e294f1c2cb
GIT binary patch
literal 3093
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

literal 0
HcmV?d00001

diff --git a/app/assets/images/common/code_languages/csharp_icon.png b/app/assets/images/common/code_languages/csharp_icon.png
new file mode 100755
index 0000000000000000000000000000000000000000..d3eff9260c6f09acaddc205ec7c31d94fc67128e
GIT binary patch
literal 3077
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
Tlxi+a00000NkvXXu0mjfW<0v?

literal 0
HcmV?d00001

diff --git a/app/assets/images/common/code_languages/go_icon.png b/app/assets/images/common/code_languages/go_icon.png
new file mode 100755
index 0000000000000000000000000000000000000000..ecbfb0d6ab769009983d760404a64aa92b6363d5
GIT binary patch
literal 2983
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

literal 0
HcmV?d00001

diff --git a/app/assets/images/common/code_languages/io_icon.png b/app/assets/images/common/code_languages/io_icon.png
new file mode 100644
index 0000000000000000000000000000000000000000..0b6c58fe4eafcd179cb0df77a7fe4123a42c8903
GIT binary patch
literal 4113
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

literal 0
HcmV?d00001

diff --git a/app/assets/images/pages/home/language_logo_io.png b/app/assets/images/common/code_languages/io_small.png
similarity index 100%
rename from app/assets/images/pages/home/language_logo_io.png
rename to app/assets/images/common/code_languages/io_small.png
diff --git a/app/assets/images/common/code_languages/java_icon.png b/app/assets/images/common/code_languages/java_icon.png
new file mode 100755
index 0000000000000000000000000000000000000000..e39879caeb661b8ae5d8f969991c3f49ee21ccaa
GIT binary patch
literal 3105
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

literal 0
HcmV?d00001

diff --git a/app/assets/images/common/code_languages/javascript_icon.png b/app/assets/images/common/code_languages/javascript_icon.png
new file mode 100644
index 0000000000000000000000000000000000000000..4580f350b4b9412f0dbd539340325962c5bbba0e
GIT binary patch
literal 3976
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
F{{(R7Ih+6h

literal 0
HcmV?d00001

diff --git a/app/assets/images/pages/home/language_logo_javascript.png b/app/assets/images/common/code_languages/javascript_small.png
similarity index 100%
rename from app/assets/images/pages/home/language_logo_javascript.png
rename to app/assets/images/common/code_languages/javascript_small.png
diff --git a/app/assets/images/common/code_languages/lua_icon.png b/app/assets/images/common/code_languages/lua_icon.png
new file mode 100755
index 0000000000000000000000000000000000000000..e97873a331f62e51f94b8fa374a596233ebf6510
GIT binary patch
literal 2917
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
P00000NkvXXu0mjfDMxEp

literal 0
HcmV?d00001

diff --git a/app/assets/images/pages/home/language_logo_lua.png b/app/assets/images/common/code_languages/lua_small.png
similarity index 100%
rename from app/assets/images/pages/home/language_logo_lua.png
rename to app/assets/images/common/code_languages/lua_small.png
diff --git a/app/assets/images/common/code_languages/php_icon.png b/app/assets/images/common/code_languages/php_icon.png
new file mode 100755
index 0000000000000000000000000000000000000000..35757de0b61b2f778df0e3ef459938f74ef5f350
GIT binary patch
literal 3020
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
O0000<MNUMnLSTYoi=V{+

literal 0
HcmV?d00001

diff --git a/app/assets/images/common/code_languages/python_icon.png b/app/assets/images/common/code_languages/python_icon.png
new file mode 100755
index 0000000000000000000000000000000000000000..b8575c4f842679491f5c631b62a76d18062200c6
GIT binary patch
literal 3008
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
CK##fr

literal 0
HcmV?d00001

diff --git a/app/assets/images/pages/home/language_logo_python.png b/app/assets/images/common/code_languages/python_small.png
similarity index 100%
rename from app/assets/images/pages/home/language_logo_python.png
rename to app/assets/images/common/code_languages/python_small.png
diff --git a/app/assets/images/common/code_languages/ruby_icon.png b/app/assets/images/common/code_languages/ruby_icon.png
new file mode 100755
index 0000000000000000000000000000000000000000..7e1192d7abf52cba6f1f82b272051b79c867ed81
GIT binary patch
literal 3073
zcmV+c4F2<pP)<h;3K|Lk000e1NJLTq000mG000mO1^@s6AM^iV00009a7bBm000XU
z000XU0RWnu7ytkYPiaF#P*7-ZbZ>KLZ*U+<Lqi~Na&Km7Y-Iodc-oy)XH-+^7Crag
z^g>IBfRsybQWXdwQbLP>6p<z>Aqfylh#{fb6;Z(vMMVS~$e@S=j*ftg6;Uh<iVD~V
z<RPMtgQJLw%KPDaqifc@_vX$1wbwr9tn;0-&j-K=43<bUQ8j=JsX`tR;Dg7+#^K~H
zK!FM*Z~zbpvt%K2{UZSY_<lS*D<Z%Lz5oGu(+dayz)hRLFdT>f59&ghTmgWD0l;*T
zI7<kC6aYYajzXpYKt=(8otP$50H6c_V9R4-;{Z@C0AMG7=F<Rxo%or10RUT+Ar%3j
zkpLhQWr#!oXgdI`&sK^>09Y^p6lP1rIRMx#05C~cW=H_Aw*bJ-5DT&Z2n+x)QHX^p
z00esgV8|mQcmRZ%02D^@S3L16t`O%c004NIvOKvYIYoh62rY33S640`D9%Y2D-<?i
z0%4j!F2Z@488U%158(66005wo6%pWr^Zj_v4zAA5HjcIqUoGmt2LB>rV&neh&#Q1i
z007~1e$oCcFS8neI|hJl{-P!B1ZZ9hpmq0)X0i`JwE&>$+E?>%_<lS*MWK+n+1cgf
z<k(8YLR(?VSAG6x!e78w{cQPuJpA|d;J)G{fihizM+Erb!p!tcr5w+a34~(Y=8s4G
zw+sLL9n&JjNn*KJDiq^U5^;`1nvC-@r6P$!k}1U{(*I=Q-z@tBKHoI}uxdU5dyy@u
zU1J0GOD7Ombim^G008p4Z^6_k2m^p<gW=D2|L;HjN1!DDfM!XOaR2~bL?kX$%CkSm
z2mk;?pn)o|K^yeJ7%adB9Ki+L!3+FgHiSYX#KJ-lLJDMn9CBbOtb#%)hRv`YDqt_v
zKpix|QD}yfa1JiQRk#j4a1Z)n2%f<xynzV>LC6RbVIkUx0b+_+BaR3cnT7Zv!AJxW
zizFb)h!jyGOOZ85F;a?DAXP{m@;!0_Ifq<Ex{*7`05XF7hP+2Hl!3BQJ=6@fL%FCo
z8iYoo3(#bAF`ADSpqtQgv>H8(HlgRxt7s3}k3K`kFu>>-2Q$QMFfPW!La{h336o>X
zu_CMttHv6zR;&ZNiS=X8v3CR#fknUxHUxJ<AYmRsNLWl*PS{AOARHt#5!wki2?K;t
z!Y3k=s7tgax)J%r7-BLphge7~Bi0g+6E6^Zh(p9TBoc{3GAFr^0!gu?RMHaCM$&Fl
zBk3%un>0uoBa_M6WNWeqIg~6QE69c9o#eyhGvpiOA@W-aonk<7r1(?fC{oI5N*U!4
z<uv66WtcKSRim0x-Ke2d5jBrmLam{;Qm;{ms1r1GnmNsb7D-E`t)i9F8fX`2_i3-_
zbh;7Ul^#x)&{xvS=|||7=mYe33=M`AgU5(xC>fg=2N-7=cNnjjOr{yriy6mMFgG#l
znCF=fnQv8CDz++o6_Lscl}eQ+l^ZHARH>?_s@|##Rr6KLRFA1%Q+=*RRWnoLsR`7U
zt5vF<Q0r40Q)j6=sE4X&sBct1q<&fbi3VB2Ov6t@q*0);U*o*SAPZv|vv@2aYYnT0
zb%8a+Cb7-ge0D0knEf5Qi#@8Tp*ce{N;6lpQuCB%KL_KOarm5cP6_8Ir<e17iry6O
zDdH&`rZh~sF=bq9s+O0QSgS~@QL9Jmy*94xr=6y~MY~!1fet~(N+(<=M`w@D1)b+p
z*;C!83a1uLJv#NSE~;y#8=<>IcfW3@?wFpwUVxrVZ>QdQz32KIeJ}k~{cZZE^+ya?
z2D1z#2HOnI7(B%_ac?{wFUQ;QQA1tBKtrWrm0_3Rgps+?Jfqb{jYbcQX~taRB;#$y
zZN{S}1|}gUOHJxc?wV3fxuz+mJ4`!F$IZ;mqRrNsHJd##*D~ju=bP7?-?v~|cv>vB
zsJ6IeNwVZxrdjT`yl#bBIa#GxRa#xMMy;K#CDyyGyQdMSxlWT#tDe?p!?5wT$+oGt
z8L;Kp2HUQ-ZMJ=3XJQv;x5ci*?vuTfeY$;({XGW_huIFR9a<fJbF^|4I#xQ~n$Dc=
zKYhjYmgz5NSkDm8*fZm{6U!;YX`NG>(?@3)XSs8O^N5RyOM=TTmp(3=8^+zpz2r)C
z^>JO{deZfso3oq3?Wo(Y?l$ge?uXo;%ru`Vo>?<<(8I_>;8Eq#KMS9gFl*neeosSB
zfoHYnBQIkwkyowPu(zdms`p{<7e4kra-ZWq<2*OsGTvEV%s0Td$hXT+!*8Bnh2KMe
zBmZRodjHV?r+_5^X9J0WL4jKW`}lf%A-|44I@@LTvf1rHjG(ze6+w@Jt%Bvjts!X0
z?2xS?_ve_-k<Mujg;0Lz*3buG=3$G&ehepthlN*$KaOySSQ^nWmo<0M+(UEUMEXRQ
zMBbZcF;6+KElM>iKB_KiJlZ$9G`c^=E@oNG)mWWaNo-3TIW8)$Hg0Ub-~8?KhvJ>$
z3*&nim@mj(aCxE5!t{lw7O5^0EIO7zOo&c6l<+|iDySBWCGrz@C5{St!X3hAA}`T4
z(TLbXTq+(;@<=L8dXnssyft|w#WSTW<++3>sgS%(4NTpeI-VAqb|7ssJvzNHgOZVu
zaYCvgO_R1~>SyL=cFU|~g|hy|Zi}}s9+d~lYqOB71z9Z$wnC=pR9Yz4DhIM>Wmjgu
z&56o6maCpC&F##y%G;1PobR9i?GnNg;gYtchD%p19a!eQtZF&3JaKv33gZ<8D~47E
ztUS1iwkmDaPpj=$m#%)jCVEY4fnLGNg2A-`YwHVD3gv};>)hAvT~AmqS>Lr``i7kw
zJ{5_It`yrBmlc25DBO7E8;5VoznR>Ww5hAaxn$2~(q`%A-YuS64wkBy=9dm`4cXeX
z4c}I@?e+FW+b@^RDBHV(wnMq2zdX3SWv9u`%{xC-q*U}&`cyXV(%rRT*Z6MH?i+i&
z_B8C(+grT%{XWUQ+f@NoP1R=AW&26{v-dx)iK^-Nmiuj8txj!m?Z*Ss1N{dh4z}01
z)YTo*JycSU)+_5r4#yw9{+;i4Ee$peRgIj+;v;ZGdF1K$3E%e~4LaI(jC-u%2h$&R
z9cLXcYC@Xwnns&bn)_Q~Te?roKGD|d-g^8;+aC{{G(1^(O7m37Y1-+6)01cN&y1aw
zoqc{T`P^XJqPBbIW6s}d4{z_f5Om?vMgNQEJG?v2T=KYd^0M3I6IZxbny)%vZR&LD
zJpPl@Psh8QyPB@KTx+@RdcC!KX7}kEo;S|j^u2lU7XQ}Oo;f|;z4Ll+_r>@1-xl3|
zawq-H%e&ckC+@AhPrP6BK<z=<L*0kfKU@CX*zeqbYQT4(^U>T#_XdT7&;F71j}Joy
zkC~6lh7E@6o;W@^IpRNZ{ptLtL(gQ-CY~4mqW;US7Zxvm_|@yz&e53Bp_lTPlfP|z
zrTyx_>lv@x#=^!PzR7qqF<$gm`|ZJZ+;<)Cqu&ot<a{81DF0~rvGr5Xr~8u`lav1h
z1DNytV>2z=0000WV@Og>004R=004l4008;_004mL004C`008P>0026e000+nl3&F}
z0003jNkl<Zc-owk%SyvQ7=^zy7X?=?x^Uf{(4ruSAZ~pG!L_dY7<~<wzJlvQ6p=_2
z-DxNYR$P>V$=H~Si#lUw603ON-wgTAIr9&(x}7$rZXaGt{-AEBy=s{T623dwRcGs`
zLja;d9}x!lqlDv&0D#sacs7|bn@qXh?`a_`1)S_{>jowqy}T`~pIdwz{048H-P8<<
zya2$d!v07Au(n)Jl=nB)G8YE${BGCMB^*Wxv1jWBfJ#>t9Y?{@pkITZvibK;(}Ir9
zuNtdYlcgN_&i>Ap2Fp|l-#^B%G|$UK3NCtspHfxzDr`28X;RgN6@X}{t{I3hAhle)
z@<UHGKr>w#gi)d$#-0sda1%6kbNv|)F9QwEM5<=&=Cv_@$qk_V?|cpb1$n}*TpAYf
P00000NkvXXu0mjfD=f2y

literal 0
HcmV?d00001

diff --git a/app/assets/images/common/code_languages/swift_icon.png b/app/assets/images/common/code_languages/swift_icon.png
new file mode 100755
index 0000000000000000000000000000000000000000..e789c15168232d60bb83864e1699406a9b6fbe0c
GIT binary patch
literal 2961
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
Hu0mjfcJg_#

literal 0
HcmV?d00001

diff --git a/app/locale/en.coffee b/app/locale/en.coffee
index a3cf8152b..2b8549b5e 100644
--- a/app/locale/en.coffee
+++ b/app/locale/en.coffee
@@ -100,6 +100,12 @@
     for_beginners: "For Beginners"
     multiplayer: "Multiplayer"
     for_developers: "For Developers"
+    javascript_blurb: "The language of the web. Great for writing websites, web apps, HTML5 games, and servers."
+    python_blurb: "Simple yet powerful, Python is a great general purpose programming language."
+    coffeescript_blurb: "Nicer JavaScript syntax."
+    clojure_blurb: "A modern Lisp."
+    lua_blurb: "Game scripting language."
+    io_blurb: "Simple but obscure."
 
   play:
     choose_your_level: "Choose Your Level"
diff --git a/app/styles/home.sass b/app/styles/home.sass
index c58133fb8..f5abd9c0f 100644
--- a/app/styles/home.sass
+++ b/app/styles/home.sass
@@ -167,6 +167,10 @@
         h2
           margin: 15px 0 5px
 
+        p
+          overflow: hidden
+          height: 40px
+
     .secondary-code-languages
       margin-left: -10px
 
@@ -201,17 +205,22 @@
           margin: 0
           padding: 0
 
+        p
+          white-space: nowrap
+          text-overflow: ellipsis
+          overflow: hidden
+
       #coffeescript .code-language-logo
-        background: transparent url(/images/pages/home/language_logo_coffeescript.png) no-repeat center
+        background: transparent url(/images/common/code_languages/coffeescript_small.png) no-repeat center
 
       #clojure .code-language-logo
-        background: transparent url(/images/pages/home/language_logo_clojure.png) no-repeat center
+        background: transparent url(/images/common/code_languages/clojure_small.png) no-repeat center
 
       #lua .code-language-logo
-        background: transparent url(/images/pages/home/language_logo_lua.png) no-repeat center
+        background: transparent url(/images/common/code_languages/lua_small.png) no-repeat center
 
       #io .code-language-logo
-        background: transparent url(/images/pages/home/language_logo_io.png) no-repeat center
+        background: transparent url(/images/common/code_languages/io_small.png) no-repeat center
 
   
 #multiplayer-launch-modal
diff --git a/app/styles/play/ladder/ladder_tab.sass b/app/styles/play/ladder/ladder_tab.sass
index c92726c9c..2529f6280 100644
--- a/app/styles/play/ladder/ladder_tab.sass
+++ b/app/styles/play/ladder/ladder_tab.sass
@@ -53,6 +53,5 @@
 
   .code-language-cell
     padding: 0 10px
-    background: transparent url(/images/pages/home/language_logo_javascript.png) no-repeat center center
-    background-size: contain
-    height: 19px
+    background: transparent url(/images/common/code_languages/javascript_icon.png) no-repeat center center
+    height: 16px
diff --git a/app/styles/play/ladder/my_matches_tab.sass b/app/styles/play/ladder/my_matches_tab.sass
index 741a3a534..13aca340d 100644
--- a/app/styles/play/ladder/my_matches_tab.sass
+++ b/app/styles/play/ladder/my_matches_tab.sass
@@ -40,6 +40,5 @@
 
   .code-language-cell
     padding: 0 10px
-    background: transparent url(/images/pages/home/language_logo_javascript.png) no-repeat center center
-    background-size: contain
-    height: 19px
+    background: transparent url(/images/common/code_languages/javascript_icon.png) no-repeat center center
+    height: 16px
diff --git a/app/styles/play/ladder/play_modal.sass b/app/styles/play/ladder/play_modal.sass
index 3587c557f..6050df159 100644
--- a/app/styles/play/ladder/play_modal.sass
+++ b/app/styles/play/ladder/play_modal.sass
@@ -98,12 +98,12 @@
 
     .code-language
       position: absolute
-      background: transparent url(/images/pages/home/language_logo_javascript.png) no-repeat center center
+      background: transparent url(/images/common/code_languages/javascript_small.png) no-repeat center center
       background-size: contain
-      width: 40px
-      height: 40px
-      right: -5px
-      top: -15px
+      width: 50px
+      height: 50px
+      right: -0px
+      top: -30px
       display: block
 
   .my-name
diff --git a/app/styles/play/level/tome/spell_palette.sass b/app/styles/play/level/tome/spell_palette.sass
index 3e2f78794..6c5a12f32 100644
--- a/app/styles/play/level/tome/spell_palette.sass
+++ b/app/styles/play/level/tome/spell_palette.sass
@@ -70,10 +70,10 @@
 
   .code-language-logo
     position: absolute
-    width: 20px
-    height: 20px
-    left: 12px
-    top: 34px
+    width: 16px
+    height: 16px
+    left: 16px
+    top: 36px
     z-index: 10
     background-color: transparent
     background-repeat: no-repeat
@@ -81,21 +81,27 @@
     cursor: pointer
 
     &.javascript
-      background-image: url(/images/pages/home/language_logo_javascript.png)
+      background-image: url(/images/common/code_languages/javascript_icon.png)
     &.python
-      background-image: url(/images/pages/home/language_logo_python.png)
+      background-image: url(/images/common/code_languages/python_icon.png)
     &.coffeescript
-      background-image: url(/images/pages/home/language_logo_coffeescript.png)
+      background-image: url(/images/common/code_languages/coffeescript_icon.png)
     &.clojure
-      background-image: url(/images/pages/home/language_logo_clojure.png)
+      background-image: url(/images/common/code_languages/clojure_icon.png)
     &.lua
-      background-image: url(/images/pages/home/language_logo_lua.png)
+      background-image: url(/images/common/code_languages/lua_icon.png)
     &.io
-      background-image: url(/images/pages/home/language_logo_io.png)
+      background-image: url(/images/common/code_languages/io_icon.png)
+
+    &:hover
+      outline: 1px outset #ccc
+
+      &:active
+        outline: 1px inset #ccc
 
 html.no-borderimage
   #spell-palette-view
     span.code-palette-background
       display: none
     img.code-palette-background
-      display: block
\ No newline at end of file
+      display: block
diff --git a/app/templates/home.jade b/app/templates/home.jade
index 02775696a..6d9d939df 100644
--- a/app/templates/home.jade
+++ b/app/templates/home.jade
@@ -10,14 +10,14 @@ block content
         .code-language#javascript(data-code-language='javascript')
           .code-wizard
           h2 JavaScript
-          p The language of the web. Great for writing websites, web apps, HTML5 games, and servers.
+          p(data-i18n="home.javascript_blurb") The language of the web. Great for writing websites, web apps, HTML5 games, and servers.
 
       .col-md-6
         .code-language.beta#python(data-code-language='python')
           .code-wizard
           .code-language-beta
           h2 Python
-          p Simple yet powerful, Python is a great general purpose programming language.
+          p(data-i18n="home.python_blurb") Simple yet powerful, Python is a great general purpose programming language.
 
     .secondary-code-languages.row
       .col-md-3
@@ -26,7 +26,7 @@ block content
           .code-wizard
           .code-language-beta
           h3 CoffeeScript
-          p Nicer JavaScript syntax
+          p(data-i18n="home.coffeescript_blurb") Nicer JavaScript syntax.
 
       .col-md-3
         .code-language.beta#clojure(data-code-language='clojure')
@@ -34,7 +34,7 @@ block content
           .code-wizard
           .code-language-beta
           h3 Clojure
-          p A modern Lisp
+          p(data-i18n="home.clojure_blurb") A modern Lisp.
 
       .col-md-3
         .code-language.beta#lua(data-code-language='lua')
@@ -42,7 +42,7 @@ block content
           .code-wizard
           .code-language-beta
           h3 Lua
-          p Game scripting language
+          p(data-i18n="home.lua_blurb") Game scripting language.
 
       .col-md-3
         .code-language.beta#io(data-code-language='io', title="Careful: Io is still quite buggy")
@@ -50,7 +50,7 @@ block content
           .code-wizard
           .code-language-beta
           h3 Io
-          p Simple but obscure
+          p(data-i18n="home.io_blurb") Simple but obscure.
 
   .alert.alert-danger.lt-ie10
     strong(data-i18n="home.no_ie") CodeCombat does not run in Internet Explorer 9 or older. Sorry!
diff --git a/app/templates/play/ladder/ladder_tab.jade b/app/templates/play/ladder/ladder_tab.jade
index 4d682243a..515397e1f 100644
--- a/app/templates/play/ladder/ladder_tab.jade
+++ b/app/templates/play/ladder/ladder_tab.jade
@@ -21,7 +21,7 @@ div#columns.row
         for session, rank in topSessions
           - var myRow = session.get('creator') == me.id
           tr(class=myRow ? "success" : "", data-player-id=session.get('creator'), data-session-id=session.id)
-            td.code-language-cell(style="background-image: url(/images/pages/home/language_logo_" + session.get('submittedCodeLanguage') + ".png)")
+            td.code-language-cell(style="background-image: url(/images/common/code_languages/" + session.get('submittedCodeLanguage') + "_icon.png)")
             td.rank-cell= rank + 1
             td.score-cell= Math.round(session.get('totalScore') * 100)
             td.name-col-cell= session.get('creatorName') || "Anonymous"
@@ -35,7 +35,7 @@ div#columns.row
           for session in team.leaderboard.nearbySessions()
             - var myRow = session.get('creator') == me.id
             tr(class=myRow ? "success" : "", data-player-id=session.get('creator'), data-session-id=session.id)
-              td.code-language-cell(style="background-image: url(/images/pages/home/language_logo_" + session.get('submittedCodeLanguage') + ".png)")
+              td.code-language-cell(style="background-image: url(/images/common/code_languages/" + session.get('submittedCodeLanguage') + "_icon.png)")
               td.rank-cell= session.rank
               td.score-cell= Math.round(session.get('totalScore') * 100)
               td.name-col-cell= session.get('creatorName') || "Anonymous"
diff --git a/app/templates/play/ladder/my_matches_tab.jade b/app/templates/play/ladder/my_matches_tab.jade
index a08f6651b..bf4d9e856 100644
--- a/app/templates/play/ladder/my_matches_tab.jade
+++ b/app/templates/play/ladder/my_matches_tab.jade
@@ -39,7 +39,7 @@ div#columns.row
                 span(data-i18n="general.loss").loss Loss
               if match.state === 'tie'
                 span(data-i18n="general.tie").tie Tie
-            td.code-language-cell(style="background-image: url(/images/pages/home/language_logo_" + match.codeLanguage +  ".png)")
+            td.code-language-cell(style="background-image: url(/images/common/code_languages/" + match.codeLanguage +  "_icon.png)")
             td.name-cell= match.opponentName || "Anonymous"
             td.time-cell= match.when
             td.battle-cell
diff --git a/app/templates/play/ladder/play_modal.jade b/app/templates/play/ladder/play_modal.jade
index 841203b2f..c25c3a1f5 100644
--- a/app/templates/play/ladder/play_modal.jade
+++ b/app/templates/play/ladder/play_modal.jade
@@ -33,7 +33,7 @@ block modal-body-content
           span= myName
         div.opponent-name.name-label
           span(data-i18n="ladder.simple_ai") Simple AI
-          //span.code-language(style="background-image: url(/images/pages/home/language_logo_javascript.png)")
+          //span.code-language(style="background-image: url(/images/common/code_languages/javascript_small.png)")
         div.difficulty
           span(data-i18n="ladder.warmup") Warmup
         div(data-i18n="ladder.vs").vs VS
@@ -50,7 +50,7 @@ block modal-body-content
           div.opponent-name.name-label
             span= challengers.easy.opponentName
             if challengers.easy.codeLanguage
-              span.code-language(style="background-image: url(/images/pages/home/language_logo_" + challengers.easy.codeLanguage + ".png)")
+              span.code-language(style="background-image: url(/images/common/code_languages/" + challengers.easy.codeLanguage + "_small.png)")
           div.difficulty
             span(data-i18n="general.easy") Easy
           div(data-i18n="ladder.vs").vs VS
@@ -67,7 +67,7 @@ block modal-body-content
           div.opponent-name.name-label
             span= challengers.medium.opponentName
             if challengers.medium.codeLanguage
-              span.code-language(style="background-image: url(/images/pages/home/language_logo_" + challengers.medium.codeLanguage + ".png)")
+              span.code-language(style="background-image: url(/images/common/code_languages/" + challengers.medium.codeLanguage + "_small.png)")
           div.difficulty
             span(data-i18n="general.medium") Medium
           div(data-i18n="ladder.vs").vs VS
@@ -84,7 +84,7 @@ block modal-body-content
           div.opponent-name.name-label
             span= challengers.hard.opponentName
             if challengers.hard.codeLanguage
-              span.code-language(style="background-image: url(/images/pages/home/language_logo_" + challengers.hard.codeLanguage + ".png)")
+              span.code-language(style="background-image: url(/images/common/code_languages/" + challengers.hard.codeLanguage + "_small.png)")
           div.difficulty
             span(data-i18n="general.hard") Hard
           div(data-i18n="ladder.vs").vs VS
diff --git a/app/views/home_view.coffee b/app/views/home_view.coffee
index 40eb72e88..ff3b287c2 100644
--- a/app/views/home_view.coffee
+++ b/app/views/home_view.coffee
@@ -52,7 +52,7 @@ module.exports = class HomeView extends View
     @updateLanguageLogos codeLanguage
 
   updateLanguageLogos: (codeLanguage) ->
-    @$el.find('.game-mode-wrapper .code-language-logo').css('background-image', "url(/images/pages/home/language_logo_#{codeLanguage}.png)").toggleClass 'inverted', (codeLanguage in ['io', 'coffeescript'])
+    @$el.find('.game-mode-wrapper .code-language-logo').css('background-image', "url(/images/common/code_languages/#{codeLanguage}_small.png)").toggleClass 'inverted', (codeLanguage in ['io', 'coffeescript'])
 
   onCodeLanguageSelected: (e) ->
     target = $(e.target).closest('.code-language')

From 207f0adf11e8b7b8d963b4ba816786b60c40f443 Mon Sep 17 00:00:00 2001
From: Nick Winter <livelily@gmail.com>
Date: Thu, 17 Jul 2014 20:13:30 -0700
Subject: [PATCH 40/58] Propagated i18n tags for code language blurbs.

---
 app/locale/ar.coffee          | 6 ++++++
 app/locale/bg.coffee          | 6 ++++++
 app/locale/ca.coffee          | 6 ++++++
 app/locale/cs.coffee          | 6 ++++++
 app/locale/da.coffee          | 6 ++++++
 app/locale/de-AT.coffee       | 6 ++++++
 app/locale/de-CH.coffee       | 6 ++++++
 app/locale/de-DE.coffee       | 6 ++++++
 app/locale/de.coffee          | 6 ++++++
 app/locale/el.coffee          | 6 ++++++
 app/locale/en-AU.coffee       | 6 ++++++
 app/locale/en-GB.coffee       | 6 ++++++
 app/locale/en-US.coffee       | 6 ++++++
 app/locale/es-419.coffee      | 6 ++++++
 app/locale/es-ES.coffee       | 6 ++++++
 app/locale/es.coffee          | 6 ++++++
 app/locale/fa.coffee          | 6 ++++++
 app/locale/fi.coffee          | 6 ++++++
 app/locale/fr.coffee          | 6 ++++++
 app/locale/he.coffee          | 6 ++++++
 app/locale/hi.coffee          | 6 ++++++
 app/locale/hu.coffee          | 6 ++++++
 app/locale/id.coffee          | 6 ++++++
 app/locale/it.coffee          | 6 ++++++
 app/locale/ja.coffee          | 6 ++++++
 app/locale/ko.coffee          | 6 ++++++
 app/locale/lt.coffee          | 6 ++++++
 app/locale/ms.coffee          | 6 ++++++
 app/locale/nb.coffee          | 6 ++++++
 app/locale/nl-BE.coffee       | 6 ++++++
 app/locale/nl-NL.coffee       | 6 ++++++
 app/locale/nl.coffee          | 6 ++++++
 app/locale/nn.coffee          | 6 ++++++
 app/locale/no.coffee          | 6 ++++++
 app/locale/pl.coffee          | 6 ++++++
 app/locale/pt-BR.coffee       | 6 ++++++
 app/locale/pt-PT.coffee       | 6 ++++++
 app/locale/pt.coffee          | 6 ++++++
 app/locale/ro.coffee          | 6 ++++++
 app/locale/ru.coffee          | 6 ++++++
 app/locale/sk.coffee          | 6 ++++++
 app/locale/sl.coffee          | 6 ++++++
 app/locale/sr.coffee          | 6 ++++++
 app/locale/sv.coffee          | 6 ++++++
 app/locale/th.coffee          | 6 ++++++
 app/locale/tr.coffee          | 6 ++++++
 app/locale/uk.coffee          | 6 ++++++
 app/locale/ur.coffee          | 6 ++++++
 app/locale/vi.coffee          | 6 ++++++
 app/locale/zh-HANS.coffee     | 6 ++++++
 app/locale/zh-HANT.coffee     | 6 ++++++
 app/locale/zh-WUU-HANS.coffee | 6 ++++++
 app/locale/zh-WUU-HANT.coffee | 6 ++++++
 app/locale/zh.coffee          | 6 ++++++
 54 files changed, 324 insertions(+)

diff --git a/app/locale/ar.coffee b/app/locale/ar.coffee
index 0d95ef171..40f349b61 100644
--- a/app/locale/ar.coffee
+++ b/app/locale/ar.coffee
@@ -100,6 +100,12 @@ module.exports = nativeDescription: "العربية", englishDescription: "Arabi
 #    for_beginners: "For Beginners"
 #    multiplayer: "Multiplayer"
 #    for_developers: "For Developers"
+#    javascript_blurb: "The language of the web. Great for writing websites, web apps, HTML5 games, and servers."
+#    python_blurb: "Simple yet powerful, Python is a great general purpose programming language."
+#    coffeescript_blurb: "Nicer JavaScript syntax."
+#    clojure_blurb: "A modern Lisp."
+#    lua_blurb: "Game scripting language."
+#    io_blurb: "Simple but obscure."
 
 #  play:
 #    choose_your_level: "Choose Your Level"
diff --git a/app/locale/bg.coffee b/app/locale/bg.coffee
index 5620a6b60..0609ffaf8 100644
--- a/app/locale/bg.coffee
+++ b/app/locale/bg.coffee
@@ -100,6 +100,12 @@ module.exports = nativeDescription: "български език", englishDescri
 #    for_beginners: "For Beginners"
 #    multiplayer: "Multiplayer"
 #    for_developers: "For Developers"
+#    javascript_blurb: "The language of the web. Great for writing websites, web apps, HTML5 games, and servers."
+#    python_blurb: "Simple yet powerful, Python is a great general purpose programming language."
+#    coffeescript_blurb: "Nicer JavaScript syntax."
+#    clojure_blurb: "A modern Lisp."
+#    lua_blurb: "Game scripting language."
+#    io_blurb: "Simple but obscure."
 
   play:
     choose_your_level: "Избери своето ниво"
diff --git a/app/locale/ca.coffee b/app/locale/ca.coffee
index 3a1a35800..0ab50115a 100644
--- a/app/locale/ca.coffee
+++ b/app/locale/ca.coffee
@@ -100,6 +100,12 @@ module.exports = nativeDescription: "Català", englishDescription: "Catalan", tr
     for_beginners: "Per a principiants"
     multiplayer: "Multijugador"
     for_developers: "Per a Desenvolupadors"
+#    javascript_blurb: "The language of the web. Great for writing websites, web apps, HTML5 games, and servers."
+#    python_blurb: "Simple yet powerful, Python is a great general purpose programming language."
+#    coffeescript_blurb: "Nicer JavaScript syntax."
+#    clojure_blurb: "A modern Lisp."
+#    lua_blurb: "Game scripting language."
+#    io_blurb: "Simple but obscure."
 
   play:
     choose_your_level: "Escull el teu nivell"
diff --git a/app/locale/cs.coffee b/app/locale/cs.coffee
index 5836d1889..cd470a43b 100644
--- a/app/locale/cs.coffee
+++ b/app/locale/cs.coffee
@@ -100,6 +100,12 @@ module.exports = nativeDescription: "čeština", englishDescription: "Czech", tr
 #    for_beginners: "For Beginners"
 #    multiplayer: "Multiplayer"
 #    for_developers: "For Developers"
+#    javascript_blurb: "The language of the web. Great for writing websites, web apps, HTML5 games, and servers."
+#    python_blurb: "Simple yet powerful, Python is a great general purpose programming language."
+#    coffeescript_blurb: "Nicer JavaScript syntax."
+#    clojure_blurb: "A modern Lisp."
+#    lua_blurb: "Game scripting language."
+#    io_blurb: "Simple but obscure."
 
   play:
     choose_your_level: "Zvolte si úroveň"
diff --git a/app/locale/da.coffee b/app/locale/da.coffee
index 470764cd8..1ffef227c 100644
--- a/app/locale/da.coffee
+++ b/app/locale/da.coffee
@@ -100,6 +100,12 @@ module.exports = nativeDescription: "dansk", englishDescription: "Danish", trans
     for_beginners: "For Begyndere"
     multiplayer: "Multiplayer"
     for_developers: "For Udviklere"
+#    javascript_blurb: "The language of the web. Great for writing websites, web apps, HTML5 games, and servers."
+#    python_blurb: "Simple yet powerful, Python is a great general purpose programming language."
+#    coffeescript_blurb: "Nicer JavaScript syntax."
+#    clojure_blurb: "A modern Lisp."
+#    lua_blurb: "Game scripting language."
+#    io_blurb: "Simple but obscure."
 
   play:
     choose_your_level: "Vælg Dit Level"
diff --git a/app/locale/de-AT.coffee b/app/locale/de-AT.coffee
index 1242212fd..9c4c0c144 100644
--- a/app/locale/de-AT.coffee
+++ b/app/locale/de-AT.coffee
@@ -100,6 +100,12 @@ module.exports = nativeDescription: "Deutsch (Österreich)", englishDescription:
 #    for_beginners: "For Beginners"
 #    multiplayer: "Multiplayer"
 #    for_developers: "For Developers"
+#    javascript_blurb: "The language of the web. Great for writing websites, web apps, HTML5 games, and servers."
+#    python_blurb: "Simple yet powerful, Python is a great general purpose programming language."
+#    coffeescript_blurb: "Nicer JavaScript syntax."
+#    clojure_blurb: "A modern Lisp."
+#    lua_blurb: "Game scripting language."
+#    io_blurb: "Simple but obscure."
 
 #  play:
 #    choose_your_level: "Choose Your Level"
diff --git a/app/locale/de-CH.coffee b/app/locale/de-CH.coffee
index b8b40dbac..d83d4959a 100644
--- a/app/locale/de-CH.coffee
+++ b/app/locale/de-CH.coffee
@@ -100,6 +100,12 @@ module.exports = nativeDescription: "Deutsch (Schweiz)", englishDescription: "Ge
     for_beginners: "Für Afänger"
     multiplayer: "Multiplayer"
     for_developers: "Für Entwickler"
+#    javascript_blurb: "The language of the web. Great for writing websites, web apps, HTML5 games, and servers."
+#    python_blurb: "Simple yet powerful, Python is a great general purpose programming language."
+#    coffeescript_blurb: "Nicer JavaScript syntax."
+#    clojure_blurb: "A modern Lisp."
+#    lua_blurb: "Game scripting language."
+#    io_blurb: "Simple but obscure."
 
   play:
     choose_your_level: "Wähl dis Level us"
diff --git a/app/locale/de-DE.coffee b/app/locale/de-DE.coffee
index 69570107d..d94fbbbfd 100644
--- a/app/locale/de-DE.coffee
+++ b/app/locale/de-DE.coffee
@@ -100,6 +100,12 @@ module.exports = nativeDescription: "Deutsch (Deutschland)", englishDescription:
     for_beginners: "Für Anfänger"
     multiplayer: "Mehrspieler"
     for_developers: "Für Entwickler"
+#    javascript_blurb: "The language of the web. Great for writing websites, web apps, HTML5 games, and servers."
+#    python_blurb: "Simple yet powerful, Python is a great general purpose programming language."
+#    coffeescript_blurb: "Nicer JavaScript syntax."
+#    clojure_blurb: "A modern Lisp."
+#    lua_blurb: "Game scripting language."
+#    io_blurb: "Simple but obscure."
 
   play:
     choose_your_level: "Wähle dein Level"
diff --git a/app/locale/de.coffee b/app/locale/de.coffee
index 4f83a118e..aa72ab375 100644
--- a/app/locale/de.coffee
+++ b/app/locale/de.coffee
@@ -100,6 +100,12 @@ module.exports = nativeDescription: "Deutsch", englishDescription: "German", tra
     for_beginners: "Für Anfänger"
     multiplayer: "Mehrspieler"
     for_developers: "Für Entwickler"
+#    javascript_blurb: "The language of the web. Great for writing websites, web apps, HTML5 games, and servers."
+#    python_blurb: "Simple yet powerful, Python is a great general purpose programming language."
+#    coffeescript_blurb: "Nicer JavaScript syntax."
+#    clojure_blurb: "A modern Lisp."
+#    lua_blurb: "Game scripting language."
+#    io_blurb: "Simple but obscure."
 
   play:
     choose_your_level: "Wähle dein Level"
diff --git a/app/locale/el.coffee b/app/locale/el.coffee
index 41d735d5d..0405a50f3 100644
--- a/app/locale/el.coffee
+++ b/app/locale/el.coffee
@@ -100,6 +100,12 @@ module.exports = nativeDescription: "ελληνικά", englishDescription: "Gre
     for_beginners: "Για αρχάριους"
 #    multiplayer: "Multiplayer"
     for_developers: "Για προγραμματιστές"
+#    javascript_blurb: "The language of the web. Great for writing websites, web apps, HTML5 games, and servers."
+#    python_blurb: "Simple yet powerful, Python is a great general purpose programming language."
+#    coffeescript_blurb: "Nicer JavaScript syntax."
+#    clojure_blurb: "A modern Lisp."
+#    lua_blurb: "Game scripting language."
+#    io_blurb: "Simple but obscure."
 
   play:
     choose_your_level: "Διάλεξε την πίστα σου"
diff --git a/app/locale/en-AU.coffee b/app/locale/en-AU.coffee
index 29d87cbe7..772111136 100644
--- a/app/locale/en-AU.coffee
+++ b/app/locale/en-AU.coffee
@@ -100,6 +100,12 @@ module.exports = nativeDescription: "English (AU)", englishDescription: "English
 #    for_beginners: "For Beginners"
 #    multiplayer: "Multiplayer"
 #    for_developers: "For Developers"
+#    javascript_blurb: "The language of the web. Great for writing websites, web apps, HTML5 games, and servers."
+#    python_blurb: "Simple yet powerful, Python is a great general purpose programming language."
+#    coffeescript_blurb: "Nicer JavaScript syntax."
+#    clojure_blurb: "A modern Lisp."
+#    lua_blurb: "Game scripting language."
+#    io_blurb: "Simple but obscure."
 
 #  play:
 #    choose_your_level: "Choose Your Level"
diff --git a/app/locale/en-GB.coffee b/app/locale/en-GB.coffee
index 0ba3466cc..e6fadc26e 100644
--- a/app/locale/en-GB.coffee
+++ b/app/locale/en-GB.coffee
@@ -100,6 +100,12 @@ module.exports = nativeDescription: "English (UK)", englishDescription: "English
 #    for_beginners: "For Beginners"
 #    multiplayer: "Multiplayer"
 #    for_developers: "For Developers"
+#    javascript_blurb: "The language of the web. Great for writing websites, web apps, HTML5 games, and servers."
+#    python_blurb: "Simple yet powerful, Python is a great general purpose programming language."
+#    coffeescript_blurb: "Nicer JavaScript syntax."
+#    clojure_blurb: "A modern Lisp."
+#    lua_blurb: "Game scripting language."
+#    io_blurb: "Simple but obscure."
 
 #  play:
 #    choose_your_level: "Choose Your Level"
diff --git a/app/locale/en-US.coffee b/app/locale/en-US.coffee
index ebecb2bd2..61513d098 100644
--- a/app/locale/en-US.coffee
+++ b/app/locale/en-US.coffee
@@ -100,6 +100,12 @@ module.exports = nativeDescription: "English (US)", englishDescription: "English
 #    for_beginners: "For Beginners"
 #    multiplayer: "Multiplayer"
 #    for_developers: "For Developers"
+#    javascript_blurb: "The language of the web. Great for writing websites, web apps, HTML5 games, and servers."
+#    python_blurb: "Simple yet powerful, Python is a great general purpose programming language."
+#    coffeescript_blurb: "Nicer JavaScript syntax."
+#    clojure_blurb: "A modern Lisp."
+#    lua_blurb: "Game scripting language."
+#    io_blurb: "Simple but obscure."
 
 #  play:
 #    choose_your_level: "Choose Your Level"
diff --git a/app/locale/es-419.coffee b/app/locale/es-419.coffee
index 84d5ddd86..6d4b7892c 100644
--- a/app/locale/es-419.coffee
+++ b/app/locale/es-419.coffee
@@ -100,6 +100,12 @@ module.exports = nativeDescription: "español (América Latina)", englishDescrip
     for_beginners: "Para Principiantes"
     multiplayer: "Multijugador"
     for_developers: "Para Desarrolladores"
+#    javascript_blurb: "The language of the web. Great for writing websites, web apps, HTML5 games, and servers."
+#    python_blurb: "Simple yet powerful, Python is a great general purpose programming language."
+#    coffeescript_blurb: "Nicer JavaScript syntax."
+#    clojure_blurb: "A modern Lisp."
+#    lua_blurb: "Game scripting language."
+#    io_blurb: "Simple but obscure."
 
   play:
     choose_your_level: "Elige tu nivel"
diff --git a/app/locale/es-ES.coffee b/app/locale/es-ES.coffee
index 565025b19..956682ba2 100644
--- a/app/locale/es-ES.coffee
+++ b/app/locale/es-ES.coffee
@@ -100,6 +100,12 @@ module.exports = nativeDescription: "español (ES)", englishDescription: "Spanis
     for_beginners: "Para principiantes"
     multiplayer: "Multijugador"
     for_developers: "Para programadores"
+#    javascript_blurb: "The language of the web. Great for writing websites, web apps, HTML5 games, and servers."
+#    python_blurb: "Simple yet powerful, Python is a great general purpose programming language."
+#    coffeescript_blurb: "Nicer JavaScript syntax."
+#    clojure_blurb: "A modern Lisp."
+#    lua_blurb: "Game scripting language."
+#    io_blurb: "Simple but obscure."
 
   play:
     choose_your_level: "Elige tu nivel"
diff --git a/app/locale/es.coffee b/app/locale/es.coffee
index dcc2e7ff1..3382d263f 100644
--- a/app/locale/es.coffee
+++ b/app/locale/es.coffee
@@ -100,6 +100,12 @@ module.exports = nativeDescription: "español", englishDescription: "Spanish", t
     for_beginners: "Para principiantes"
     multiplayer: "Multijugador"
     for_developers: "Para desarrolladores"
+#    javascript_blurb: "The language of the web. Great for writing websites, web apps, HTML5 games, and servers."
+#    python_blurb: "Simple yet powerful, Python is a great general purpose programming language."
+#    coffeescript_blurb: "Nicer JavaScript syntax."
+#    clojure_blurb: "A modern Lisp."
+#    lua_blurb: "Game scripting language."
+#    io_blurb: "Simple but obscure."
 
   play:
     choose_your_level: "Elige tu nivel"
diff --git a/app/locale/fa.coffee b/app/locale/fa.coffee
index e043269ae..5643e4646 100644
--- a/app/locale/fa.coffee
+++ b/app/locale/fa.coffee
@@ -100,6 +100,12 @@ module.exports = nativeDescription: "فارسی", englishDescription: "Persian",
 #    for_beginners: "For Beginners"
 #    multiplayer: "Multiplayer"
 #    for_developers: "For Developers"
+#    javascript_blurb: "The language of the web. Great for writing websites, web apps, HTML5 games, and servers."
+#    python_blurb: "Simple yet powerful, Python is a great general purpose programming language."
+#    coffeescript_blurb: "Nicer JavaScript syntax."
+#    clojure_blurb: "A modern Lisp."
+#    lua_blurb: "Game scripting language."
+#    io_blurb: "Simple but obscure."
 
   play:
     choose_your_level: "مرحله خود را انتخاب کنید"
diff --git a/app/locale/fi.coffee b/app/locale/fi.coffee
index cd1da3699..d045279e8 100644
--- a/app/locale/fi.coffee
+++ b/app/locale/fi.coffee
@@ -100,6 +100,12 @@ module.exports = nativeDescription: "suomi", englishDescription: "Finnish", tran
 #    for_beginners: "For Beginners"
 #    multiplayer: "Multiplayer"
 #    for_developers: "For Developers"
+#    javascript_blurb: "The language of the web. Great for writing websites, web apps, HTML5 games, and servers."
+#    python_blurb: "Simple yet powerful, Python is a great general purpose programming language."
+#    coffeescript_blurb: "Nicer JavaScript syntax."
+#    clojure_blurb: "A modern Lisp."
+#    lua_blurb: "Game scripting language."
+#    io_blurb: "Simple but obscure."
 
 #  play:
 #    choose_your_level: "Choose Your Level"
diff --git a/app/locale/fr.coffee b/app/locale/fr.coffee
index 94a3dd46d..1d717c739 100644
--- a/app/locale/fr.coffee
+++ b/app/locale/fr.coffee
@@ -100,6 +100,12 @@ module.exports = nativeDescription: "français", englishDescription: "French", t
     for_beginners: "Pour débutants"
     multiplayer: "Multijoueurs"
     for_developers: "Pour développeurs"
+#    javascript_blurb: "The language of the web. Great for writing websites, web apps, HTML5 games, and servers."
+#    python_blurb: "Simple yet powerful, Python is a great general purpose programming language."
+#    coffeescript_blurb: "Nicer JavaScript syntax."
+#    clojure_blurb: "A modern Lisp."
+#    lua_blurb: "Game scripting language."
+#    io_blurb: "Simple but obscure."
 
   play:
     choose_your_level: "Choisissez votre niveau"
diff --git a/app/locale/he.coffee b/app/locale/he.coffee
index 7dda67ac8..4621f2dce 100644
--- a/app/locale/he.coffee
+++ b/app/locale/he.coffee
@@ -100,6 +100,12 @@ module.exports = nativeDescription: "עברית", englishDescription: "Hebrew",
     for_beginners: "למתחילים"
     multiplayer: "רב-משתתפים"
     for_developers: "למומחים"
+#    javascript_blurb: "The language of the web. Great for writing websites, web apps, HTML5 games, and servers."
+#    python_blurb: "Simple yet powerful, Python is a great general purpose programming language."
+#    coffeescript_blurb: "Nicer JavaScript syntax."
+#    clojure_blurb: "A modern Lisp."
+#    lua_blurb: "Game scripting language."
+#    io_blurb: "Simple but obscure."
 
   play:
     choose_your_level: "בחר את השלב"
diff --git a/app/locale/hi.coffee b/app/locale/hi.coffee
index 85ccf7dac..ca51ba569 100644
--- a/app/locale/hi.coffee
+++ b/app/locale/hi.coffee
@@ -100,6 +100,12 @@ module.exports = nativeDescription: "मानक हिन्दी", englishDe
 #    for_beginners: "For Beginners"
 #    multiplayer: "Multiplayer"
 #    for_developers: "For Developers"
+#    javascript_blurb: "The language of the web. Great for writing websites, web apps, HTML5 games, and servers."
+#    python_blurb: "Simple yet powerful, Python is a great general purpose programming language."
+#    coffeescript_blurb: "Nicer JavaScript syntax."
+#    clojure_blurb: "A modern Lisp."
+#    lua_blurb: "Game scripting language."
+#    io_blurb: "Simple but obscure."
 
 #  play:
 #    choose_your_level: "Choose Your Level"
diff --git a/app/locale/hu.coffee b/app/locale/hu.coffee
index 2aef84d38..390e20a98 100644
--- a/app/locale/hu.coffee
+++ b/app/locale/hu.coffee
@@ -100,6 +100,12 @@ module.exports = nativeDescription: "magyar", englishDescription: "Hungarian", t
     for_beginners: "Kezdőknek"
 #    multiplayer: "Multiplayer"
     for_developers: "Fejlesztőknek"
+#    javascript_blurb: "The language of the web. Great for writing websites, web apps, HTML5 games, and servers."
+#    python_blurb: "Simple yet powerful, Python is a great general purpose programming language."
+#    coffeescript_blurb: "Nicer JavaScript syntax."
+#    clojure_blurb: "A modern Lisp."
+#    lua_blurb: "Game scripting language."
+#    io_blurb: "Simple but obscure."
 
   play:
     choose_your_level: "Válaszd ki a pályát!"
diff --git a/app/locale/id.coffee b/app/locale/id.coffee
index ae972660d..fe9958166 100644
--- a/app/locale/id.coffee
+++ b/app/locale/id.coffee
@@ -100,6 +100,12 @@ module.exports = nativeDescription: "Bahasa Indonesia", englishDescription: "Ind
 #    for_beginners: "For Beginners"
 #    multiplayer: "Multiplayer"
 #    for_developers: "For Developers"
+#    javascript_blurb: "The language of the web. Great for writing websites, web apps, HTML5 games, and servers."
+#    python_blurb: "Simple yet powerful, Python is a great general purpose programming language."
+#    coffeescript_blurb: "Nicer JavaScript syntax."
+#    clojure_blurb: "A modern Lisp."
+#    lua_blurb: "Game scripting language."
+#    io_blurb: "Simple but obscure."
 
 #  play:
 #    choose_your_level: "Choose Your Level"
diff --git a/app/locale/it.coffee b/app/locale/it.coffee
index e1535c040..a1ed0fbaf 100644
--- a/app/locale/it.coffee
+++ b/app/locale/it.coffee
@@ -100,6 +100,12 @@ module.exports = nativeDescription: "Italiano", englishDescription: "Italian", t
     for_beginners: "Per Principianti"
 #    multiplayer: "Multiplayer"
     for_developers: "Per Sviluppatori"
+#    javascript_blurb: "The language of the web. Great for writing websites, web apps, HTML5 games, and servers."
+#    python_blurb: "Simple yet powerful, Python is a great general purpose programming language."
+#    coffeescript_blurb: "Nicer JavaScript syntax."
+#    clojure_blurb: "A modern Lisp."
+#    lua_blurb: "Game scripting language."
+#    io_blurb: "Simple but obscure."
 
   play:
     choose_your_level: "Scegli il tuo livello"
diff --git a/app/locale/ja.coffee b/app/locale/ja.coffee
index fce997c9a..acdc9ffb6 100644
--- a/app/locale/ja.coffee
+++ b/app/locale/ja.coffee
@@ -100,6 +100,12 @@ module.exports = nativeDescription: "日本語", englishDescription: "Japanese",
     for_beginners: "初心者向け"
     multiplayer: "マルチプレイヤー"
     for_developers: "開発者向け"
+#    javascript_blurb: "The language of the web. Great for writing websites, web apps, HTML5 games, and servers."
+#    python_blurb: "Simple yet powerful, Python is a great general purpose programming language."
+#    coffeescript_blurb: "Nicer JavaScript syntax."
+#    clojure_blurb: "A modern Lisp."
+#    lua_blurb: "Game scripting language."
+#    io_blurb: "Simple but obscure."
 
   play:
     choose_your_level: "レベル選択"
diff --git a/app/locale/ko.coffee b/app/locale/ko.coffee
index 791630d0e..fdc645eb4 100644
--- a/app/locale/ko.coffee
+++ b/app/locale/ko.coffee
@@ -100,6 +100,12 @@ module.exports = nativeDescription: "한국어", englishDescription: "Korean", t
     for_beginners: "초보자용"
     multiplayer: "멀티플레이어"
     for_developers: "개발자용"
+#    javascript_blurb: "The language of the web. Great for writing websites, web apps, HTML5 games, and servers."
+#    python_blurb: "Simple yet powerful, Python is a great general purpose programming language."
+#    coffeescript_blurb: "Nicer JavaScript syntax."
+#    clojure_blurb: "A modern Lisp."
+#    lua_blurb: "Game scripting language."
+#    io_blurb: "Simple but obscure."
 
   play:
     choose_your_level: "레벨을 선택하세요."
diff --git a/app/locale/lt.coffee b/app/locale/lt.coffee
index dd8420fff..c34b07ae6 100644
--- a/app/locale/lt.coffee
+++ b/app/locale/lt.coffee
@@ -100,6 +100,12 @@ module.exports = nativeDescription: "lietuvių kalba", englishDescription: "Lith
 #    for_beginners: "For Beginners"
 #    multiplayer: "Multiplayer"
 #    for_developers: "For Developers"
+#    javascript_blurb: "The language of the web. Great for writing websites, web apps, HTML5 games, and servers."
+#    python_blurb: "Simple yet powerful, Python is a great general purpose programming language."
+#    coffeescript_blurb: "Nicer JavaScript syntax."
+#    clojure_blurb: "A modern Lisp."
+#    lua_blurb: "Game scripting language."
+#    io_blurb: "Simple but obscure."
 
 #  play:
 #    choose_your_level: "Choose Your Level"
diff --git a/app/locale/ms.coffee b/app/locale/ms.coffee
index 7149e3b19..62d60bdb5 100644
--- a/app/locale/ms.coffee
+++ b/app/locale/ms.coffee
@@ -100,6 +100,12 @@ module.exports = nativeDescription: "Bahasa Melayu", englishDescription: "Bahasa
 #    for_beginners: "For Beginners"
 #    multiplayer: "Multiplayer"
 #    for_developers: "For Developers"
+#    javascript_blurb: "The language of the web. Great for writing websites, web apps, HTML5 games, and servers."
+#    python_blurb: "Simple yet powerful, Python is a great general purpose programming language."
+#    coffeescript_blurb: "Nicer JavaScript syntax."
+#    clojure_blurb: "A modern Lisp."
+#    lua_blurb: "Game scripting language."
+#    io_blurb: "Simple but obscure."
 
 #  play:
 #    choose_your_level: "Choose Your Level"
diff --git a/app/locale/nb.coffee b/app/locale/nb.coffee
index 855b05b2b..cfcf2cd07 100644
--- a/app/locale/nb.coffee
+++ b/app/locale/nb.coffee
@@ -100,6 +100,12 @@ module.exports = nativeDescription: "Norsk Bokmål", englishDescription: "Norweg
 #    for_beginners: "For Beginners"
 #    multiplayer: "Multiplayer"
 #    for_developers: "For Developers"
+#    javascript_blurb: "The language of the web. Great for writing websites, web apps, HTML5 games, and servers."
+#    python_blurb: "Simple yet powerful, Python is a great general purpose programming language."
+#    coffeescript_blurb: "Nicer JavaScript syntax."
+#    clojure_blurb: "A modern Lisp."
+#    lua_blurb: "Game scripting language."
+#    io_blurb: "Simple but obscure."
 
   play:
     choose_your_level: "Velg Ditt Nivå"
diff --git a/app/locale/nl-BE.coffee b/app/locale/nl-BE.coffee
index 42221b38d..20eef3d90 100644
--- a/app/locale/nl-BE.coffee
+++ b/app/locale/nl-BE.coffee
@@ -100,6 +100,12 @@ module.exports = nativeDescription: "Nederlands (België)", englishDescription:
     for_beginners: "Voor Beginners"
     multiplayer: "Multiplayer"
     for_developers: "Voor ontwikkelaars"
+#    javascript_blurb: "The language of the web. Great for writing websites, web apps, HTML5 games, and servers."
+#    python_blurb: "Simple yet powerful, Python is a great general purpose programming language."
+#    coffeescript_blurb: "Nicer JavaScript syntax."
+#    clojure_blurb: "A modern Lisp."
+#    lua_blurb: "Game scripting language."
+#    io_blurb: "Simple but obscure."
 
   play:
     choose_your_level: "Kies Je Level"
diff --git a/app/locale/nl-NL.coffee b/app/locale/nl-NL.coffee
index f54d02efd..5db7557ee 100644
--- a/app/locale/nl-NL.coffee
+++ b/app/locale/nl-NL.coffee
@@ -100,6 +100,12 @@ module.exports = nativeDescription: "Nederlands (Nederland)", englishDescription
     for_beginners: "Voor Beginners"
     multiplayer: "Multiplayer"
     for_developers: "Voor ontwikkelaars"
+#    javascript_blurb: "The language of the web. Great for writing websites, web apps, HTML5 games, and servers."
+#    python_blurb: "Simple yet powerful, Python is a great general purpose programming language."
+#    coffeescript_blurb: "Nicer JavaScript syntax."
+#    clojure_blurb: "A modern Lisp."
+#    lua_blurb: "Game scripting language."
+#    io_blurb: "Simple but obscure."
 
   play:
     choose_your_level: "Kies Je Level"
diff --git a/app/locale/nl.coffee b/app/locale/nl.coffee
index 74b8c35b4..0fccad1af 100644
--- a/app/locale/nl.coffee
+++ b/app/locale/nl.coffee
@@ -100,6 +100,12 @@ module.exports = nativeDescription: "Nederlands", englishDescription: "Dutch", t
     for_beginners: "Voor Beginners"
     multiplayer: "Multiplayer"
     for_developers: "Voor ontwikkelaars"
+#    javascript_blurb: "The language of the web. Great for writing websites, web apps, HTML5 games, and servers."
+#    python_blurb: "Simple yet powerful, Python is a great general purpose programming language."
+#    coffeescript_blurb: "Nicer JavaScript syntax."
+#    clojure_blurb: "A modern Lisp."
+#    lua_blurb: "Game scripting language."
+#    io_blurb: "Simple but obscure."
 
   play:
     choose_your_level: "Kies Je Level"
diff --git a/app/locale/nn.coffee b/app/locale/nn.coffee
index c7e58789f..180420e6a 100644
--- a/app/locale/nn.coffee
+++ b/app/locale/nn.coffee
@@ -100,6 +100,12 @@ module.exports = nativeDescription: "Norwegian Nynorsk", englishDescription: "No
 #    for_beginners: "For Beginners"
 #    multiplayer: "Multiplayer"
 #    for_developers: "For Developers"
+#    javascript_blurb: "The language of the web. Great for writing websites, web apps, HTML5 games, and servers."
+#    python_blurb: "Simple yet powerful, Python is a great general purpose programming language."
+#    coffeescript_blurb: "Nicer JavaScript syntax."
+#    clojure_blurb: "A modern Lisp."
+#    lua_blurb: "Game scripting language."
+#    io_blurb: "Simple but obscure."
 
 #  play:
 #    choose_your_level: "Choose Your Level"
diff --git a/app/locale/no.coffee b/app/locale/no.coffee
index 4085d5128..d319665ee 100644
--- a/app/locale/no.coffee
+++ b/app/locale/no.coffee
@@ -100,6 +100,12 @@ module.exports = nativeDescription: "Norsk", englishDescription: "Norwegian", tr
 #    for_beginners: "For Beginners"
 #    multiplayer: "Multiplayer"
 #    for_developers: "For Developers"
+#    javascript_blurb: "The language of the web. Great for writing websites, web apps, HTML5 games, and servers."
+#    python_blurb: "Simple yet powerful, Python is a great general purpose programming language."
+#    coffeescript_blurb: "Nicer JavaScript syntax."
+#    clojure_blurb: "A modern Lisp."
+#    lua_blurb: "Game scripting language."
+#    io_blurb: "Simple but obscure."
 
   play:
     choose_your_level: "Velg Ditt Nivå"
diff --git a/app/locale/pl.coffee b/app/locale/pl.coffee
index 6cbdc2007..a047b1f31 100644
--- a/app/locale/pl.coffee
+++ b/app/locale/pl.coffee
@@ -100,6 +100,12 @@ module.exports = nativeDescription: "język polski", englishDescription: "Polish
     for_beginners: "Dla początkujących"
 #    multiplayer: "Multiplayer"
     for_developers: "Dla developerów"
+#    javascript_blurb: "The language of the web. Great for writing websites, web apps, HTML5 games, and servers."
+#    python_blurb: "Simple yet powerful, Python is a great general purpose programming language."
+#    coffeescript_blurb: "Nicer JavaScript syntax."
+#    clojure_blurb: "A modern Lisp."
+#    lua_blurb: "Game scripting language."
+#    io_blurb: "Simple but obscure."
 
   play:
     choose_your_level: "Wybierz poziom"
diff --git a/app/locale/pt-BR.coffee b/app/locale/pt-BR.coffee
index f7758b9be..21ef4fcf3 100644
--- a/app/locale/pt-BR.coffee
+++ b/app/locale/pt-BR.coffee
@@ -100,6 +100,12 @@ module.exports = nativeDescription: "português do Brasil", englishDescription:
     for_beginners: "Para Iniciantes"
     multiplayer: "Multijogador"
     for_developers: "Para Desenvolvedores"
+#    javascript_blurb: "The language of the web. Great for writing websites, web apps, HTML5 games, and servers."
+#    python_blurb: "Simple yet powerful, Python is a great general purpose programming language."
+#    coffeescript_blurb: "Nicer JavaScript syntax."
+#    clojure_blurb: "A modern Lisp."
+#    lua_blurb: "Game scripting language."
+#    io_blurb: "Simple but obscure."
 
   play:
     choose_your_level: "Escolha seu estágio"
diff --git a/app/locale/pt-PT.coffee b/app/locale/pt-PT.coffee
index ec504f6db..9e51664d6 100644
--- a/app/locale/pt-PT.coffee
+++ b/app/locale/pt-PT.coffee
@@ -100,6 +100,12 @@ module.exports = nativeDescription: "Português (Portugal)", englishDescription:
     for_beginners: "Para Iniciantes"
     multiplayer: "Multijogador"
     for_developers: "Para Programadores"
+#    javascript_blurb: "The language of the web. Great for writing websites, web apps, HTML5 games, and servers."
+#    python_blurb: "Simple yet powerful, Python is a great general purpose programming language."
+#    coffeescript_blurb: "Nicer JavaScript syntax."
+#    clojure_blurb: "A modern Lisp."
+#    lua_blurb: "Game scripting language."
+#    io_blurb: "Simple but obscure."
 
   play:
     choose_your_level: "Escolha o Seu Nível"
diff --git a/app/locale/pt.coffee b/app/locale/pt.coffee
index ea24890d3..e69e86463 100644
--- a/app/locale/pt.coffee
+++ b/app/locale/pt.coffee
@@ -100,6 +100,12 @@ module.exports = nativeDescription: "português", englishDescription: "Portugues
 #    for_beginners: "For Beginners"
 #    multiplayer: "Multiplayer"
 #    for_developers: "For Developers"
+#    javascript_blurb: "The language of the web. Great for writing websites, web apps, HTML5 games, and servers."
+#    python_blurb: "Simple yet powerful, Python is a great general purpose programming language."
+#    coffeescript_blurb: "Nicer JavaScript syntax."
+#    clojure_blurb: "A modern Lisp."
+#    lua_blurb: "Game scripting language."
+#    io_blurb: "Simple but obscure."
 
   play:
     choose_your_level: "Escolha seu estágio"
diff --git a/app/locale/ro.coffee b/app/locale/ro.coffee
index baefa15fb..145382ca0 100644
--- a/app/locale/ro.coffee
+++ b/app/locale/ro.coffee
@@ -100,6 +100,12 @@ module.exports = nativeDescription: "limba română", englishDescription: "Roman
     for_beginners: "Pentru Începători"
     multiplayer: "Multiplayer"
     for_developers: "Pentru dezvoltatori"
+#    javascript_blurb: "The language of the web. Great for writing websites, web apps, HTML5 games, and servers."
+#    python_blurb: "Simple yet powerful, Python is a great general purpose programming language."
+#    coffeescript_blurb: "Nicer JavaScript syntax."
+#    clojure_blurb: "A modern Lisp."
+#    lua_blurb: "Game scripting language."
+#    io_blurb: "Simple but obscure."
 
   play:
     choose_your_level: "Alege nivelul"
diff --git a/app/locale/ru.coffee b/app/locale/ru.coffee
index 9ac956a4d..cb96b0e6e 100644
--- a/app/locale/ru.coffee
+++ b/app/locale/ru.coffee
@@ -100,6 +100,12 @@ module.exports = nativeDescription: "русский", englishDescription: "Russi
     for_beginners: "Новичкам"
     multiplayer: "Мультиплеер"
     for_developers: "Разработчикам"
+#    javascript_blurb: "The language of the web. Great for writing websites, web apps, HTML5 games, and servers."
+#    python_blurb: "Simple yet powerful, Python is a great general purpose programming language."
+#    coffeescript_blurb: "Nicer JavaScript syntax."
+#    clojure_blurb: "A modern Lisp."
+#    lua_blurb: "Game scripting language."
+#    io_blurb: "Simple but obscure."
 
   play:
     choose_your_level: "Выберите ваш уровень"
diff --git a/app/locale/sk.coffee b/app/locale/sk.coffee
index 20be15ee8..135b8acf0 100644
--- a/app/locale/sk.coffee
+++ b/app/locale/sk.coffee
@@ -100,6 +100,12 @@ module.exports = nativeDescription: "slovenčina", englishDescription: "Slovak",
     for_beginners: "Pre začiatočníkov"
 #    multiplayer: "Multiplayer"
     for_developers: "Pre vývojárov"
+#    javascript_blurb: "The language of the web. Great for writing websites, web apps, HTML5 games, and servers."
+#    python_blurb: "Simple yet powerful, Python is a great general purpose programming language."
+#    coffeescript_blurb: "Nicer JavaScript syntax."
+#    clojure_blurb: "A modern Lisp."
+#    lua_blurb: "Game scripting language."
+#    io_blurb: "Simple but obscure."
 
   play:
     choose_your_level: "Vyber si úroveň"
diff --git a/app/locale/sl.coffee b/app/locale/sl.coffee
index 73c8947f7..6517ac37d 100644
--- a/app/locale/sl.coffee
+++ b/app/locale/sl.coffee
@@ -100,6 +100,12 @@ module.exports = nativeDescription: "slovenščina", englishDescription: "Sloven
 #    for_beginners: "For Beginners"
 #    multiplayer: "Multiplayer"
 #    for_developers: "For Developers"
+#    javascript_blurb: "The language of the web. Great for writing websites, web apps, HTML5 games, and servers."
+#    python_blurb: "Simple yet powerful, Python is a great general purpose programming language."
+#    coffeescript_blurb: "Nicer JavaScript syntax."
+#    clojure_blurb: "A modern Lisp."
+#    lua_blurb: "Game scripting language."
+#    io_blurb: "Simple but obscure."
 
 #  play:
 #    choose_your_level: "Choose Your Level"
diff --git a/app/locale/sr.coffee b/app/locale/sr.coffee
index 4b748189c..ae0508b0f 100644
--- a/app/locale/sr.coffee
+++ b/app/locale/sr.coffee
@@ -100,6 +100,12 @@ module.exports = nativeDescription: "српски", englishDescription: "Serbian
 #    for_beginners: "For Beginners"
 #    multiplayer: "Multiplayer"
 #    for_developers: "For Developers"
+#    javascript_blurb: "The language of the web. Great for writing websites, web apps, HTML5 games, and servers."
+#    python_blurb: "Simple yet powerful, Python is a great general purpose programming language."
+#    coffeescript_blurb: "Nicer JavaScript syntax."
+#    clojure_blurb: "A modern Lisp."
+#    lua_blurb: "Game scripting language."
+#    io_blurb: "Simple but obscure."
 
   play:
     choose_your_level: "Изабери ниво"
diff --git a/app/locale/sv.coffee b/app/locale/sv.coffee
index ac9d04d87..1e6356c4f 100644
--- a/app/locale/sv.coffee
+++ b/app/locale/sv.coffee
@@ -100,6 +100,12 @@ module.exports = nativeDescription: "Svenska", englishDescription: "Swedish", tr
     for_beginners: "För nybörjare"
     multiplayer: "Flera spelare"
     for_developers: "För utvecklare"
+#    javascript_blurb: "The language of the web. Great for writing websites, web apps, HTML5 games, and servers."
+#    python_blurb: "Simple yet powerful, Python is a great general purpose programming language."
+#    coffeescript_blurb: "Nicer JavaScript syntax."
+#    clojure_blurb: "A modern Lisp."
+#    lua_blurb: "Game scripting language."
+#    io_blurb: "Simple but obscure."
 
   play:
     choose_your_level: "Välj din nivå"
diff --git a/app/locale/th.coffee b/app/locale/th.coffee
index debe63e0f..0ffadebae 100644
--- a/app/locale/th.coffee
+++ b/app/locale/th.coffee
@@ -100,6 +100,12 @@ module.exports = nativeDescription: "ไทย", englishDescription: "Thai", tra
 #    for_beginners: "For Beginners"
 #    multiplayer: "Multiplayer"
 #    for_developers: "For Developers"
+#    javascript_blurb: "The language of the web. Great for writing websites, web apps, HTML5 games, and servers."
+#    python_blurb: "Simple yet powerful, Python is a great general purpose programming language."
+#    coffeescript_blurb: "Nicer JavaScript syntax."
+#    clojure_blurb: "A modern Lisp."
+#    lua_blurb: "Game scripting language."
+#    io_blurb: "Simple but obscure."
 
 #  play:
 #    choose_your_level: "Choose Your Level"
diff --git a/app/locale/tr.coffee b/app/locale/tr.coffee
index 83596230d..6c52344fa 100644
--- a/app/locale/tr.coffee
+++ b/app/locale/tr.coffee
@@ -100,6 +100,12 @@ module.exports = nativeDescription: "Türkçe", englishDescription: "Turkish", t
     for_beginners: "Yeni Başlayanlar için"
     multiplayer: "Çoklu-oyuncu Modu"
     for_developers: "Geliştiriciler için"
+#    javascript_blurb: "The language of the web. Great for writing websites, web apps, HTML5 games, and servers."
+#    python_blurb: "Simple yet powerful, Python is a great general purpose programming language."
+#    coffeescript_blurb: "Nicer JavaScript syntax."
+#    clojure_blurb: "A modern Lisp."
+#    lua_blurb: "Game scripting language."
+#    io_blurb: "Simple but obscure."
 
   play:
     choose_your_level: "Seviye Seçimi"
diff --git a/app/locale/uk.coffee b/app/locale/uk.coffee
index beb7659ec..65c15f9c3 100644
--- a/app/locale/uk.coffee
+++ b/app/locale/uk.coffee
@@ -100,6 +100,12 @@ module.exports = nativeDescription: "українська мова", englishDesc
     for_beginners: "Для новачків"
     multiplayer: "Командна гра"
     for_developers: "Для розробників"
+#    javascript_blurb: "The language of the web. Great for writing websites, web apps, HTML5 games, and servers."
+#    python_blurb: "Simple yet powerful, Python is a great general purpose programming language."
+#    coffeescript_blurb: "Nicer JavaScript syntax."
+#    clojure_blurb: "A modern Lisp."
+#    lua_blurb: "Game scripting language."
+#    io_blurb: "Simple but obscure."
 
   play:
     choose_your_level: "Оберіть свій рівень"
diff --git a/app/locale/ur.coffee b/app/locale/ur.coffee
index a0ca20473..9672ccdbd 100644
--- a/app/locale/ur.coffee
+++ b/app/locale/ur.coffee
@@ -100,6 +100,12 @@ module.exports = nativeDescription: "اُردُو", englishDescription: "Urdu",
 #    for_beginners: "For Beginners"
 #    multiplayer: "Multiplayer"
 #    for_developers: "For Developers"
+#    javascript_blurb: "The language of the web. Great for writing websites, web apps, HTML5 games, and servers."
+#    python_blurb: "Simple yet powerful, Python is a great general purpose programming language."
+#    coffeescript_blurb: "Nicer JavaScript syntax."
+#    clojure_blurb: "A modern Lisp."
+#    lua_blurb: "Game scripting language."
+#    io_blurb: "Simple but obscure."
 
 #  play:
 #    choose_your_level: "Choose Your Level"
diff --git a/app/locale/vi.coffee b/app/locale/vi.coffee
index 55bf539c7..f58f20fb4 100644
--- a/app/locale/vi.coffee
+++ b/app/locale/vi.coffee
@@ -100,6 +100,12 @@ module.exports = nativeDescription: "Tiếng Việt", englishDescription: "Vietn
 #    for_beginners: "For Beginners"
 #    multiplayer: "Multiplayer"
 #    for_developers: "For Developers"
+#    javascript_blurb: "The language of the web. Great for writing websites, web apps, HTML5 games, and servers."
+#    python_blurb: "Simple yet powerful, Python is a great general purpose programming language."
+#    coffeescript_blurb: "Nicer JavaScript syntax."
+#    clojure_blurb: "A modern Lisp."
+#    lua_blurb: "Game scripting language."
+#    io_blurb: "Simple but obscure."
 
   play:
     choose_your_level: "Chọn Trình của bạn"
diff --git a/app/locale/zh-HANS.coffee b/app/locale/zh-HANS.coffee
index 665af4c82..7523c69af 100644
--- a/app/locale/zh-HANS.coffee
+++ b/app/locale/zh-HANS.coffee
@@ -100,6 +100,12 @@ module.exports = nativeDescription: "简体中文", englishDescription: "Chinese
     for_beginners: "适合初学者"
     multiplayer: "多人游戏"
     for_developers: "适合开发者"
+#    javascript_blurb: "The language of the web. Great for writing websites, web apps, HTML5 games, and servers."
+#    python_blurb: "Simple yet powerful, Python is a great general purpose programming language."
+#    coffeescript_blurb: "Nicer JavaScript syntax."
+#    clojure_blurb: "A modern Lisp."
+#    lua_blurb: "Game scripting language."
+#    io_blurb: "Simple but obscure."
 
   play:
     choose_your_level: "选择关卡"
diff --git a/app/locale/zh-HANT.coffee b/app/locale/zh-HANT.coffee
index 96a11fc42..b4a96e647 100644
--- a/app/locale/zh-HANT.coffee
+++ b/app/locale/zh-HANT.coffee
@@ -100,6 +100,12 @@ module.exports = nativeDescription: "繁体中文", englishDescription: "Chinese
 #    for_beginners: "For Beginners"
 #    multiplayer: "Multiplayer"
 #    for_developers: "For Developers"
+#    javascript_blurb: "The language of the web. Great for writing websites, web apps, HTML5 games, and servers."
+#    python_blurb: "Simple yet powerful, Python is a great general purpose programming language."
+#    coffeescript_blurb: "Nicer JavaScript syntax."
+#    clojure_blurb: "A modern Lisp."
+#    lua_blurb: "Game scripting language."
+#    io_blurb: "Simple but obscure."
 
   play:
     choose_your_level: "選取關卡"
diff --git a/app/locale/zh-WUU-HANS.coffee b/app/locale/zh-WUU-HANS.coffee
index 5d5a8c757..ea129d982 100644
--- a/app/locale/zh-WUU-HANS.coffee
+++ b/app/locale/zh-WUU-HANS.coffee
@@ -100,6 +100,12 @@ module.exports = nativeDescription: "吴语", englishDescription: "Wuu (Simplifi
 #    for_beginners: "For Beginners"
 #    multiplayer: "Multiplayer"
 #    for_developers: "For Developers"
+#    javascript_blurb: "The language of the web. Great for writing websites, web apps, HTML5 games, and servers."
+#    python_blurb: "Simple yet powerful, Python is a great general purpose programming language."
+#    coffeescript_blurb: "Nicer JavaScript syntax."
+#    clojure_blurb: "A modern Lisp."
+#    lua_blurb: "Game scripting language."
+#    io_blurb: "Simple but obscure."
 
 #  play:
 #    choose_your_level: "Choose Your Level"
diff --git a/app/locale/zh-WUU-HANT.coffee b/app/locale/zh-WUU-HANT.coffee
index 6fdb7dd26..361a86c11 100644
--- a/app/locale/zh-WUU-HANT.coffee
+++ b/app/locale/zh-WUU-HANT.coffee
@@ -100,6 +100,12 @@ module.exports = nativeDescription: "吳語", englishDescription: "Wuu (Traditio
     for_beginners: "適合學起頭個人"
     multiplayer: "聚隊打遊戲"
     for_developers: "適合開發個人"
+#    javascript_blurb: "The language of the web. Great for writing websites, web apps, HTML5 games, and servers."
+#    python_blurb: "Simple yet powerful, Python is a great general purpose programming language."
+#    coffeescript_blurb: "Nicer JavaScript syntax."
+#    clojure_blurb: "A modern Lisp."
+#    lua_blurb: "Game scripting language."
+#    io_blurb: "Simple but obscure."
 
   play:
     choose_your_level: "揀關數"
diff --git a/app/locale/zh.coffee b/app/locale/zh.coffee
index 7a2b8c97e..811f7a5ca 100644
--- a/app/locale/zh.coffee
+++ b/app/locale/zh.coffee
@@ -100,6 +100,12 @@ module.exports = nativeDescription: "中文", englishDescription: "Chinese", tra
 #    for_beginners: "For Beginners"
 #    multiplayer: "Multiplayer"
 #    for_developers: "For Developers"
+#    javascript_blurb: "The language of the web. Great for writing websites, web apps, HTML5 games, and servers."
+#    python_blurb: "Simple yet powerful, Python is a great general purpose programming language."
+#    coffeescript_blurb: "Nicer JavaScript syntax."
+#    clojure_blurb: "A modern Lisp."
+#    lua_blurb: "Game scripting language."
+#    io_blurb: "Simple but obscure."
 
   play:
     choose_your_level: "选取难度"

From 051fd9ecbc014143e919cfee40ed51a2710783ab Mon Sep 17 00:00:00 2001
From: Imperadeiro98 <Imperadeiro98@users.noreply.github.com>
Date: Fri, 18 Jul 2014 13:40:05 +0100
Subject: [PATCH 41/58] Update pt-PT.coffee

---
 app/locale/pt-PT.coffee | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/app/locale/pt-PT.coffee b/app/locale/pt-PT.coffee
index 9e51664d6..215d1aad0 100644
--- a/app/locale/pt-PT.coffee
+++ b/app/locale/pt-PT.coffee
@@ -100,12 +100,12 @@ module.exports = nativeDescription: "Português (Portugal)", englishDescription:
     for_beginners: "Para Iniciantes"
     multiplayer: "Multijogador"
     for_developers: "Para Programadores"
-#    javascript_blurb: "The language of the web. Great for writing websites, web apps, HTML5 games, and servers."
-#    python_blurb: "Simple yet powerful, Python is a great general purpose programming language."
-#    coffeescript_blurb: "Nicer JavaScript syntax."
-#    clojure_blurb: "A modern Lisp."
-#    lua_blurb: "Game scripting language."
-#    io_blurb: "Simple but obscure."
+    javascript_blurb: "A linguagem da web. Ótima para escrever websites, aplicações da web, jogos HTML5 e servidores."
+    python_blurb: "Simples mas poderoso, o Python é uma linguagem de programação ótima para propósitos gerais."
+    coffeescript_blurb: "Sintaxe do Javascript mais agradável."
+    clojure_blurb: "Um Lisp moderno"
+    lua_blurb: "Linguagem para scripts de jogos"
+    io_blurb: "Simples mas obscuro"
 
   play:
     choose_your_level: "Escolha o Seu Nível"

From 3ac1d6c77cae0b493cf1b23b9b89396e9e764ae3 Mon Sep 17 00:00:00 2001
From: Imperadeiro98 <Imperadeiro98@users.noreply.github.com>
Date: Fri, 18 Jul 2014 15:48:36 +0100
Subject: [PATCH 42/58] Update pt-PT.coffee

---
 app/locale/pt-PT.coffee | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/app/locale/pt-PT.coffee b/app/locale/pt-PT.coffee
index 215d1aad0..47879bfe7 100644
--- a/app/locale/pt-PT.coffee
+++ b/app/locale/pt-PT.coffee
@@ -100,12 +100,12 @@ module.exports = nativeDescription: "Português (Portugal)", englishDescription:
     for_beginners: "Para Iniciantes"
     multiplayer: "Multijogador"
     for_developers: "Para Programadores"
-    javascript_blurb: "A linguagem da web. Ótima para escrever websites, aplicações da web, jogos HTML5 e servidores."
-    python_blurb: "Simples mas poderoso, o Python é uma linguagem de programação ótima para propósitos gerais."
-    coffeescript_blurb: "Sintaxe do Javascript mais agradável."
-    clojure_blurb: "Um Lisp moderno"
-    lua_blurb: "Linguagem para scripts de jogos"
-    io_blurb: "Simples mas obscuro"
+#    javascript_blurb: "A linguagem da web. Ótima para escrever websites, aplicações da web, jogos HTML5 e servidores."
+#    python_blurb: "Simples mas poderoso, o Python é uma linguagem de programação ótima para propósitos gerais."
+#    coffeescript_blurb: "Sintaxe do Javascript mais agradável."
+#    clojure_blurb: "Um Lisp moderno"
+#    lua_blurb: "Linguagem para scripts de jogos"
+#    io_blurb: "Simples mas obscuro"
 
   play:
     choose_your_level: "Escolha o Seu Nível"

From a6ab97703410aeadc73e864374e2a0151b44cdb5 Mon Sep 17 00:00:00 2001
From: Michael Schmatz <michaelschmatz@gmail.com>
Date: Fri, 18 Jul 2014 11:05:37 -0700
Subject: [PATCH 43/58] Add candidate finish reminder email

---
 server/routes/mail.coffee | 104 +++++++++++++++++++++++++++++++++++++-
 1 file changed, 102 insertions(+), 2 deletions(-)

diff --git a/server/routes/mail.coffee b/server/routes/mail.coffee
index 26a5e8ed0..e7deb6707 100644
--- a/server/routes/mail.coffee
+++ b/server/routes/mail.coffee
@@ -1,5 +1,6 @@
 mail = require '../commons/mail'
 MailSent = require '../mail/sent/MailSent'
+UserRemark = require '../users/remarks/UserRemark'
 User = require '../users/User'
 async = require 'async'
 errors = require '../commons/errors'
@@ -28,6 +29,9 @@ setupScheduledEmails = ->
     ,
       taskFunction: employerNewCandidatesAvailableTask
       frequencyMs: 10 * 60 * 1000 #10 minutes
+    ,
+      taskFunction: unapprovedCandidateFinishProfileTask
+      frequencyMs: 10 * 60 * 1000
   ]
 
   for mailTask in mailTasks
@@ -35,7 +39,7 @@ setupScheduledEmails = ->
     
 testForLockManager = -> unless lockManager then throw "The system isn't configured to do distributed locking!"
   
-### Candidate Update Reminder Task ###
+### Approved Candidate Update Reminder Task ###
 
 candidateUpdateProfileTask = ->
   mailTaskName = "candidateUpdateProfileTask"
@@ -132,7 +136,103 @@ sendReminderEmailToCandidate = (candidate, sendEmailCallback) ->
       sendwithus.api.send context, (err, result) ->
         log.error "Error sending candidate update reminder email: #{err} with result #{result}" if err
         sendEmailCallback null
-### End Candidate Update Reminder Task ###
+### End Approved Candidate Update Reminder Task ###
+  
+### Unapproved Candidate Finish Reminder Task ###
+unapprovedCandidateFinishProfileTask = ->
+  mailTaskName = "unapprovedCandidateFinishProfileTask"
+  lockDurationMs = 2 * 60 * 1000
+  currentDate = new Date()
+  timeRanges = []
+  for weekPair in [[4, 2,'two weeks'], [8, 4, 'four weeks'], [52, 8, 'eight weeks']]
+    timeRanges.push
+      start: generateWeekOffset currentDate, weekPair[0]
+      end: generateWeekOffset currentDate, weekPair[1]
+      name: weekPair[2]
+  lockManager.setLock mailTaskName, lockDurationMs, (err) ->
+    if err? then return log.error "Error getting a distributed lock for task #{mailTaskName}: #{err}"
+    async.each timeRanges, emailUnapprovedCandidateTimeRange.bind({mailTaskName: mailTaskName}), (err) ->
+      if err
+        log.error "There was an error sending the candidate profile update reminder emails: #{err}"
+      else
+        log.info "Completed mail task #{mailTaskName}"
+      lockManager.releaseLock mailTaskName, (err) ->
+        if err? then return log.error "There was an error releasing the distributed lock for task #{mailTaskName}: #{err}"
+
+emailUnapprovedCandidateTimeRange = (timeRange, emailTimeRangeCallback) ->
+  waterfallContext =
+    "timeRange": timeRange
+    "mailTaskName": @mailTaskName
+  async.waterfall [
+    findAllUnapprovedCandidatesWithinTimeRange.bind(waterfallContext)
+    (unfilteredCandidates, cb) ->
+      async.reject unfilteredCandidates, ignoredCandidateFilter, cb.bind(null,null)
+    (unfilteredPotentialCandidates, cb) ->
+      async.reject unfilteredPotentialCandidates, unapprovedCandidateFilter.bind(waterfallContext), cb.bind(null, null)
+    (filteredCandidates, cb) ->
+      async.each filteredCandidates, sendReminderEmailToUnapprovedCandidate.bind(waterfallContext), cb
+  ], emailTimeRangeCallback
+
+findAllUnapprovedCandidatesWithinTimeRange = (cb) ->
+  findParameters =
+    "jobProfile":
+      $exists: true
+    "jobProfile.updated":
+      $gt: @timeRange.start
+      $lte: @timeRange.end
+    "jobProfileApproved": false
+  selection =  "_id email jobProfile.name jobProfile.updated emails"
+  User.find(findParameters).select(selection).lean().exec cb
+
+ignoredCandidateFilter = (candidate, cb) ->
+  findParameters = 
+    "user": candidate._id
+    "contactName": "Ignore"
+  UserRemark.count findParameters, (err, results) ->
+    if err? then return true
+    return cb Boolean(results.length)
+    
+unapprovedCandidateFilter = (candidate, sentEmailFilterCallback) ->
+  if candidate.emails?.anyNotes?.enabled is false or candidate.emails?.recruitNotes?.enabled is false
+    return sentEmailFilterCallback true
+  findParameters =
+    "user": candidate._id
+    "mailTask": @mailTaskName
+    "metadata.timeRangeName": @timeRange.name
+    "metadata.updated": candidate.jobProfile.updated
+  MailSent.find(findParameters).lean().exec (err, sentMail) ->
+    if err?
+      log.error "Error finding mail sent for task #{@mailTaskName} and user #{candidate._id}!"
+      sentEmailFilterCallback true
+    else
+      sentEmailFilterCallback Boolean(sentMail.length)
+
+sendReminderEmailToUnapprovedCandidate = (candidate, sendEmailCallback) ->
+  if err?
+    log.error "There was an error finding employers who signed up after #{candidate.jobProfile.updated}: #{err}"
+    return sendEmailCallback err
+  context =
+    email_id: "tem_RXyjzmc7S2HJH287pfoSPN"
+    recipient:
+      address: candidate.email
+      name: candidate.jobProfile.name
+    email_data:
+      user_profile: "http://codecombat.com/account/profile/#{candidate._id}"
+      recipient_address: encodeURIComponent(candidate.email)
+  log.info "Sending #{@timeRange.name} finish profile reminder to #{context.recipient.name}(#{context.recipient.address})"
+  newSentMail =
+    mailTask: @mailTaskName
+    user: candidate._id
+    metadata:
+      timeRangeName: @timeRange.name
+      updated: candidate.jobProfile.updated
+  MailSent.create newSentMail, (err) ->
+    if err? then return sendEmailCallback err
+    sendwithus.api.send context, (err, result) ->
+      log.error "Error sending candidate finish profile reminder email: #{err} with result #{result}" if err
+      sendEmailCallback null
+### End Unapproved Candidate Finish Reminder Task ###
+  
 ### Internal Candidate Update Reminder Email ###
 internalCandidateUpdateTask = ->
   mailTaskName = "internalCandidateUpdateTask"

From 321bce121c8772b38be3f837bff2f6ff21d1f88e Mon Sep 17 00:00:00 2001
From: Michael Schmatz <michaelschmatz@gmail.com>
Date: Fri, 18 Jul 2014 14:50:31 -0700
Subject: [PATCH 44/58] Edited task schema

---
 app/schemas/models/user_remark.coffee | 18 +++++++++++++++++-
 server/routes/mail.coffee             |  4 ++++
 2 files changed, 21 insertions(+), 1 deletion(-)

diff --git a/app/schemas/models/user_remark.coffee b/app/schemas/models/user_remark.coffee
index 839ce1380..260164a3b 100644
--- a/app/schemas/models/user_remark.coffee
+++ b/app/schemas/models/user_remark.coffee
@@ -12,7 +12,23 @@ _.extend UserRemarkSchema.properties,
   history: c.array {title: 'History', description: 'Records of our interactions with the user.'},
     c.object {title: 'Record'}, {date: c.date(title: 'Date'), content: {title: 'Content', type: 'string', format: 'markdown'}}
   tasks: c.array {title: 'Tasks', description: 'Task entries: when to email the contact about something.'},
-    c.object {title: 'Task'}, {date: c.date(title: 'Date'), action: {title: 'Action', type: 'string'}}
+    c.object {title: 'Task'}, 
+      date: c.date 
+        title: 'Date'
+      action: 
+        title: 'Action'
+        type: 'string'
+      status: 
+        title: 'Status'
+        description: 'The current status of the task'
+        type: 'string'
+        enum: ['Not started', 'In progress', 'Completed']
+      notes:
+        title: 'Notes'
+        description: 'Notes about the task in progress'
+        type: 'string'
+        format: 'markdown'
+        
 
   # denormalization
   userName: {title: 'Player Name', type: 'string'}
diff --git a/server/routes/mail.coffee b/server/routes/mail.coffee
index e0ef70220..0786a5f62 100644
--- a/server/routes/mail.coffee
+++ b/server/routes/mail.coffee
@@ -403,6 +403,10 @@ sendEmployerNewCandidatesAvailableEmail = (employer, cb) ->
         cb null
 
 ### End Employer New Candidates Available Email ###
+  
+### Task Emails ###
+userRemarkTaskEmailTask = ->
+  
 
 ### New Recruit Leaderboard Email ###
 ###

From 18631ec5b152468d0889713f9d4e9bd1c1a36aa8 Mon Sep 17 00:00:00 2001
From: George Saines <gsaines@gmail.com>
Date: Fri, 18 Jul 2014 15:42:53 -0700
Subject: [PATCH 45/58] upgrading our level icons

---
 app/assets/images/pages/home/language_js.png  | Bin 9586 -> 9268 bytes
 .../images/pages/home/language_python.png     | Bin 7633 -> 8282 bytes
 2 files changed, 0 insertions(+), 0 deletions(-)

diff --git a/app/assets/images/pages/home/language_js.png b/app/assets/images/pages/home/language_js.png
index 75db0f254b6ce29a7e5b869ec1d8ed2e98ee2c80..9da73cf33c8c7ee7d6e29f82ccb850e866574279 100644
GIT binary patch
delta 8701
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
Q65TFsbpy59XLgbQ3wXY0g#Z8m

delta 9001
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
OpQ$Lkl`oUE2>CzL&<<Sy

diff --git a/app/assets/images/pages/home/language_python.png b/app/assets/images/pages/home/language_python.png
index 80e09da9eddaaf746a569d80f1671a5e4b1e5f1d..71f23d4ad89a4618e74065bd1edbd01e3b13886d 100644
GIT binary patch
delta 7530
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

delta 6876
zcmV<28YAV}K+!vp<QX(MF)=J4GB7bSFEKDLGC3_VF*-CiIx#k}{b2zhLNGZ-IYKi;
zMMXhHF)>9mK`=5fML|VDFflSkGBq?glYRmmAVM%XMma(=Lq$bFMKLi&GeIyiFhxN{
zK`=2gMKU!sIg`2qVI*cWG%;Z@HZv__GGQ|<G-Ek9EnzldVJ$dgWHvKoIAJ$rI5v|%
z1A>3)m4h?@00RI}OjJdJcUMYOQ}XlkfPQ?y$;Zm0L9)ENKRPpmjEkkEq(ftW+Qf#{
zsy$k0b~`;gN<}$!g@a{gV_;cExu<k|aa&MEGqbX>Q(I-2iDT~Y@I7LI=IZHbbaceZ
z%Tr!lKt@H?xN}`>Yn7Usd4+_AaW;H^e$0Q&%c7KNT4ZERX@XT_V!OM#KS4x9XN8-l
zrHPl8>+bGxfPajdnT3;*cWhE}eSNf-OV!%hHZ(R>PCr3DJ8gV=!?AnJ)6#f|hhuGP
zlAoT6f?+;EK3#K$MNCUjS61Wa=SogZIW#hii;2#=fHyrxW^r-1n^bdSIC_eSqpg3f
zsEtKJW`x<;*jZd&-r?bqmX)iuv@|d;LrF)flUiwbc5Grxw!gltt*k96Db%SteuIL*
zpGvvHz%VT>)~-g};ov`Gf~K^x=H=y^tg2RQfJ|6doQPPxpH-Tem&wr1DJCXJQBa+n
zo5I4uV^}oCqD3__GRLM<m4Z}pW>9}eYKC)kbY)yeVr+JUh=*BYZP?x1uDZBsZfwb=
zO01u8)~rFmpiN#@OExn!OlEzMe_L8uRY*%wyvN2*S76PkN>5QxnTA?tU{Im4uhOeV
zMn^?lQ#3nZf2gRZQd34wO-(vqf77WxVQ+3TGB93me^6j<_51wRtwYDh#z=oeKPMz4
z|NsBf)YM&EOkP||#;IUVTw9ozla!{UHZ(DefL*Y!txZcv_xSjnh*#FFLcGMo;N;``
z{QPrqZ`G_o(AU+ioo~d<%fG+AIXE}dt3#@|w#Tn|G&(w$sHVHc!!b2AXlH1Wq@tUE
zHn5y+NlZ)C*VllLkMj8WhnRns)~rJ1$c50-(cI$W(bd&rXJ~$jh%z)X`1$#dpr4YG
zkCb~hwY9ay$jHvIYt*bmR!>H^xVLzDcTPw_Uub90*4K`Xk3c>@$jHZ^sHbabXVcc!
z&!|Pg%E-gb%!rwn#Kgp+j99RfO<!9{(5gt)t3J@DKi%TtPgGfOczA!Jg*G%XE-*GW
zG%zsa&y4BJigg<YZ2$lk=t)FDRCwC#-3wG4Rhj@`Xb{o^X`oT$k-%aM0VD(hNYOwW
zk%WXr6L}a~h(W`Ipsge%BdgAiiH|6ec{r0{;$vbIw9ITtBWwbB(UVnYoK@6yMrU+q
zcGb;>eebNh><(Mq?B0J@RTte|-38Po!E^s}Jcgz_-KW0%|NZZ+TU{a3^N;HI_(2$E
z5b*!;@zv8TF53v1*Q?7`4Vq&_e-UFITvf&n?^lXE>g=Fd3>N0Wvr+6Ae<jGP6BXQD
z-QC??Go-te5112KnP2SW)rloaUJga~rj8EyV@F5F1b#&Eub_W~sV`#ks8vdDOI!~(
zvFUds|M(nNZ{Xo0Jb#hvH5UI*K`%F9Q9QF`6|3-zlDxVwQbrsKOQ_=wIoue}^M-9{
z++Iwc!SyzPM>cFRaqV>pVMFrsBMVuoFFNx0X4$XDSjWS7hWn^^WaPkG5&2wiI3f?@
zmh2oEIkV%DOz?k?07RX!M}AdvJUifvi9Fuy@owjF7%p;6yAGc}f4JbNlf&dc=hp1n
zb^iR_n*}a&g8@CO-J@=1=!=HDS^~F()e-Iu#o^&AxeEgz3IxF<lgGkG@`X^YCp`RI
zF=np|lLmG(EANYfJgQI{z>PR@4Lf&-!&u3sWj5uPrVD>|ZbB;TmFcDVO_@R^_f7Pa
z@ZCG%YYawdSTAIa+~rT6NSd~x1mrzTyg_W`oS_1Y9Imnnk&kgsJAA<I<Z`8Fh3_62
z2CqvX=#h!+xL@AnW#$>+DQChx5s}F`D+M7m2SOwA6cgv{6og7A*Slqh;+bdi6zFEQ
z7JE6950ZZ|9D$E+kP|$7$GR2iFuifuIy>RhGK^Iw{6G#!_M=NYnI67-!ze%}WBMRF
z^p`8S)V6Jc<MHUoIXS)8Hlczp*weZ>Zsvk3T!HP*vE$zhMeF2bKQ}VU8#b{v?y@F7
zi%0P|)TMjC*A*enP@Bo2eon<<vV{`$Tn{?v-s6Api2k3)Sx}F{8{=n39)fGS5rXGQ
zB|V}b8#-21a6!+ciCje$LQgM{QhhfV(~Y>g|Juc30ivQXUNd<VF6uon#fPP)En)>E
z?5uEz8pBc1315-DBtmNBhWR?YHuD1WSeQ5-uZ_G6Z+_T>YPu5KZu81-w@-NGx(yBN
zE2Mu+2h|;q=r0(Tv!EK+EXzUYAyFF0%g``xL1#_MNsqn+^=poR+J4;~X%IbID(~e6
zehd|N%dcKyK{>W9gXYhc1tnkQDe4=frVWhY_6m<<qdRCcdY)YY(bJ_yZi7_ZUuP!N
zWBEsLNG}UQj>S)bso5wQ#Uq+#WVi-zZ*_l^=|v>bi$@KonE67*H45{PK;mJrsFOy0
zElBZ7hn9M-Uf~^;u)32(-)-Q-(4%`_WkD?tG^D(Ts(X%X9uh#j11_)Px%dt+5x1M>
z2ChUm**$ICxfCAlof0qhv!EI8ZUE+g56qv9QYFXY37$@UYq}uV<_@kzPXp#hw@QDV
zdjfi_eu@R1czDT@Yo6KHp8?Rf!M<IM{H!c~K<?Y*6nD=#6p1bs_XET{li|>e+xGRp
zYCz+8nSXLTI|JgQM7%%{svPqL_n<rAg527f=09W0B{brVv?`QMMW6R)B)ydCavk?e
z9wm#D+4u@UNE7uCm%DdZ+*gpLxKV#>&Uk2r=>jb9`}+GgEC)Zu`yr1iA-%dsT$+o!
zbqLQKotT%8hOxC*x)BP@uK{gb9+;jN`XMirW@l$)ai@OblDX4kegMzae)PXAbdSHj
z_D9gX3YcHl-=DDq{5i^pJQ1zA8RX7Q7H@Rx6pcRS2DA=$3lpNE9s`_HK?{Ee()`0J
zmur<bc^O*xR*Hu@bWCwYqB}wr=4ieBTINF|egVwisF|7qqj~?GE?2V`IUdOCcs@ny
z)hUQ8%nR__q|~A7lYhZ{sF+(&X}<%I-{Epqc#)$m5k{WRBlB^=PD5NW2eo}2exoEK
zeBc|5hf3T6O8c^@XW&8{_)~xN4Dxui>51nJc$IZ)HW|lN=}cGO^ELmG^<r;Ob1<G~
z<8`=m!*Q&%(+iO1^>@Aw$?L&1O-UXVg9malJ=>8k1QGvkR$JR@|52M<yHtyL`VMje
z9S-M_th7^!Z-9x~r-=Mfmn$*EyR47#{7zhLi-d~6;+X)vt*xzA1^s`>w}P5i2tpBl
zvz=q8YyUGA`ow+LE6A?}gZXQSe5K2EV~AI`eo7w5*OC({s%SY`ZMALpy!c{PvYL5)
zP;;BS^qPmxp8v)FvCu32==z}KW>VJiKpv6Z8KiUD|NQE<{gD19mFk{+EO-ysDP-eq
zkmr(MX*V+|J<)FsOn!fsbnC@9>zZ)09)RpvGBJI+)_-lU&6)^m4%+r6vP}kc?SILj
zbd0~cFCaPW-FoD*o-3Gwthse%wH?778keOqoUi`l;OlTEd8U>J7vW-<ldf@J0CKb~
zB10<cJJM~zCgj~&waNR@pPX|fmxl9f+_mri2l(SE#-wZ9tWJL(gQw)ATek)+>yW(d
zo`8itD7jSH$s*iH97}WkYx}Kg<S5D8`C)wU4`-W#F1i77(7ttn_U#_E$$3z6H!1Dp
zLY4-W<`jB3HS!pI%JdA`zuYNmBCl;bv~=leRdH?Pplc`RSBk?}n(H6e`zI$!o`eVT
zw*@Zv%6c~%!E1kyB-gH<J2^7v<TQVmr8$i>_e*ZZt1u|Zcf6Tz({L`OJ1c;-W^y;~
z;ELYD+oDdfxw-yvt3UEG+^#2K@lR463rp^>XTOcR_A#~uM`5DokGv4i$zhU5yg9Hr
zP0I;WoygsI|6}Z%sJ5ShbMr!`q-*?*A9A#*HGwyThrfSycwk^4)1is{(2->Cm@B!%
zo;fhE>pQ^w4tPQ>iZSUrnEN4Lg;&=PytV61ApU-(rd<);$8Pe8)wQ!HC!=}6z`)(x
z!ozo4SOcef_#tmbGqm5_J%FN=o9jlHiLAMjb3zk*Ymn$)!0&oxN|ec?@P@ZDSbSjp
zoVPx4b0U97=2h9~z2A&L4IHcNl*wUTAL9ALSp0p}g}0nPTpc*}KjcFmd8HJE&3_kg
z32q#}{jMQa+3Axvqi=-CBT3$*at6)06mEeD9JM~}+f~tWO#aIQ7WFe~_EPfxtg<fv
zIj-y930&8mhmHiFl=*h-SN*h4j)N^vysX~9Ws-mQ&xJoRCaUCcZ-j;CN%QuJ(?9vK
z=U1<uCwX6A%gtSC<W6BN{s4z9Y^MZm@(|Ror;sGu>|gx3wpty?`=YN@O>_HZ@(CUV
zKZGzRn&c&D9p>K@2i#whA6cyj`Q**&mA#34f|c;@JIsk9c@#d0M*8)Er~Q*3s?~-3
zgZqEgd-inl3D&V`8fEf$G(|Iz<NdbE4DD;Hbs_J&LVcbl{5$y!aQl2bgVLEi!9zZX
z&YK<}hr9IBk$2{Q;+Zo%#h`R1zs^J6jP^2<DcUEgmySHGl&r=qV>5HQ<T2<}IT^~w
zdsTKa&z1bMuOHMx4p(DLHP!<3AwFi?p(uZlf9@fN31;{WNpkB(mBrS%kk>vm0mx5i
zA%|)1NVi(wN1uW%#!zkF%Fsd#nU#+hi8_)e-_zx8p6t^~E@oS;R<s`DWLsnOCpXIE
z@o4{gIZ5&wJ;{&kce`(o)=r)Z$gQx2t70v?{^T7p`5;<*!`)kfHC0FQ=Z|sjmw$hF
zP&>H|l5c){V4$A0?D~_xHrBt-L*BthpgH;GIgr<?L|gKq3Ag)RuOtsho(9RS<8Ke#
zz{n|(C-mQe$<1iF6`fOAYqhF1?EcAX+uCX$Qi(%Xce~wJw)ANvM=iS*n-5H}t<4n3
zjr;a`$TN6+Mg^0*wUW23&f5R&9RGiTE;D}6Ylaqp-0dN^7JSUeDUf$O^O}M@50B(l
zt7#VG$ywhHxWCEyRP^b-*^oO3xwVv$Qy>TNdqfWRGuNdMajU4E{Q0F$_=}DHBl5`y
z?wUN&H!E^cB8MAuBAJx_<kul`d~aGJJ`3_A$AEar17ALIm*04-Z_+o#wUU2Z*;))8
z^51&M%Za#l^0q9K+g<p*=*iOu{l|&EK1P1Ik-zRC-#u=fC3$ka+a1z!x^K3@$S)<i
z(L;XHI!p3ekmN)EHG6SJeo4vq&VxL8soVYimOe(lxX54oV(#Q^SG(OePcrhwM*iqL
z$m`u3@9$&ei;X;P9%Ff$JMw=DM!q=7(WaPLlf$dc=#kg3Z80>-%`?a=E+u(|lAJBL
zE)couX_Z5@`jForfV`KHF9<pOniyk)bg-XRtL#gYbs?X8BEZShccf2|$-Xd#COO(7
zA(N|ak@!QKF61pw1=|QEeG0Zkf*LuzG1{pV>0n<_?cZ)Xq67KlpICnakWWdU;vMiq
zB9o#;j<-81M^RDb9t$(R#&J&MlmGpLKn?rH%8r6<cceyMjV9*fL1$_1iKVq|$<H4l
z;fH)OI!H|3_hi8Di^)}fh-xN9iyU3L(4MQDrKx@Ie${vPe@luSAM%5@-}~o2ajz%7
zAJXg$_-*_>(uXKwD=~j`$<ZurYtWY6C%nlgpPc8t^1`H2a|4^B(Itnow2qU(`#0+3
z3Cf0@&Cw{5!<Icxo~13BGx@>W6Mf?4*^uv6c5kd<r$`Q4cFVAIxW|XI-niPQeT#1K
zj_8tE+~9hsSo#bbS;J139DfJc8tHg{p*78ePts0&y<|2+`AL7p{#Mq#Q6-1{n^ErH
z_FgLTu`P<_R@S{yB}d;JQZA97v}mmCI+8b{3!cXnYj141l`1*9<wBA~o*Sky%>$92
zM%SrmCP#HWNx2Zit}draJ`FEe8IuR|v3ZjpJpIJYkDWd-JMyt|#jKoNszR9@&dkFi
zB=UwKZRV=v2mgQe!Hw?7kV(ztBKjJ#EsDh;HY=x0j=scIo|#8<%#%F&M)dpJqh~|j
zArIvn*;lyICr6b%K|17X+C@zboErIwpW^Rbe{fPGIr?ty_6Anh7l6E8B8QdzlsrvK
z(bm94s%&aL@xvJO`yWhxpp6_gZ+wKJUuSil7WsOK9NmAq{C9F?&(M_SUHAFFbm7D#
zJ}LfG%jxe~v?h6mRM(5xP0T5hZ<5K;*Zp-ANR^$B(~#z^t@pO5ZGDN{vuDp|kDZSG
zvQ=Y}$MMCAQz~pfGcEEvJ>+mTX6O+q&5Hx3d28$T?SS-^S3djkK^616LT-8BvB|#Z
z=2yTIw{L%MZ4I8}(y(G;>o63_r#$3nYs}tKa@e=1rFkRNenpPK7L|+0C!-IxoIcU=
zAM!Jydt;y^Pg0({WgB8Bk$<WnM-AMNyfr4N-Os(OfwzJi#RET{R7v!{4<=9F+B)OO
zd;F@4_{J_L6-myTH(KNmE6L#*RM9A<`Br|D4|#v9w>ONETkpEUf877&pZY$1PpeA1
zK1`aoqar(RN|F3dB{@2s7AJ2pO)^-#%(uUyOKkTeZZYs=u{E}WokXKazH$aRPV*W$
z%@e#z`yPGB_xLI62|T|>F_N<+r$zqh)C_Wz=0huDr8M{M;OJyI?%kx3JeFfgPLq74
z7dd}Q^M^C#G;jAR?X5cGx%XI(%6hvzlCNh;PLurMDKB!A=9Z~t()l!>((b2YpPjc)
z$1at1vesJTU`bAq9F%o$a<o(8i`0C4{MYe(n9oejYhFGZZa*_L5qIl6xgah-jqQz~
zNnYejj_!&m7G;w(U(OqP{4T=Dt8bdD)mMMt(6U>Pf#=uZHxxv67etEWu&n!#N5ONb
z&t)DZyPK2vI!l0s*H%am?e}>5<A=6G>ee6&t(H2TUrwgv@a`Is?2dS}$fx{~qx+bP
zaYB<^+R<9Owq5OWx;{nB0A(HbZcV7Hv-_6QB2V*AjygE;f;60;<b7H=oy9@xHjIDE
zdcIv`z1yWAuZE?)!k!%~b?v;7PM)KxE_U!dIfE9P3a8|e?0m|ClcVd?M3X?w!EjF6
z_C^}wpjjs?t+CngbPBr;?NX4VyJ3npA)O58!&J;Y;$(i7ZWGx(FDb??E>|Tc5A`LF
zia|G=mCSQ_$z0TV7{}tcbxZGr55#}4Zk<+K<#MHB@-&z0aW8VbAmgx0=39BGhZFS`
zH}Z1pmTq^jMHre<?Q*$lF!>uUSD80C9?qTq%p3J9>abV$h&$OpPBnfa59Kugf7*u}
zZIJOY$7?crBs%_k;0lbFINJ(CEe3(}1x#M=avk?WK3#&_cBOfHk3Q!3Z|Q$&SBML!
zSubHSG{x6r@u^DCz4;@LLgp2~JXSWxJEP`_PX3Bb@b61P;<4#M1rlei8>Kk=ED(R%
z=&9>v{>br)3^XV6b2wMy$1L+iCoi{*@p7*on~lZAXMe(iO1NO8{{9+yiuUZZU-IcP
z*&MIEu1Nt(hEw7^(52U&GC+UvawMKFiT}*Sf?g~s?!OZ!Iq26{sgM(M(8HzTb1dWK
z5GrG6uISS1hER%=JrPZ*xN~FT6eDNlFB|$3aFSQKT)oq3<Q{W*K!?TM&|#Siy7U@L
zhhfGrj>Rq8mb0K0zkF{)Mn6gNOczRWHF9F^2%TBn`Svi$PwO<jQGS0xSUXDbVyUQy
zq7@j+uU=w7DUwFs?FVt2T-J|I2Oys=Lw&oWQV;~P)j49=3q5$QE1pWglkk^C)CfW)
z5`XTx1{QORk-WS-gJ0_R^72L+-hH(n2X5Dw<+xlG)d9)LTun?9Jc(Y6)Y?7eJrKL{
zIhGC#&YzT0TtHhQ#OHs;`dQ37K77>^8D78JcTpC1Jw6?nd^!rP!=V9PsKFz8ZVHx5
zh!ee{(O)Si(UV}nFKa-TD8wEW$S^Mc6BDNz`|h|6?Q)#D!34w;r-PB>Ymh;4w*hm~
zx?8s<VZC-^kEkhnj3mMNhFsF93xW+5bx~RrVnI39!{%M04oH7KeHJxwq6sE?Hn~V~
zE6H@Ae##QW`;_d>7h~{JP}A*bjaA&3$t)Hm>S2nbW?cjMbaja*(S=Nco?9+C@^!|r
zo-PnC%#enU^n@Af<fjdn<Ezd}GX*)tEsrt``cacv^#%m*Et}RzE){pt*@@6ec^{9E
zQk_r8;b3(4#G!xjJuWV;3q6pNAcGfgCA(N5cqbmk#b2{!k_C(#qo%c!li3=n?n3r5
zvKMj<R!`u#Z~peW+uq^oc^=)Rh2P6fTpauSVH1}?ym5lZE(0Z9s_EhjY{hNiq9UYP
z2^ySSPIR#Xp$qBKHxG<&S$-ggGmi57XhaV83?^^qCO&@z(s{WY*PgOm`pU-Abofep
zg~(ETf#Z0{<6fLv$fv8#GtpCJ^$Xlb2lA43{_D0<kmiW|BDZ8DFYmxx5%pZX?43FT
z++01);?hNkwx^wqAzY>^fv7jZ3SZAnoj<>A+pe`uPVOWk|2enj{3F{U4i{u{HdxP_
zu(wb}O1gg-bCw<T#Xvqioft{TI2%rNFs`RBThCn>0P(&cm^dpTkA;uK3U;n{S$Z~p
zrrpMoS4SqYW4>6(r=tcXbkS5PsoS`;^!)t%qX5{6$-l{U)__Mcg-R}mcvngZE=CSU
zu|vLi$l-O0G4j;gWDA9yp_~)z=WuD6h&+MAt-XKU$-#MDs7>}3V^*=_z1YaXnBMGJ
zaB-Myoq!t7*zGxx9+9swaVGFcC;Xqy<nTPbnT_F#k{opJgE7j5HfJ}-IZfcdN&%7o
zGnjgVpPU@mt$bR{AnVc>Eje7A2~nzdb;HFsr^$pW_|qnn13uE-rSJ|ZV+VS1lSB1H
zv$jMNX`(rid4DCyVZ;xbBLiwjng`?A5&kNXqmey+FvMKqgI!_{8H{J6_vIP?FTem)
Wl{nr3RxTa@0000<MNUMnLSTYWXr)X5


From 90a4a1b635db04f91564537ad8a3e4afeaa6ea47 Mon Sep 17 00:00:00 2001
From: Scott Erickson <sderickson@gmail.com>
Date: Thu, 17 Jul 2014 16:22:06 -0700
Subject: [PATCH 46/58] Added setProjection so CocoModels can more easily get
 subsets of data.

---
 app/models/CocoModel.coffee           | 15 +++++++++++----
 test/app/models/CocoModel.spec.coffee |  8 ++++++++
 2 files changed, 19 insertions(+), 4 deletions(-)

diff --git a/app/models/CocoModel.coffee b/app/models/CocoModel.coffee
index 045843306..5da19cab3 100644
--- a/app/models/CocoModel.coffee
+++ b/app/models/CocoModel.coffee
@@ -13,8 +13,10 @@ class CocoModel extends Backbone.Model
 
   getMe: -> @me or @me = require('lib/auth').me
 
-  initialize: ->
-    super()
+  initialize: (attributes, options) ->
+    super(arguments...)
+    options ?= {}
+    @setProjection options.project
     if not @constructor.className
       console.error("#{@} needs a className set.")
     @addSchemaDefaults()
@@ -22,6 +24,8 @@ class CocoModel extends Backbone.Model
     @on 'error', @onError, @
     @on 'add', @onLoaded, @
     @saveBackup = _.debounce(@saveBackup, 500)
+    
+  setProjection: (@project) ->
 
   type: ->
     @constructor.className
@@ -116,8 +120,11 @@ class CocoModel extends Backbone.Model
     console.debug 'Patching', @get('name') or @, keys
     @save(attrs, options)
 
-  fetch: ->
-    @jqxhr = super(arguments...)
+  fetch: (options) ->
+    options ?= {}
+    options.data ?= {}
+    options.data.project = @project.join(',') if @project
+    @jqxhr = super(options)
     @loading = true
     @jqxhr
 
diff --git a/test/app/models/CocoModel.spec.coffee b/test/app/models/CocoModel.spec.coffee
index 67e019c9a..7f2529466 100644
--- a/test/app/models/CocoModel.spec.coffee
+++ b/test/app/models/CocoModel.spec.coffee
@@ -14,6 +14,14 @@ class BlandClass extends CocoModel
   urlRoot: '/db/bland'
 
 describe 'CocoModel', ->
+  describe 'setProjection', ->
+    it 'takes an array of properties to project and adds them as a query parameter', ->
+      b = new BlandClass({})
+      b.setProjection ['number', 'object']
+      b.fetch()
+      request = jasmine.Ajax.requests.mostRecent()
+      expect(decodeURIComponent(request.url).indexOf('project=number,object')).toBeGreaterThan(-1)
+  
   describe 'save', ->
 
     it 'saves to db/<urlRoot>', ->

From 52447f9e227d7da4e9a1a1d31313d8403a1e70f8 Mon Sep 17 00:00:00 2001
From: Scott Erickson <sderickson@gmail.com>
Date: Thu, 17 Jul 2014 09:12:12 -0700
Subject: [PATCH 47/58] Fixed the avatar endpoint handling when the user object
 DNE.

---
 server/users/user_handler.coffee | 1 +
 1 file changed, 1 insertion(+)

diff --git a/server/users/user_handler.coffee b/server/users/user_handler.coffee
index 020d30f20..275807ad7 100644
--- a/server/users/user_handler.coffee
+++ b/server/users/user_handler.coffee
@@ -219,6 +219,7 @@ UserHandler = class UserHandler extends Handler
   avatar: (req, res, id) ->
     @modelClass.findById(id).exec (err, document) =>
       return @sendDatabaseError(res, err) if err
+      return @sendNotFoundError(res) unless document
       photoURL = document?.get('photoURL')
       if photoURL
         photoURL = "/file/#{photoURL}"

From 4658c3000f34d0655adbca47a861d3ec68635cd5 Mon Sep 17 00:00:00 2001
From: Scott Erickson <sderickson@gmail.com>
Date: Thu, 17 Jul 2014 16:28:52 -0700
Subject: [PATCH 48/58] Extended getLatestVersion for Handler to also be able
 to accept project parameters.

---
 server/commons/Handler.coffee | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/server/commons/Handler.coffee b/server/commons/Handler.coffee
index a796b705e..9dfca705b 100644
--- a/server/commons/Handler.coffee
+++ b/server/commons/Handler.coffee
@@ -232,7 +232,11 @@ module.exports = class Handler
       query['version.minor'] = minorVersion unless _.isNaN(minorVersion)
     sort = { 'version.major': -1, 'version.minor': -1 }
     args = [query]
-    args.push PROJECT if req.query.project
+    if req.query.project
+      projection = {}
+      fields = if req.query.project is 'true' then _.keys(PROJECT) else req.query.project.split(',')
+      projection[field] = 1 for field in fields
+      args.push projection
     @modelClass.findOne(args...).sort(sort).exec (err, doc) =>
       return @sendNotFoundError(res) unless doc?
       return @sendUnauthorizedError(res) unless @hasAccessToDocument(req, doc)

From 74425103d18e8122865fb0c17aa0c124f9e5e1c2 Mon Sep 17 00:00:00 2001
From: Scott Erickson <sderickson@gmail.com>
Date: Thu, 17 Jul 2014 16:29:26 -0700
Subject: [PATCH 49/58] Fixed some DemoView issues, mainly clicking links from
 one demo to another.

---
 app/views/DemoView.coffee | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/app/views/DemoView.coffee b/app/views/DemoView.coffee
index a3b65c781..d18190162 100644
--- a/app/views/DemoView.coffee
+++ b/app/views/DemoView.coffee
@@ -35,6 +35,7 @@ module.exports = DemoView = class DemoView extends CocoView
     @loadDemoingLibs() unless DemoView.loaded
 
   loadDemoingLibs: ->
+    DemoView.loaded = true
     @queue = new createjs.LoadQueue()
     @queue.on('complete', @scriptsLoaded, @)
     window.jasmine = {} # so that mock-ajax properly loads. It expects jasmine to be loaded
@@ -81,8 +82,14 @@ module.exports = DemoView = class DemoView extends CocoView
     view = demoFunc()
     return unless view
     @$el.find('#demo-area').empty().append(view.$el)
+    view.afterInsert()
     # TODO, maybe handle root views differently than modal views differently than everything else?
 
   getAllDemoFiles: ->
     allFiles = window.require.list()
     (f for f in allFiles when f.indexOf('.demo') > -1)
+
+  destroy: ->
+    # hack to get jasmine tests to properly run again on clicking links, and make sure if you
+    # leave this page (say, back to the main site) that test stuff doesn't follow you.
+    document.location.reload()

From 9ad166048d37daaef40a6d961c871c003a13d3e8 Mon Sep 17 00:00:00 2001
From: Scott Erickson <sderickson@gmail.com>
Date: Thu, 17 Jul 2014 09:12:21 -0700
Subject: [PATCH 50/58] Some work the job profile page. Added a demo view,
 mainly added a modal view for viewing raw player code.

---
 app/schemas/models/level.coffee               |   2 +
 app/schemas/models/level_session.coffee       |   2 +-
 app/styles/account/profile.sass               |   3 +-
 app/styles/base.sass                          |  13 +-
 .../common/level_session_code_view.sass       |  25 +
 .../account/job_profile_code_modal.jade       |  12 +
 app/templates/account/profile.jade            |   7 +-
 app/templates/base.jade                       |   2 +-
 app/templates/common/level_session_code.jade  |  13 +
 app/views/account/JobProfileCodeModal.coffee  |  25 +
 app/views/account/profile_view.coffee         |  14 +-
 app/views/common/LevelSessionCodeView.coffee  |  50 ++
 .../editor/level/settings_tab_view.coffee     |   2 +-
 app/views/kinds/RootView.coffee               |   7 +
 server/levels/level_handler.coffee            |   2 +
 server/users/user_handler.coffee              |   2 +-
 .../common/LevelSessionCodeView.demo.coffee   |  13 +
 .../views/user/JobProfileView.demo.coffee     | 576 ++++++++++++++++++
 18 files changed, 754 insertions(+), 16 deletions(-)
 create mode 100644 app/styles/common/level_session_code_view.sass
 create mode 100644 app/templates/account/job_profile_code_modal.jade
 create mode 100644 app/templates/common/level_session_code.jade
 create mode 100644 app/views/account/JobProfileCodeModal.coffee
 create mode 100644 app/views/common/LevelSessionCodeView.coffee
 create mode 100644 test/demo/views/common/LevelSessionCodeView.demo.coffee
 create mode 100644 test/demo/views/user/JobProfileView.demo.coffee

diff --git a/app/schemas/models/level.coffee b/app/schemas/models/level.coffee
index eba42f599..262c02d18 100644
--- a/app/schemas/models/level.coffee
+++ b/app/schemas/models/level.coffee
@@ -230,12 +230,14 @@ _.extend LevelSchema.properties,
     title: 'Next Level',
     description: 'Reference to the next level players will play after beating this one.'
   }
+  employerDescription: { type:'string', format: 'markdown', title: 'Employer Description' }
   scripts: c.array {title: 'Scripts', description: 'An array of scripts that trigger based on what the player does and affect things outside of the core level simulation.', 'default': []}, ScriptSchema
   thangs: c.array {title: 'Thangs', description: 'An array of Thangs that make up the level.', 'default': []}, LevelThangSchema
   systems: c.array {title: 'Systems', description: 'Levels are configured by changing the Systems attached to them.', uniqueItems: true, default: []}, LevelSystemSchema  # TODO: uniqueness should be based on 'original', not whole thing
   victory: c.object {title: 'Victory Screen', default: {}, properties: {'body': {type: 'string', format: 'markdown', title: 'Body Text', description: 'Inserted into the Victory Modal once this level is complete. Tell the player they did a good job and what they accomplished!'}, i18n: {type: 'object', format: 'i18n', props: ['body'], description: 'Help translate this victory message'}}}
   i18n: {type: 'object', format: 'i18n', props: ['name', 'description'], description: 'Help translate this level'}
   icon: {type: 'string', format: 'image-file', title: 'Icon'}
+  banner: {type: 'string', format: 'image-file', title: 'Banner'}
   goals: c.array {title: 'Goals', description: 'An array of goals which are visible to the player and can trigger scripts.'}, GoalSchema
   type: c.shortString(title: 'Type', description: 'What kind of level this is.', 'enum': ['campaign', 'ladder', 'ladder-tutorial'])
   showsGuide: c.shortString(title: 'Shows Guide', description: 'If the guide is shown at the beginning of the level.', 'enum': ['first-time', 'always'])
diff --git a/app/schemas/models/level_session.coffee b/app/schemas/models/level_session.coffee
index f4f629914..92ff0f5ba 100644
--- a/app/schemas/models/level_session.coffee
+++ b/app/schemas/models/level_session.coffee
@@ -13,7 +13,7 @@ LevelSessionPlayerSchema = c.object
   changes:
     type: 'Number'
 
-LevelSessionLevelSchema = c.object {required: ['original', 'majorVersion']},
+LevelSessionLevelSchema = c.object {required: ['original', 'majorVersion'], links: [{rel: 'db', href: '/db/level/{(original)}/version/{(majorVersion)}'}]},
   original: c.objectId({})
   majorVersion:
     type: 'integer'
diff --git a/app/styles/account/profile.sass b/app/styles/account/profile.sass
index 05a06f6ee..a661ea611 100644
--- a/app/styles/account/profile.sass
+++ b/app/styles/account/profile.sass
@@ -127,13 +127,14 @@
               text-align: center
 
           ul.links
+            text-align: center
             li.has-icon
               display: inline-block
               img
                 margin: 0 0 10px 0
             li.has-icon:not(:nth-child(5))
               img
-                margin: 0 10px 10px 0
+                margin: 0 5px 10px 5px
 
           #contact-candidate
             margin-top: 20px
diff --git a/app/styles/base.sass b/app/styles/base.sass
index eae0d473b..c873d3d0f 100644
--- a/app/styles/base.sass
+++ b/app/styles/base.sass
@@ -24,13 +24,16 @@ h1 h2 h3 h4
   @include box-sizing(border-box)
 
 #outer-content-wrapper
+  background: #B4B4B4
+  
+#outer-content-wrapper.show-background
   background: #8cc63f url(/images/pages/base/repeat-tile.png) top center
 
-#intermediate-content-wrapper
-  background: url(/images/pages/base/sky_repeater.png) repeat-x
+  #intermediate-content-wrapper
+    background: url(/images/pages/base/sky_repeater.png) repeat-x
 
-#inner-content-wrapper
-  background: url(/images/pages/base/background_texture.png) top center no-repeat
+  #inner-content-wrapper
+    background: url(/images/pages/base/background_texture.png) top center no-repeat
 
 #front-summary-points-left
   width: 250px
@@ -70,7 +73,7 @@ h1 h2 h3 h4
   &:hover
     color: $white
 
-a[data-toggle="modal"]
+a
   cursor: pointer
 
 .share-buttons, .partner-badges
diff --git a/app/styles/common/level_session_code_view.sass b/app/styles/common/level_session_code_view.sass
new file mode 100644
index 000000000..270d9a0d3
--- /dev/null
+++ b/app/styles/common/level_session_code_view.sass
@@ -0,0 +1,25 @@
+.level-session-code-view
+  #level-icon
+    max-width: 60%
+    max-height: 150px
+    margin-right: 10px
+    display: inline-block
+    float: right
+    margin-bottom: 20px
+   
+  #level-meta-data
+    width: 35%
+    button
+      float: right
+    
+  #session-code
+    clear: both
+    margin-top: 20px
+    
+    h3
+      font-family: Arial
+      margin: 0
+      
+    .code
+      height: 600px
+      border: 2px solid black
\ No newline at end of file
diff --git a/app/templates/account/job_profile_code_modal.jade b/app/templates/account/job_profile_code_modal.jade
new file mode 100644
index 000000000..6f5703ef6
--- /dev/null
+++ b/app/templates/account/job_profile_code_modal.jade
@@ -0,0 +1,12 @@
+extends /templates/modal/modal_base
+
+block modal-header-content
+  h3 Applicant Code for
+    span.spl= session.get('levelName')
+
+block modal-body-content
+  .level-session-code-view
+
+block modal-footer
+  .modal-footer
+    button(data-dismiss="modal", data-i18n="modal.close").btn Close
diff --git a/app/templates/account/profile.jade b/app/templates/account/profile.jade
index 11c0d6956..2699a3ac1 100644
--- a/app/templates/account/profile.jade
+++ b/app/templates/account/profile.jade
@@ -181,13 +181,12 @@ block content
               ul.sessions
                 each session in sessions
                   li
-                    - var sessionLink = "/play/level/" + session.levelID + "?team=" + (session.team || 'humans') + (myProfile ? '' : "&session=" + session._id);
-                    a(href=sessionLink)
+                    a.session-link(data-session-id=session._id)
                       span= session.levelName
                       if session.team
-                        span  #{session.team}
+                        span.spl - #{session.team}
                     if session.codeLanguage != 'javascript'
-                      span  - #{{coffeescript: 'CoffeeScript', python: 'Python', lua: 'Lua', io: 'Io', clojure: 'Clojure'}[session.codeLanguage]}
+                      span.spl - #{{coffeescript: 'CoffeeScript', python: 'Python', lua: 'Lua', io: 'Io', clojure: 'Clojure'}[session.codeLanguage]}
 
         .middle-column.full-height-column
           .sub-column
diff --git a/app/templates/base.jade b/app/templates/base.jade
index 01a67687c..6c18d420c 100644
--- a/app/templates/base.jade
+++ b/app/templates/base.jade
@@ -49,7 +49,7 @@ body
             a.header-font(href='/community', data-i18n="nav.community") Community
 
   block outer_content
-    #outer-content-wrapper
+    #outer-content-wrapper(class=showBackground ? 'show-background' : '')
       #intermediate-content-wrapper
         #inner-content-wrapper
           .main-content-area
diff --git a/app/templates/common/level_session_code.jade b/app/templates/common/level_session_code.jade
new file mode 100644
index 000000000..ad998e89d
--- /dev/null
+++ b/app/templates/common/level_session_code.jade
@@ -0,0 +1,13 @@
+div#session-info
+  img(src='/file/'+levelIcon alt='levelIcon')#level-icon
+  div#level-meta-data
+    a.btn.btn-primary(href=sessionLink, target=_blank) Spectate
+    p!= levelDescription
+  
+div#session-code
+  for spell in levelSpells
+    .panel.panel-success
+      .panel-heading
+        h3= spell.name
+      .panel-body
+        .code(data-height=spell.height)= spell.code
\ No newline at end of file
diff --git a/app/views/account/JobProfileCodeModal.coffee b/app/views/account/JobProfileCodeModal.coffee
new file mode 100644
index 000000000..397de97cf
--- /dev/null
+++ b/app/views/account/JobProfileCodeModal.coffee
@@ -0,0 +1,25 @@
+ModalView = require 'views/kinds/ModalView'
+template = require 'templates/account/job_profile_code_modal'
+LevelSessionCodeView = require 'views/common/LevelSessionCodeView'
+console.log 'template', template
+
+module.exports = class JobProfileCodeModal extends ModalView
+  id: 'job_profile_code_modal'
+  template: template
+  modalWidthPercent: 90
+  plain: true
+  
+  constructor: (options) ->
+    super(arguments...)
+    @session = options.session
+    
+  getRenderData: ->
+    c = super()
+    c.session = @session
+    c
+
+  afterRender: ->
+    super()
+    codeView = new LevelSessionCodeView({session:@session})
+    @insertSubView(codeView, @$el.find('.level-session-code-view'))
+    
\ No newline at end of file
diff --git a/app/views/account/profile_view.coffee b/app/views/account/profile_view.coffee
index 213b89a97..ca33ba8e8 100644
--- a/app/views/account/profile_view.coffee
+++ b/app/views/account/profile_view.coffee
@@ -1,4 +1,4 @@
-View = require 'views/kinds/RootView'
+RootView = require 'views/kinds/RootView'
 template = require 'templates/account/profile'
 User = require 'models/User'
 LevelSession = require 'models/LevelSession'
@@ -9,6 +9,7 @@ JobProfileView = require 'views/account/job_profile_view'
 UserRemark = require 'models/UserRemark'
 forms = require 'lib/forms'
 ModelModal = require 'views/modal/model_modal'
+JobProfileCodeModal = require './JobProfileCodeModal'
 
 class LevelSessionsCollection extends CocoCollection
   url: -> "/db/user/#{@userID}/level.sessions/employer"
@@ -25,9 +26,11 @@ adminContacts = [
   {id: '52a57252a89409700d0000d9', name: 'Ignore'}
 ]
 
-module.exports = class ProfileView extends View
+module.exports = class ProfileView extends RootView
   id: 'profile-view'
   template: template
+  showBackground: false
+
   subscriptions:
     'linkedin-loaded': 'onLinkedInLoaded'
 
@@ -49,6 +52,7 @@ module.exports = class ProfileView extends View
     'keyup .editable-profile .editable-array input': 'onEditArray'
     'click .editable-profile a': 'onClickLinkWhileEditing'
     'change #admin-contact': 'onAdminContactChanged'
+    'click .session-link': 'onSessionLinkPressed'
 
   constructor: (options, @userID) ->
     @userID ?= me.id
@@ -584,3 +588,9 @@ module.exports = class ProfileView extends View
       {name: t('account_profile.next_photo'), weight: 2, container: '#profile-photo-container', fn: modified 'photoURL'}
       {name: t('account_profile.next_active'), weight: 1, fn: modified 'active'}
     ]
+
+  onSessionLinkPressed: (e) ->
+    sessionID = $(e.target).closest('.session-link').data('session-id')
+    session = _.find @sessions.models, (session) -> session.id is sessionID
+    modal = new JobProfileCodeModal({session:session})
+    @openModalView modal
\ No newline at end of file
diff --git a/app/views/common/LevelSessionCodeView.coffee b/app/views/common/LevelSessionCodeView.coffee
new file mode 100644
index 000000000..768793115
--- /dev/null
+++ b/app/views/common/LevelSessionCodeView.coffee
@@ -0,0 +1,50 @@
+CocoView = require 'views/kinds/CocoView'
+template = require 'templates/common/level_session_code'
+
+Level = require 'models/Level'
+LevelSession = require 'models/LevelSession'
+
+module.exports = class LevelSessionCodeView extends CocoView
+  className: 'level-session-code-view'
+  template: template
+
+  constructor: (options) ->
+    super(options)
+    @session = options.session
+    @level = LevelSession.getReferencedModel(@session.get('level'), LevelSession.schema.properties.level)
+    @level.setProjection ['employerDescription', 'name', 'icon', 'banner', 'slug']
+    @supermodel.loadModel @level, 'level'
+
+  getRenderData: ->
+    c = super()
+    c.levelIcon = @level.get('banner') or @level.get('icon')
+    c.levelName = @level.get('name')
+    c.levelDescription = marked(@level.get('employerDescription') or '')
+    c.levelSpells = @organizeCode()
+    c.sessionLink = "/play/level/" + (@level.get('slug') or @level.id) + "?team=" + (@session.get('team') || 'humans') + "&session=" + @session.id
+    c
+    
+  afterRender: ->
+    super()
+    @$el.find('.code').each (index, codeEl) ->
+      height = parseInt($(codeEl).data('height'))
+      $(codeEl).height(height)
+      editor = ace.edit codeEl
+      editor.setReadOnly true
+      aceSession = editor.getSession()
+      aceSession.setMode 'ace/mode/javascript'
+    
+  organizeCode: ->
+    team = @session.get('team') or 'humans'
+    teamSpells = @session.get('teamSpells')[team] or []
+    filteredSpells = []
+    for spell in teamSpells
+      code = @session.getSourceFor(spell)
+      lines = code.split('\n').length
+      height = lines * 16 + 20
+      filteredSpells.push {
+        code: code
+        name: spell
+        height: height
+      }
+    filteredSpells 
\ No newline at end of file
diff --git a/app/views/editor/level/settings_tab_view.coffee b/app/views/editor/level/settings_tab_view.coffee
index b3f99150c..21504830a 100644
--- a/app/views/editor/level/settings_tab_view.coffee
+++ b/app/views/editor/level/settings_tab_view.coffee
@@ -13,7 +13,7 @@ module.exports = class SettingsTabView extends View
   # not thangs or scripts or the backend stuff
   editableSettings: [
     'name', 'description', 'documentation', 'nextLevel', 'background', 'victory', 'i18n', 'icon', 'goals',
-    'type', 'showsGuide'
+    'type', 'showsGuide', 'banner', 'employerDescription'
   ]
 
   subscriptions:
diff --git a/app/views/kinds/RootView.coffee b/app/views/kinds/RootView.coffee
index aac5dc64f..858c9fb48 100644
--- a/app/views/kinds/RootView.coffee
+++ b/app/views/kinds/RootView.coffee
@@ -17,6 +17,8 @@ filterKeyboardEvents = (allowedEvents, func) ->
     return func(splat...)
 
 module.exports = class RootView extends CocoView
+  showBackground: true
+  
   events:
     'click #logout-button': 'logoutAccount'
     'change .language-dropdown': 'onLanguageChanged'
@@ -112,6 +114,11 @@ module.exports = class RootView extends CocoView
     @renderScrollbar()
     #@$('.antiscroll-wrap').antiscroll()  # not yet, buggy
 
+  getRenderData: ->
+    c = super()
+    c.showBackground = @showBackground
+    c
+  
   afterRender: ->
     super(arguments...)
     @chooseTab(location.hash.replace('#', '')) if location.hash
diff --git a/server/levels/level_handler.coffee b/server/levels/level_handler.coffee
index bcda60e1c..76d0ed8ac 100644
--- a/server/levels/level_handler.coffee
+++ b/server/levels/level_handler.coffee
@@ -25,6 +25,8 @@ LevelHandler = class LevelHandler extends Handler
     'goals'
     'type'
     'showsGuide'
+    'banner'
+    'employerDescription'
   ]
 
   postEditableProperties: ['name']
diff --git a/server/users/user_handler.coffee b/server/users/user_handler.coffee
index 275807ad7..fbd13ec19 100644
--- a/server/users/user_handler.coffee
+++ b/server/users/user_handler.coffee
@@ -233,7 +233,7 @@ UserHandler = class UserHandler extends Handler
   getLevelSessionsForEmployer: (req, res, userID) ->
     return @sendUnauthorizedError(res) unless req.user._id+'' is userID or req.user.isAdmin() or ('employer' in req.user.get('permissions'))
     query = creator: userID, levelID: {$in: ['gridmancer', 'greed', 'dungeon-arena', 'brawlwood', 'gold-rush']}
-    projection = 'levelName levelID team playtime codeLanguage submitted code totalScore'
+    projection = 'levelName levelID team playtime codeLanguage submitted code totalScore teamSpells level'
     LevelSession.find(query).select(projection).exec (err, documents) =>
       return @sendDatabaseError(res, err) if err
       documents = (LevelSessionHandler.formatEntity(req, doc) for doc in documents)
diff --git a/test/demo/views/common/LevelSessionCodeView.demo.coffee b/test/demo/views/common/LevelSessionCodeView.demo.coffee
new file mode 100644
index 000000000..a7aa3810e
--- /dev/null
+++ b/test/demo/views/common/LevelSessionCodeView.demo.coffee
@@ -0,0 +1,13 @@
+LevelSessionCodeView = require 'views/common/LevelSessionCodeView'
+LevelSession = require 'models/LevelSession'
+
+levelSessionData = {"_id":"5317ad4909098828ed071f4d","level":{"original":"53173f76c269d400000543c2","majorVersion":0},"team":"humans","levelID":"dungeon-arena","levelName":"Dungeon Arena","submitted":true,"totalScore":38.4584087145667,"code":{"programmable-librarian":{"chooseAction":"// The Librarian is a spellcaster with a fireball attack\n// plus three useful spells: 'slow', 'regen', and 'haste'.\n// Slow makes a target move and attack at half speed for 5s.\n// Regen makes a target heal 10 hp/s for 10s.\n// Haste speeds up a target by 4x for 5s, once per match.\n\nvar enemies = this.getEnemies();\nif (enemies.length === 0) return;  // Chill if all enemies are dead.\nvar enemy = this.getNearest(enemies);\nif (this.canCast('slow', enemy)) {\n    // Slow the enemy, or chase if out of range (30m).\n    this.castSlow(enemy);\n    if (this.distance(enemy) <= 50)\n        this.say(\"Not so fast, \" + enemy.type + \" \" + enemy.id);\n}\nelse {\n    this.attack(enemy);\n}\nvar base = this.getFriends()[0];\nvar d = base.distance(enemy);\n// You can also command your troops with this.say():\n//this.say(\"Defend!\", {targetPos: {x: 30, y: 30}}));\n//this.say(\"Attack!\", {target: enemy});\n//this.say(\"Move!\", {targetPos: {x: 50, y: 40});\n"},"human-base":{"chooseAction":"// This is the code for your base. Decide which unit to build each frame.\n// Units you build will go into the this.built array.\n// Destroy the enemy base within 60 seconds!\n// Check out the Guide at the top for more info.\n\n// CHOOSE YOUR HERO! You can only build one hero.\nvar hero;\n//hero = 'tharin';  // A fierce knight with battlecry abilities.\nhero = 'hushbaum';  // A fiery spellcaster hero.\n\nif(hero && !this.builtHero) {\n    this.builtHero = this.build(hero);\n    return;\n}\n\n// Soldiers are hard-to-kill, low damage melee units with 2s build cooldown.\n// Archers are fragile but deadly ranged units with 2.5s build cooldown.\nvar buildOrder = ['soldier', 'soldier', 'soldier', 'soldier', 'archer'];\nvar type = buildOrder[this.built.length % buildOrder.length];\n//this.say('Unit #' + this.built.length + ' will be a ' + type);\nthis.build(type);"},"hushbaum":{"chooseAction":"var enemy = this.getNearestEnemy();\nif (enemy) {\n    if (!enemy.hasEffect('slow')) {\n        this.say(\"Not so fast, \" + enemy.type + \" \" + enemy.id);\n        this.castSlow(enemy);\n    }\n    else {\n        this.attack(enemy);\n    }\n}\nelse {\n    this.move({x: 70, y: 30});\n}\n"},"tharin":{"chooseAction":"var enemies = this.getEnemies();\nvar enemy = this.getNearest(enemies);\nif (!this.getCooldown('warcry')) {\n    this.warcry();\n}\nelse if (enemy) {\n    this.attack(enemy);\n}\nelse {\n    this.move({x: 10, y: 30});\n}\n"},"tharin-1":{"chooseAction":"var __interceptThis=(function(){var G=this;return function($this,sandbox){if($this==G){return sandbox;}return $this;};})();\nreturn (function (__global) {\n    var tmp0, tmp1;\n    tmp1 = function () {\n        _aether.logCallStart(this._aetherUserInfo); var enemies, enemy, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8, tmp9, tmp10, tmp11, tmp12, tmp13, tmp14, tmp15, tmp16, tmp17, tmp18, tmp19, tmp20, tmp21, tmp22, tmp23, tmp24, tmp25, tmp26;\n        tmp2 = 'use strict';\n        tmp3 = __interceptThis(this, __global);\n        tmp4 = 'getEnemies';\n        _aether.logStatementStart([{ofs: 0, row: 0, col: 0}, {ofs: 32, row: 0, col: 32}]); enemies = tmp3[tmp4](); _aether.vars['enemies'] = typeof enemies == 'undefined' ? undefined : enemies; _aether.vars['enemy'] = typeof enemy == 'undefined' ? undefined : enemy; _aether.vars['chooseAction'] = typeof chooseAction == 'undefined' ? undefined : chooseAction; _aether.logStatement([{ofs: 0, row: 0, col: 0}, {ofs: 32, row: 0, col: 32}], \"var enemies = this.getEnemies();\", this._aetherUserInfo);\n        tmp5 = __interceptThis(this, __global);\n        tmp6 = 'getNearest';\n        tmp7 = enemies;\n        _aether.logStatementStart([{ofs: 33, row: 1, col: 0}, {ofs: 70, row: 1, col: 37}]); enemy = tmp5[tmp6](tmp7); _aether.vars['enemies'] = typeof enemies == 'undefined' ? undefined : enemies; _aether.vars['enemy'] = typeof enemy == 'undefined' ? undefined : enemy; _aether.vars['chooseAction'] = typeof chooseAction == 'undefined' ? undefined : chooseAction; _aether.logStatement([{ofs: 33, row: 1, col: 0}, {ofs: 70, row: 1, col: 37}], \"var enemy = this.getNearest(enemies);\", this._aetherUserInfo);\n        tmp10 = __interceptThis(this, __global);\n        tmp11 = 'getCooldown';\n        _aether.logStatementStart([{ofs: 93, row: 2, col: 22}, {ofs: 101, row: 2, col: 30}]); tmp12 = 'warcry'; _aether.vars['enemies'] = typeof enemies == 'undefined' ? undefined : enemies; _aether.vars['enemy'] = typeof enemy == 'undefined' ? undefined : enemy; _aether.vars['chooseAction'] = typeof chooseAction == 'undefined' ? undefined : chooseAction; _aether.logStatement([{ofs: 93, row: 2, col: 22}, {ofs: 101, row: 2, col: 30}], \"'warcry'\", this._aetherUserInfo);\n        _aether.logStatementStart([{ofs: 76, row: 2, col: 5}, {ofs: 102, row: 2, col: 31}]); tmp9 = tmp10[tmp11](tmp12); _aether.vars['enemies'] = typeof enemies == 'undefined' ? undefined : enemies; _aether.vars['enemy'] = typeof enemy == 'undefined' ? undefined : enemy; _aether.vars['chooseAction'] = typeof chooseAction == 'undefined' ? undefined : chooseAction; _aether.logStatement([{ofs: 76, row: 2, col: 5}, {ofs: 102, row: 2, col: 31}], \"this.getCooldown('warcry')\", this._aetherUserInfo);\n        _aether.logStatementStart([{ofs: 75, row: 2, col: 4}, {ofs: 102, row: 2, col: 31}]); tmp8 = !tmp9; _aether.vars['enemies'] = typeof enemies == 'undefined' ? undefined : enemies; _aether.vars['enemy'] = typeof enemy == 'undefined' ? undefined : enemy; _aether.vars['chooseAction'] = typeof chooseAction == 'undefined' ? undefined : chooseAction; _aether.logStatement([{ofs: 75, row: 2, col: 4}, {ofs: 102, row: 2, col: 31}], \"!this.getCooldown('warcry')\", this._aetherUserInfo);\n        if (tmp8) {\n            tmp13 = __interceptThis(this, __global);\n            tmp14 = 'warcry';\n            _aether.logStatementStart([{ofs: 110, row: 3, col: 4}, {ofs: 123, row: 3, col: 17}]); tmp15 = tmp13[tmp14](); _aether.vars['enemies'] = typeof enemies == 'undefined' ? undefined : enemies; _aether.vars['enemy'] = typeof enemy == 'undefined' ? undefined : enemy; _aether.vars['chooseAction'] = typeof chooseAction == 'undefined' ? undefined : chooseAction; _aether.logStatement([{ofs: 110, row: 3, col: 4}, {ofs: 123, row: 3, col: 17}], \"this.warcry()\", this._aetherUserInfo);\n        } else {\n            tmp16 = enemy;\n            if (tmp16) {\n                tmp17 = __interceptThis(this, __global);\n                tmp18 = 'attack';\n                tmp19 = enemy;\n                _aether.logStatementStart([{ofs: 149, row: 6, col: 4}, {ofs: 167, row: 6, col: 22}]); tmp20 = tmp17[tmp18](tmp19); _aether.vars['enemies'] = typeof enemies == 'undefined' ? undefined : enemies; _aether.vars['enemy'] = typeof enemy == 'undefined' ? undefined : enemy; _aether.vars['chooseAction'] = typeof chooseAction == 'undefined' ? undefined : chooseAction; _aether.logStatement([{ofs: 149, row: 6, col: 4}, {ofs: 167, row: 6, col: 22}], \"this.attack(enemy)\", this._aetherUserInfo);\n            } else {\n                tmp21 = __interceptThis(this, __global);\n                tmp22 = 'move';\n                _aether.logStatementStart([{ofs: 196, row: 9, col: 18}, {ofs: 198, row: 9, col: 20}]); tmp24 = 10; _aether.vars['enemies'] = typeof enemies == 'undefined' ? undefined : enemies; _aether.vars['enemy'] = typeof enemy == 'undefined' ? undefined : enemy; _aether.vars['chooseAction'] = typeof chooseAction == 'undefined' ? undefined : chooseAction; _aether.logStatement([{ofs: 196, row: 9, col: 18}, {ofs: 198, row: 9, col: 20}], \"10\", this._aetherUserInfo);\n                _aether.logStatementStart([{ofs: 203, row: 9, col: 25}, {ofs: 205, row: 9, col: 27}]); tmp25 = 30; _aether.vars['enemies'] = typeof enemies == 'undefined' ? undefined : enemies; _aether.vars['enemy'] = typeof enemy == 'undefined' ? undefined : enemy; _aether.vars['chooseAction'] = typeof chooseAction == 'undefined' ? undefined : chooseAction; _aether.logStatement([{ofs: 203, row: 9, col: 25}, {ofs: 205, row: 9, col: 27}], \"30\", this._aetherUserInfo);\n                _aether.logStatementStart([{ofs: 192, row: 9, col: 14}, {ofs: 206, row: 9, col: 28}]); tmp23 = {\n                    x: tmp24,\n                    y: tmp25\n                }; _aether.vars['enemies'] = typeof enemies == 'undefined' ? undefined : enemies; _aether.vars['enemy'] = typeof enemy == 'undefined' ? undefined : enemy; _aether.vars['chooseAction'] = typeof chooseAction == 'undefined' ? undefined : chooseAction; _aether.logStatement([{ofs: 192, row: 9, col: 14}, {ofs: 206, row: 9, col: 28}], \"{x: 10, y: 30}\", this._aetherUserInfo);\n                _aether.logStatementStart([{ofs: 182, row: 9, col: 4}, {ofs: 207, row: 9, col: 29}]); tmp26 = tmp21[tmp22](tmp23); _aether.vars['enemies'] = typeof enemies == 'undefined' ? undefined : enemies; _aether.vars['enemy'] = typeof enemy == 'undefined' ? undefined : enemy; _aether.vars['chooseAction'] = typeof chooseAction == 'undefined' ? undefined : chooseAction; _aether.logStatement([{ofs: 182, row: 9, col: 4}, {ofs: 207, row: 9, col: 29}], \"this.move({x: 10, y: 30})\", this._aetherUserInfo);\n            }\n        }\n        _aether.logCallEnd(); return;\n    };\n    tmp0 = 'chooseAction';\n    __global[tmp0] = tmp1;\n}(this));"},"programmable-tharin":{"chooseAction":"/*this.getFriends();\nthis.attack(this.getEnemies()[0]);\nreturn;\n*/\n \n\n/* TODO:\n   If they fully base race us, we actually do want to produce archers since they DPS faster\n   The effective DPS on soldiers is better if they attack us\n   but worse if they straight race us\n\n   //not sure if this is good but...\n   if they're attacking our base with a small number of units\n   we should make archers and get them to defend\n*/\n/*\nreturn;\n// Tharin is a melee fighter with shield, warcry, and terrify skills.\n// this.shield() lets him take one-third damage while defending.\n// this.warcry() gives allies within 10m 30% haste for 5s, every 10s.\n// this.terrify() sends foes within 30m fleeing for 5s, once per match.\nvar friends = this.getFriends();\nvar enemies = this.getEnemies();\nif (enemies.length === 0) return;  // Chill if all enemies are dead.\nvar enemy = this.getNearest(enemies);\nvar furthestFriendX = 30;\nfor (var i = 0; i < friends.length; ++i) {\n    var friend = friends[i];\n    furthestFriendX = Math.max(friend.pos.x, furthestFriendX);\n}  \nif (!this.getCooldown('warcry') && friends.length > 5) {\n    this.warcry();\n}  \nelse if ((this.now() > 15 || this.health < 150) && !this.getCooldown('terrify')) {\n    this.terrify();\n}\nelse if (this.health < 75 && this.pos.x > furthestFriendX - 5) {\n    this.move({x: 10, y: 27});\n}\nelse if (this.pos.x > furthestFriendX - 1 && this.now() < 50) {\n    this.shield();\n}\nelse {\n    this.attack(enemy);\n}\nthis.say(\"Defend!\", {targetPos: {x: 30, y: Infinity}});\n\n// You can also command your troops with this.say():\n//this.say(\"Defend!\", {targetPos: {x: 30, y: 30}}));\n//this.say(\"Attack!\", {target: enemy});\n//this.say(\"Move!\", {targetPos: {x: 40, y: 40});\n\n// You can store state on this across frames:\n//this.lastHealth = this.health;\n*/"}},"teamSpells":{"ogres":["programmable-brawler/chooseAction","programmable-shaman/chooseAction","ogre-base/chooseAction"],"humans":["programmable-librarian/chooseAction","programmable-tharin/chooseAction","human-base/chooseAction"]},"submittedCodeLanguage":"javascript","playtime":9753,"codeLanguage":"javascript"}
+levelData = {"_id":"53c997066567c600002a43d0","name":"Dungeon Arena","icon":"db/level/53173f76c269d400000543c2/11_dungeon.png","banner":"db/level/53173f76c269d400000543c2/dungeon_arena.png","employerDescription":"Players:\n* Attempt to destroy the enemy base.\n* Choose and control heroes to attack with.\n* Choose which types of lesser units to build and have limited control over them.\n* Try to write strategies that counter other enemy strategies.\n* Play on a small map.","systems":[],"thangs":[],"scripts":[],"documentation":{"generalArticles":[],"specificArticles":[]},"description":"This level is indescribably flarmy!","version":{"minor":0,"major":0,"isLatestMajor":true,"isLatestMinor":true}};
+
+module.exports = ->
+  session = new LevelSession(levelSessionData)
+  v = new LevelSessionCodeView({session:session})
+  request = jasmine.Ajax.requests.mostRecent()
+  request.response({status: 200, responseText: JSON.stringify(levelData)})
+  console.log 'okay should be fine'
+  v
diff --git a/test/demo/views/user/JobProfileView.demo.coffee b/test/demo/views/user/JobProfileView.demo.coffee
new file mode 100644
index 000000000..17ac8767b
--- /dev/null
+++ b/test/demo/views/user/JobProfileView.demo.coffee
@@ -0,0 +1,576 @@
+ProfileView = require 'views/account/profile_view'
+
+responses =
+  '/db/user/joe/nameToID':'512ef4805a67a8c507000001'
+  
+  '/db/user/512ef4805a67a8c507000001': {
+    "_id": "512ef4805a67a8c507000001",
+    "__v": 47,
+    "email": "livelily@gmail.com",
+    "emailSubscriptions": [
+      "announcement",
+      "notification",
+      "developer",
+      "level_creator",
+      "tester",
+      "article_editor",
+      "translator",
+      "support"
+    ],
+    "facebookID": "4301215",
+    "firstName": "Nick",
+    "gender": "male",
+    "lastName": "Winter",
+    "name": "Nick!",
+    "photoURL": "db/user/512ef4805a67a8c507000001/nick_wizard.png",
+    "volume": 0,
+    "wizardColor1": 0.4,
+    "testGroupNumber": 217,
+    "mailChimp": {
+      "leid": "70264209",
+      "euid": "c4418e2abd",
+      "email": "livelily@gmail.com"
+    },
+    "hourOfCode": true,
+    "hourOfCodeComplete": true,
+    "signedCLA": "Fri Jan 03 2014 14:40:18 GMT-0800 (PST)",
+    "wizard": {
+      "colorConfig": {
+        "boots": {
+          "lightness": 0.1647058823529412,
+          "saturation": 0.023809523809523805,
+          "hue": 0
+        },
+        "spell": {
+          "hue": 0.7490196078431373,
+          "saturation": 0.4106280193236715,
+          "lightness": 0.5941176470588235
+        },
+        "cloud": {
+          "lightness": 0.14,
+          "saturation": 1,
+          "hue": 0
+        },
+        "clothes": {
+          "lightness": 0.1411764705882353,
+          "saturation": 0,
+          "hue": 0
+        },
+        "trim": {
+          "hue": 0.5,
+          "saturation": 0.009900990099009936,
+          "lightness": 0.19803921568627453
+        }
+      }
+    },
+    "aceConfig": {
+      "liveCompletion": true,
+      "indentGuides": true,
+      "invisibles": true,
+      "keyBindings": "emacs",
+      "behaviors": true,
+      "language": "javascript"
+    },
+    "lastLevel": "drink-me",
+    "gplusID": "110703832132860599877",
+    "jobProfile": {
+      "photoURL": "db/user/512ef4805a67a8c507000001/nick_bokeh_small.jpg",
+      "links": [
+#        {
+#          "name": "Twitter",
+#          "link": "https://twitter.com/nwinter"
+#        },
+#        {
+#          "name": "Facebook",
+#          "link": "https://www.facebook.com/nwinter"
+#        },
+        {
+          "name": "LinkedIn",
+          "link": "https://www.linkedin.com/in/nwinter"
+        },
+        {
+          "name": "Blog",
+          "link": "http://blog.nickwinter.net/"
+        },
+        {
+          "name": "Personal Site",
+          "link": "http://www.nickwinter.net/"
+        },
+        {
+          "name": "GitHub",
+          "link": "https://github.com/nwinter"
+        },
+        {
+          "name": "G+",
+          "link": "https://plus.google.com/u/0/+NickWinter"
+        }
+      ],
+      "projects": [
+        {
+          "name": "The Motivation Hacker",
+          "description": "I wrote a book. *The Motivation Hacker* shows you how to summon extreme amounts of motivation to accomplish anything you can think of. From precommitment to rejection therapy, this is your field guide to getting yourself to want to do everything you always wanted to want to do.",
+          "picture": "db/user/512ef4805a67a8c507000001/the_motivation_hacker_thumb.jpg",
+          "link": "http://www.nickwinter.net/motivation-hacker"
+        },
+        {
+          "name": "Quantified Mind",
+          "description": "Quantified Mind is a tool that quickly, reliably, and comprehensively measures your basic cognitive abilities. We've adapted tests used by psychologists to a practical web application that you can use whenever, wherever, and as often as you want.",
+          "picture": "db/user/512ef4805a67a8c507000001/screenshot.png",
+          "link": "http://www.quantified-mind.com/"
+        },
+        {
+          "link": "https://github.com/nwinter/telepath-logger",
+          "name": "Telepath",
+          "description": "A happy Mac keylogger for Quantified Self purposes. It also now serves as a time lapse heads-up-display thing. I used it to make a [time-lapse video of myself working an 120-hour workweek](http://blog.nickwinter.net/the-120-hour-workweek-epic-coding-time-lapse).",
+          "picture": "db/user/512ef4805a67a8c507000001/687474703a2f2f63646e2e736574742e636f6d2f696d616765732f757365722f32303133313131303139353534393937375a30356665633666623234623937323263373733636231303537613130626336365f66726f6e742e6a7067"
+        }
+      ],
+      "education": [
+        {
+          "school": "Oberlin College",
+          "degree": "BA Computer Science, Mathematics, and East Asian Studies, highest honors in CS",
+          "duration": "Aug 2004 - May 2008",
+          "description": "Cofounded Oberlin Street Art and did all sorts of crazy missions without telling anyone about it."
+        }
+      ],
+      "work": [
+        {
+          "employer": "CodeCombat",
+          "role": "Cofounder",
+          "duration": "Jan 2013 - present",
+          "description": "Programming a programming game for learning programming to be a programming programmer of programmatic programs."
+        },
+        {
+          "employer": "Skritter",
+          "role": "Cofounder",
+          "duration": "May 2008 - present",
+          "description": "I coded, I designed, I marketed, I businessed, I wrote, I drudged, I cheffed, I laughed, I cried. But mostly I emailed. God, so much email."
+        }
+      ],
+      "visa": "Authorized to work in the US",
+      "longDescription": "I cofounded Skritter, am working on CodeCombat, helped with Quantified Mind, live in San Francisco, went to Oberlin College, wrote a book about motivation hacking, and can do anything.\n\nI like hacking on startups, pigs with dogs for feet, and Smash Bros. I dislike shoes, mortality, and Java.\n\nDo you love hiring renegade maverick commandos who can't abide the system? Are you looking to hire the sample job profile candidate of the job profile system? Are you just testing this thing? If your answer is yes, yes yes!–then let us talk.",
+      "shortDescription": "Maniac two-time startup cofounder looking to test the system and see what a job profile might look like. Can't nobody hold him down.",
+      "experience": 6,
+      "skills": [
+        "python",
+        "coffeescript",
+        "node",
+        "ios",
+        "objective-c",
+        "javascript",
+        "app-engine",
+        "mongodb",
+        "web dev",
+        "django",
+        "backbone",
+        "chinese",
+        "qs",
+        "writing"
+      ],
+      "country": "USA",
+      "city": "San Francisco",
+      "active": false,
+      "lookingFor": "Full-time",
+      "name": "Nick Winter",
+      "updated": "2014-07-12T01:48:42.980Z",
+      "jobTitle": "Mutant Code Gorilla"
+    },
+    "jobProfileApproved": false,
+    "emails": {
+      "anyNotes": {
+        "enabled": true
+      },
+      "generalNews": {
+        "enabled": true
+      },
+      "archmageNews": {
+        "enabled": true
+      },
+      "artisanNews": {
+        "enabled": true
+      },
+      "adventurerNews": {
+        "enabled": true
+      },
+      "scribeNews": {
+        "enabled": true
+      },
+      "diplomatNews": {
+        "enabled": true
+      },
+      "ambassadorNews": {
+        "enabled": true
+      }
+    },
+    "activity": {
+      "viewed_by_employer": {
+        "last": "2014-06-19T20:21:43.747Z",
+        "count": 6,
+        "first": "2014-06-12T01:37:38.278Z"
+      },
+      "view_candidate": {
+        "first": "2014-06-10T19:59:30.773Z",
+        "count": 661,
+        "last": "2014-07-11T02:14:40.131Z"
+      },
+      "login": {
+        "first": "2014-06-10T21:55:08.968Z",
+        "count": 22,
+        "last": "2014-07-16T16:32:31.661Z"
+      },
+      "contacted_by_employer": {
+        "first": "2014-06-19T20:24:51.870Z",
+        "count": 1,
+        "last": "2014-06-19T20:24:51.870Z"
+      }
+    },
+    "slug": "nick",
+    "jobProfileNotes": "Nick used to be the **#1 Brawlwood player** on CodeCombat. He wrote most of the game engine, so that's totally cheating. Now other players have surpassed him by emulating his moves and improving his strategy. If you like the sixth Rocky movie, you might still want to hire this aging hero even in his fading senescence.",
+    "simulatedFor": 2363,
+    "simulatedBy": 103674,
+    "preferredLanguage": "en-US",
+    "anonymous": false,
+    "permissions": [
+      "admin"
+    ],
+    "autocastDelay": 90019001,
+    "music": false,
+    "dateCreated": "2013-02-28T06:09:04.743Z"
+  },
+
+  '/db/user/512ef4805a67a8c507000001/level.sessions/employer': [
+    {
+      "_id": "53179b49b483edfcdb7ef13e",
+      "level": {
+        "original": "53173f76c269d400000543c2",
+        "majorVersion": 0
+      },
+      "code": {
+      },
+      "submitted": false,
+      "teamSpells": {
+        "ogres": [
+          "programmable-brawler/chooseAction",
+          "programmable-shaman/chooseAction",
+          "ogre-base/chooseAction"
+        ],
+        "humans": [
+          "programmable-librarian/chooseAction",
+          "programmable-tharin/chooseAction",
+          "human-base/chooseAction"
+        ]
+      },
+      "levelID": "dungeon-arena",
+      "levelName": "Dungeon Arena",
+      "submittedCodeLanguage": "javascript",
+      "playtime": 33,
+      "codeLanguage": "javascript"
+    },
+    {
+      "_id": "53336ee91506ed33756f73e5",
+      "level": {
+        "original": "533353722a61b7ca6832840c",
+        "majorVersion": 0
+      },
+      "code": {
+      },
+      "teamSpells": {
+        "humans": [
+          "programmable-coin/chooseAction",
+          "tharin/chooseAction",
+          "wizard-purple/chooseAction"
+        ]
+      },
+      "levelID": "gold-rush",
+      "levelName": "Resource gathering multiplayer",
+      "submittedCodeLanguage": "javascript",
+      "playtime": 0,
+      "codeLanguage": "javascript"
+    },
+    {
+      "_id": "52ae32cbef42c52f1300000d",
+      "level": {
+        "original": "52ae2460ef42c52f13000008",
+        "majorVersion": 0
+      },
+      "levelID": "gridmancer",
+      "levelName": "Gridmancer",
+      "code": {
+      },
+      "teamSpells": {
+        "humans": [
+          "thoktar"
+        ]
+      },
+      "submitted": false,
+      "submittedCodeLanguage": "javascript",
+      "playtime": 302,
+      "codeLanguage": "javascript"
+    },
+    {
+      "_id": "5334901f0a0f9b286f57382c",
+      "level": {
+        "original": "533353722a61b7ca6832840c",
+        "majorVersion": 0
+      },
+      "team": "humans",
+      "code": {
+      },
+      "teamSpells": {
+        "common": [
+          "coin-generator-9000/chooseAction"
+        ],
+        "humans": [
+          "tharin/chooseAction"
+        ],
+        "ogres": [
+          "mak-fod/chooseAction"
+        ]
+      },
+      "levelID": "gold-rush",
+      "levelName": "Gold Rush",
+      "totalScore": 39.23691444835561,
+      "submitted": true,
+      "submittedCodeLanguage": "javascript",
+      "playtime": 1158,
+      "codeLanguage": "javascript"
+    },
+    {
+      "_id": "52dea9b77e486eeb97000001",
+      "level": {
+        "original": "52d97ecd32362bc86e004e87",
+        "majorVersion": 0
+      },
+      "levelID": "brawlwood",
+      "levelName": "Brawlwood",
+      "code": {
+      },
+      "totalScore": 24.138610165979667,
+      "teamSpells": {
+        "humans": [
+          "programmable-artillery/chooseAction",
+          "programmable-artillery/hear",
+          "programmable-soldier/chooseAction",
+          "programmable-soldier/hear",
+          "s-arrow-tower/chooseAction",
+          "programmable-archer/chooseAction",
+          "programmable-archer/hear",
+          "human-base/chooseAction",
+          "human-base/hear"
+        ],
+        "ogres": [
+          "programmable-shaman/chooseAction",
+          "programmable-shaman/hear",
+          "n-beam-tower/chooseAction",
+          "programmable-thrower/chooseAction",
+          "programmable-thrower/hear",
+          "programmable-munchkin/chooseAction",
+          "programmable-munchkin/hear",
+          "ogre-base/chooseAction",
+          "ogre-base/hear"
+        ]
+      },
+      "team": "humans",
+      "submitted": true,
+      "submittedCodeLanguage": "javascript",
+      "playtime": 0,
+      "codeLanguage": "javascript"
+    },
+    {
+      "_id": "535701331bfa9bba14b5e03d",
+      "level": {
+        "original": "53558b5a9914f5a90d7ccddb",
+        "majorVersion": 0
+      },
+      "team": "ogres",
+      "levelID": "greed",
+      "levelName": "Greed",
+      "code": {
+      },
+      "teamSpells": {
+        "humans": [
+          "human-base/chooseAction"
+        ],
+        "ogres": [
+          "ogre-base/chooseAction"
+        ],
+        "common": [
+          "well/chooseAction"
+        ]
+      },
+      "totalScore": 36.77589873873074,
+      "submitted": true,
+      "submittedCodeLanguage": "javascript",
+      "playtime": 12893,
+      "codeLanguage": "javascript"
+    },
+    {
+      "_id": "5356fc2e1bfa9bba14b5e039",
+      "level": {
+        "original": "53558b5a9914f5a90d7ccddb",
+        "majorVersion": 0
+      },
+      "team": "humans",
+      "levelID": "greed",
+      "levelName": "Greed",
+      "code": {
+      },
+      "teamSpells": {
+        "humans": [
+          "human-base/chooseAction"
+        ],
+        "ogres": [
+          "ogre-base/chooseAction"
+        ],
+        "common": [
+          "well/chooseAction"
+        ]
+      },
+      "totalScore": 31.538998178536794,
+      "submitted": true,
+      "submittedCodeLanguage": "javascript",
+      "playtime": 15648,
+      "codeLanguage": "javascript"
+    },
+    {
+      "_id": "52fd5bf7e3c53130231726e1",
+      "level": {
+        "original": "52d97ecd32362bc86e004e87",
+        "majorVersion": 0
+      },
+      "team": "ogres",
+      "levelID": "brawlwood",
+      "levelName": "Brawlwood",
+      "submitted": true,
+      "totalScore": 53.73511062513137,
+      "teamSpells": {
+        "humans": [
+          "programmable-artillery/chooseAction",
+          "programmable-artillery/hear",
+          "programmable-soldier/chooseAction",
+          "programmable-soldier/hear",
+          "s-arrow-tower/chooseAction",
+          "programmable-archer/chooseAction",
+          "programmable-archer/hear",
+          "human-base/chooseAction",
+          "human-base/hear"
+        ],
+        "ogres": [
+          "programmable-shaman/chooseAction",
+          "programmable-shaman/hear",
+          "n-beam-tower/chooseAction",
+          "programmable-thrower/chooseAction",
+          "programmable-thrower/hear",
+          "programmable-munchkin/chooseAction",
+          "programmable-munchkin/hear",
+          "ogre-base/chooseAction",
+          "ogre-base/hear"
+        ]
+      },
+      "code": {
+      },
+      "submittedCodeLanguage": "javascript",
+      "playtime": 178,
+      "codeLanguage": "javascript"
+    },
+    {
+      "_id": "5317ad4909098828ed071f4d",
+      "level": {
+        "original": "53173f76c269d400000543c2",
+        "majorVersion": 0
+      },
+      "team": "humans",
+      "levelID": "dungeon-arena",
+      "levelName": "Dungeon Arena",
+      "submitted": true,
+      "totalScore": 38.19039674380126,
+      "code": {
+      },
+      "teamSpells": {
+        "ogres": [
+          "programmable-brawler/chooseAction",
+          "programmable-shaman/chooseAction",
+          "ogre-base/chooseAction"
+        ],
+        "humans": [
+          "programmable-librarian/chooseAction",
+          "programmable-tharin/chooseAction",
+          "human-base/chooseAction"
+        ]
+      },
+      "submittedCodeLanguage": "javascript",
+      "playtime": 9753,
+      "codeLanguage": "javascript"
+    },
+    {
+      "_id": "53361c80948ad7a777a10d9c",
+      "level": {
+        "original": "533353722a61b7ca6832840c",
+        "majorVersion": 0
+      },
+      "team": "ogres",
+      "levelID": "gold-rush",
+      "levelName": "Gold Rush",
+      "code": {
+      },
+      "teamSpells": {
+        "common": [
+          "coin-generator-9000/chooseAction"
+        ],
+        "humans": [
+          "tharin/chooseAction"
+        ],
+        "ogres": [
+          "mak-fod/chooseAction"
+        ]
+      },
+      "totalScore": 40.73558595296533,
+      "submitted": true,
+      "submittedCodeLanguage": "javascript",
+      "playtime": 1014,
+      "codeLanguage": "javascript"
+    },
+    {
+      "_id": "531920069f44be00001a7aef",
+      "level": {
+        "original": "53173f76c269d400000543c2",
+        "majorVersion": 0
+      },
+      "team": "ogres",
+      "levelID": "dungeon-arena",
+      "levelName": "Dungeon Arena",
+      "submitted": true,
+      "totalScore": 26.50666470188054,
+      "code": {
+      },
+      "teamSpells": {
+        "ogres": [
+          "programmable-brawler/chooseAction",
+          "programmable-shaman/chooseAction",
+          "ogre-base/chooseAction"
+        ],
+        "humans": [
+          "programmable-librarian/chooseAction",
+          "programmable-tharin/chooseAction",
+          "human-base/chooseAction"
+        ]
+      },
+      "submittedCodeLanguage": "javascript",
+      "playtime": 1786,
+      "codeLanguage": "javascript"
+    }
+  ]
+
+module.exports = ->
+  me.isAdmin = -> false
+  me.set('permissions', ['employer'])
+  v = new ProfileView({}, 'joe')
+  for url, responseBody of responses
+    requests = jasmine.Ajax.requests.filter(url)
+    if not requests.length
+      console.error "could not find response for <#{url}>", responses
+      continue
+    request = requests[0]
+    request.response({status: 200, responseText: JSON.stringify(responseBody)})
+  #  v.$el = v.$el.find('.main-content-area')
+  v

From cd0d81438dc75dc829afdbdf9b9a028e358e7222 Mon Sep 17 00:00:00 2001
From: Michael Schmatz <michaelschmatz@gmail.com>
Date: Fri, 18 Jul 2014 16:26:53 -0700
Subject: [PATCH 51/58] Add recruitment task reminder emails

---
 server/routes/mail.coffee | 94 ++++++++++++++++++++++++++++++++++++++-
 1 file changed, 93 insertions(+), 1 deletion(-)

diff --git a/server/routes/mail.coffee b/server/routes/mail.coffee
index 0786a5f62..ed239f9be 100644
--- a/server/routes/mail.coffee
+++ b/server/routes/mail.coffee
@@ -32,6 +32,9 @@ setupScheduledEmails = ->
     ,
       taskFunction: unapprovedCandidateFinishProfileTask
       frequencyMs: 10 * 60 * 1000
+    ,
+      taskFunction: emailUserRemarkTaskRemindersTask
+      frequencyMs: 10 * 60 * 1000
   ]
 
   for mailTask in mailTasks
@@ -405,8 +408,97 @@ sendEmployerNewCandidatesAvailableEmail = (employer, cb) ->
 ### End Employer New Candidates Available Email ###
   
 ### Task Emails ###
-userRemarkTaskEmailTask = ->
+emailUserRemarkTaskRemindersTask = ->
+  mailTaskName = "emailUserRemarkTaskRemindersTask"
+  lockDurationMs = 2 * 60 * 1000
+  lockManager.setLock mailTaskName, lockDurationMs, (err) ->
+    if err? then return log.error "Error getting a distributed lock for task #{mailTaskName}: #{err}"
+    emailUserRemarkTaskReminders.call {"mailTaskName":mailTaskName}, (err) ->
+      if err
+        log.error "There was an error completing the #{mailTaskName}: #{err}"
+      else
+        log.info "Completed the #{mailTaskName}"
+      lockManager.releaseLock mailTaskName, (err) ->
+        if err? then return log.error "There was an error releasing the distributed lock for task #{mailTaskName}: #{err}"
+
+emailUserRemarkTaskReminders = (cb) ->
+  currentTime = new Date()
+  asyncContext =
+    "currentTime": currentTime
+    "mailTaskName": @mailTaskName
   
+  async.waterfall [
+    findAllIncompleteUserRemarkTasksDue.bind(asyncContext)
+    processRemarksIntoTasks.bind(asyncContext)
+    (allTasks, cb) ->
+      async.reject allTasks, taskReminderAlreadySentThisWeekFilter.bind(asyncContext), cb.bind(null,null)
+    (tasksToRemind, cb) ->
+      async.each tasksToRemind, sendUserRemarkTaskEmail.bind(asyncContext), cb
+  ], cb
+  
+findAllIncompleteUserRemarkTasksDue = (cb) ->
+  findParameters = 
+    tasks:
+      $exists: true
+      $elemMatch:
+        date:
+          $lte: @currentTime.toISOString()
+        status:
+          $ne: 'Completed'
+  selection = "contact user tasks"
+  UserRemark.find(findParameters).select(selection).lean().exec cb
+  
+processRemarksIntoTasks = (remarks, cb) ->
+  tasks = []
+  for remark in remarks
+      for task in remark.tasks
+        taskObject = 
+          date: task.date
+          action: task.action
+          contact: remark.contact
+          user: remark.user
+          remarkID: remark._id
+        tasks.push taskObject
+  cb null, tasks
+
+taskReminderAlreadySentThisWeekFilter = (task, cb) ->
+  findParameters =
+    "user": task.contact
+    "mailTask": @mailTaskName
+    "sent":
+      $gt: new Date(@currentTime.getTime() - 7 * 24 * 60 * 60 * 1000)
+    "metadata":
+      remarkID: task.remarkID
+      taskAction: task.action
+      date: task.date
+  MailSent.count findParameters, (err, count) ->
+    if err? then return cb true
+    return cb Boolean(count)
+  
+sendUserRemarkTaskEmail = (task, cb) ->
+  mailTaskName = @mailTaskName
+  User.findOne("_id":task.contact).select("email").lean().exec (err, contact) ->
+    if err? then return cb err
+    context =
+      email_id: "tem_aryDjyw6JmEmbKtCMTSwAM"
+      recipient:
+        address: contact.email
+      email_data:
+        candidate_link: "http://codecombat.com/account/profile/#{task.user}"
+        due_date: task.date
+    log.info "Sending recruitment task reminder to #{contact.email}"
+    newSentMail =
+      mailTask: mailTaskName
+      user: task.contact
+      "metadata":
+        remarkID: task.remarkID
+        taskAction: task.action
+        date: task.date
+    MailSent.create newSentMail, (err) ->
+      if err? then return cb err
+      sendwithus.api.send context, (err, result) ->
+        log.error "Error sending #{mailTaskName} to #{contact.email}: #{err} with result #{result}" if err
+        cb null
 
 ### New Recruit Leaderboard Email ###
 ###

From 00c11fd70e1915f070de72d52978258d997fc427 Mon Sep 17 00:00:00 2001
From: Scott Erickson <sderickson@gmail.com>
Date: Fri, 18 Jul 2014 16:45:35 -0700
Subject: [PATCH 52/58] Minor defensive bug handling for the
 LevelSessionCodeView for when teamSpells has invalid, old data.

---
 app/views/common/LevelSessionCodeView.coffee | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/app/views/common/LevelSessionCodeView.coffee b/app/views/common/LevelSessionCodeView.coffee
index 768793115..277eb2e3e 100644
--- a/app/views/common/LevelSessionCodeView.coffee
+++ b/app/views/common/LevelSessionCodeView.coffee
@@ -39,7 +39,7 @@ module.exports = class LevelSessionCodeView extends CocoView
     teamSpells = @session.get('teamSpells')[team] or []
     filteredSpells = []
     for spell in teamSpells
-      code = @session.getSourceFor(spell)
+      code = @session.getSourceFor(spell) ? ''
       lines = code.split('\n').length
       height = lines * 16 + 20
       filteredSpells.push {

From 574e9e7804f4039c6ef07187fc4cda61b5e0bcc4 Mon Sep 17 00:00:00 2001
From: Scott Erickson <sderickson@gmail.com>
Date: Fri, 18 Jul 2014 16:56:08 -0700
Subject: [PATCH 53/58] Removed the deprecated ErrorView.

---
 app/views/editor/level/edit.coffee | 1 -
 app/views/editor/thang/edit.coffee | 1 -
 app/views/error_view.coffee        | 6 ------
 3 files changed, 8 deletions(-)
 delete mode 100644 app/views/error_view.coffee

diff --git a/app/views/editor/level/edit.coffee b/app/views/editor/level/edit.coffee
index d597f0bfd..6683d6a54 100644
--- a/app/views/editor/level/edit.coffee
+++ b/app/views/editor/level/edit.coffee
@@ -16,7 +16,6 @@ LevelForkView = require './fork_view'
 SaveVersionModal = require 'views/modal/save_version_modal'
 PatchesView = require 'views/editor/patches_view'
 VersionHistoryView = require './versions_view'
-ErrorView = require '../../error_view'
 
 module.exports = class EditorLevelView extends RootView
   id: 'editor-level-view'
diff --git a/app/views/editor/thang/edit.coffee b/app/views/editor/thang/edit.coffee
index b5ea43653..b7d04b751 100644
--- a/app/views/editor/thang/edit.coffee
+++ b/app/views/editor/thang/edit.coffee
@@ -11,7 +11,6 @@ VersionHistoryView = require './versions_view'
 ColorsTabView = require './colors_tab_view'
 PatchesView = require 'views/editor/patches_view'
 SaveVersionModal = require 'views/modal/save_version_modal'
-ErrorView = require '../../error_view'
 template = require 'templates/editor/thang/edit'
 
 CENTER = {x: 200, y: 300}
diff --git a/app/views/error_view.coffee b/app/views/error_view.coffee
deleted file mode 100644
index f7b0ba04b..000000000
--- a/app/views/error_view.coffee
+++ /dev/null
@@ -1,6 +0,0 @@
-RootView = require 'views/kinds/RootView'
-template = require 'templates/error'
-
-module.exports = class ErrorView extends RootView
-  id: 'error-view'
-  template: template

From 97964f785347517d533d751f24e759a7da7af57c Mon Sep 17 00:00:00 2001
From: Scott Erickson <sderickson@gmail.com>
Date: Fri, 18 Jul 2014 17:06:20 -0700
Subject: [PATCH 54/58] More work on renaming. Cleaned out
 sprite_parser_test_view, and fixed the TeachersView.

---
 app/lib/Router.coffee                         | 35 +++++++++++++------
 app/templates/teachers.jade                   |  2 +-
 ...oyers_view.coffee => EmployersView.coffee} |  0
 .../{home_view.coffee => HomeView.coffee}     |  0
 .../{legal_view.coffee => LegalView.coffee}   |  0
 ...yer_view.coffee => MultiplayerView.coffee} |  2 +-
 .../{not_found.coffee => NotFoundView.coffee} |  0
 ...achers_view.coffee => TeachersView.coffee} |  0
 .../MainEditorView.coffee}                    |  2 +-
 .../MainPlayView.coffee}                      |  2 +-
 app/views/sprite_parser_test_view.coffee      | 22 ------------
 11 files changed, 28 insertions(+), 37 deletions(-)
 rename app/views/{employers_view.coffee => EmployersView.coffee} (100%)
 rename app/views/{home_view.coffee => HomeView.coffee} (100%)
 rename app/views/{legal_view.coffee => LegalView.coffee} (100%)
 rename app/views/{multiplayer_view.coffee => MultiplayerView.coffee} (93%)
 rename app/views/{not_found.coffee => NotFoundView.coffee} (100%)
 rename app/views/{teachers_view.coffee => TeachersView.coffee} (100%)
 rename app/views/{editor_view.coffee => editor/MainEditorView.coffee} (69%)
 rename app/views/{play_view.coffee => play/MainPlayView.coffee} (99%)
 delete mode 100644 app/views/sprite_parser_test_view.coffee

diff --git a/app/lib/Router.coffee b/app/lib/Router.coffee
index 17dab5309..2c3a026a3 100644
--- a/app/lib/Router.coffee
+++ b/app/lib/Router.coffee
@@ -1,4 +1,7 @@
 gplusClientID = '800329290710-j9sivplv2gpcdgkrsis9rff3o417mlfa.apps.googleusercontent.com'
+# TODO: Move to GPlusHandler
+
+NotFoundView = require('views/NotFoundView')
 
 go = (path) -> -> @routeDirectly path, arguments
 
@@ -8,11 +11,15 @@ module.exports = class CocoRouter extends Backbone.Router
     Backbone.Mediator.subscribe 'router:navigate', @onNavigate, @
 
   routes:
+    '': go('HomeView')
+
     'about': go('AboutView')
     'admin': go('AdminView')
+
+    'beta': go('HomeView')
+
     'cla': go('CLAView')
     'community': go('CommunityView')
-    
     'contribute': go('contribute/MainContributeView')
     'contribute/adventurer': go('contribute/AdventurerView')
     'contribute/ambassador': go('contribute/AmbassadorView')
@@ -20,21 +27,28 @@ module.exports = class CocoRouter extends Backbone.Router
     'contribute/artisan': go('contribute/ArtisanView')
     'contribute/diplomat': go('contribute/DiplomatView')
     'contribute/scribe': go('contribute/ScribeView')
-  
-    # every abnormal view gets listed here
-    '': 'home'
-    'preview': 'home'
-    'beta': 'home'
+
+    'demo(/*subpath)': go('DemoView')
+    
+    'editor': go('editor/MainEditorView')
+    'employers': go('EmployersView')
+    
+    'legal': go('LegalView')
+    
+    'multiplayer': go('MultiplayerView')
+
+    'play': go('play/MainPlayView')
+    'preview': go('HomeView')
+
+    'teachers': go('TeachersView')
+    'test(/*subpath)': go('TestView')
+
 
     # editor views tend to have the same general structure
     'editor/:model(/:slug_or_id)(/:subview)': 'editorModelView'
 
     # Direct links
-    'test': go('TestView')
-    'test/*subpath': go('TestView')
 
-    'demo': go('DemoView')
-    'demo/*subpath': go('DemoView')
 
     'play/ladder/:levelID': go('play/ladder/ladder_view')
     'play/ladder': go('play/ladder_home')
@@ -147,7 +161,6 @@ module.exports = class CocoRouter extends Backbone.Router
         throw error
 
   notFoundView: ->
-    NotFoundView = require('views/not_found')
     view = new NotFoundView()
     view.render()
 
diff --git a/app/templates/teachers.jade b/app/templates/teachers.jade
index 3653491d8..651de1205 100644
--- a/app/templates/teachers.jade
+++ b/app/templates/teachers.jade
@@ -2,7 +2,7 @@ extends /templates/base
 
 block content
 
-  .row
+  p.row
 
     .span5
 
diff --git a/app/views/employers_view.coffee b/app/views/EmployersView.coffee
similarity index 100%
rename from app/views/employers_view.coffee
rename to app/views/EmployersView.coffee
diff --git a/app/views/home_view.coffee b/app/views/HomeView.coffee
similarity index 100%
rename from app/views/home_view.coffee
rename to app/views/HomeView.coffee
diff --git a/app/views/legal_view.coffee b/app/views/LegalView.coffee
similarity index 100%
rename from app/views/legal_view.coffee
rename to app/views/LegalView.coffee
diff --git a/app/views/multiplayer_view.coffee b/app/views/MultiplayerView.coffee
similarity index 93%
rename from app/views/multiplayer_view.coffee
rename to app/views/MultiplayerView.coffee
index acfaefe15..9b5737d10 100644
--- a/app/views/multiplayer_view.coffee
+++ b/app/views/MultiplayerView.coffee
@@ -1,4 +1,4 @@
-HomeView = require './home_view'
+HomeView = require './HomeView'
 ModalView = require 'views/kinds/ModalView'
 modalTemplate = require 'templates/multiplayer_launch_modal'
 
diff --git a/app/views/not_found.coffee b/app/views/NotFoundView.coffee
similarity index 100%
rename from app/views/not_found.coffee
rename to app/views/NotFoundView.coffee
diff --git a/app/views/teachers_view.coffee b/app/views/TeachersView.coffee
similarity index 100%
rename from app/views/teachers_view.coffee
rename to app/views/TeachersView.coffee
diff --git a/app/views/editor_view.coffee b/app/views/editor/MainEditorView.coffee
similarity index 69%
rename from app/views/editor_view.coffee
rename to app/views/editor/MainEditorView.coffee
index 7536d5ebc..e5a841279 100644
--- a/app/views/editor_view.coffee
+++ b/app/views/editor/MainEditorView.coffee
@@ -1,6 +1,6 @@
 RootView = require 'views/kinds/RootView'
 template = require 'templates/editor'
 
-module.exports = class EditorView extends RootView
+module.exports = class MainEditorView extends RootView
   id: 'editor-nav-view'
   template: template
diff --git a/app/views/play_view.coffee b/app/views/play/MainPlayView.coffee
similarity index 99%
rename from app/views/play_view.coffee
rename to app/views/play/MainPlayView.coffee
index 202bd32a3..685887eab 100644
--- a/app/views/play_view.coffee
+++ b/app/views/play/MainPlayView.coffee
@@ -11,7 +11,7 @@ class LevelSessionsCollection extends CocoCollection
     super()
     @url = "/db/user/#{me.id}/level.sessions?project=state.complete,levelID"
 
-module.exports = class PlayView extends RootView
+module.exports = class MainPlayView extends RootView
   id: 'play-view'
   template: template
 
diff --git a/app/views/sprite_parser_test_view.coffee b/app/views/sprite_parser_test_view.coffee
deleted file mode 100644
index 80369fc45..000000000
--- a/app/views/sprite_parser_test_view.coffee
+++ /dev/null
@@ -1,22 +0,0 @@
-RootView = require 'views/kinds/RootView'
-template = require 'templates/editor/thang/sprite_parser_test'
-SpriteParser = require 'lib/sprites/SpriteParser'
-mixed_samples = require 'lib/sprites/parser_samples'
-samples = require 'lib/sprites/parser_samples_artillery'
-ThangType = require 'models/ThangType'
-
-module.exports = class SpriteParserTestView extends RootView
-  id: 'sprite-parser-test-view'
-  template: template
-
-  afterRender: ->
-    @parse samples
-
-  parse: (samples) ->
-    thangType = new ThangType()
-    for sample in _.shuffle samples
-      parser = new SpriteParser(thangType)
-      parser.parse(sample)
-    console.log 'thang type is now', thangType
-    console.log JSON.stringify(thangType).length
-#    console.log JSON.stringify(thangType.attributes.raw.animations.tharin_defend.tweens)

From 1d5078ad10cbda15276ab1ecb2a21f0f7bde97bc Mon Sep 17 00:00:00 2001
From: Michael Schmatz <michaelschmatz@gmail.com>
Date: Fri, 18 Jul 2014 19:22:00 -0700
Subject: [PATCH 55/58] Changed https to http in curation email

---
 server/routes/mail.coffee | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/server/routes/mail.coffee b/server/routes/mail.coffee
index ed239f9be..b75acfce7 100644
--- a/server/routes/mail.coffee
+++ b/server/routes/mail.coffee
@@ -292,7 +292,7 @@ sendInternalCandidateUpdateReminder = (candidate, cb) ->
       address: "team@codecombat.com"
       name: "The CodeCombat Team"
     email_data:
-      new_candidate_profile: "https://codecombat.com/account/profile/#{candidate._id}"
+      new_candidate_profile: "http://codecombat.com/account/profile/#{candidate._id}"
   log.info "Sending candidate updated reminder for #{candidate.jobProfile.name}"
   newSentMail =
     mailTask: @mailTaskName

From d45c2d31de6f8feddf823b9809cc2a165b855226 Mon Sep 17 00:00:00 2001
From: Nick Winter <livelily@gmail.com>
Date: Fri, 18 Jul 2014 20:14:41 -0700
Subject: [PATCH 56/58] New language icons.

---
 .../images/common/code_languages/c_small.png  | Bin 0 -> 3538 bytes
 .../common/code_languages/clojure_small.png   | Bin 6228 -> 5202 bytes
 .../code_languages/coffeescript_small.png     | Bin 16254 -> 4544 bytes
 .../common/code_languages/cpp_small.png       | Bin 0 -> 4040 bytes
 .../common/code_languages/csharp_small.png    | Bin 0 -> 3686 bytes
 .../images/common/code_languages/go_small.png | Bin 0 -> 4015 bytes
 .../images/common/code_languages/io_small.png | Bin 15390 -> 2824 bytes
 .../common/code_languages/java_small.png      | Bin 0 -> 3914 bytes
 .../code_languages/javascript_small.png       | Bin 3828 -> 2349 bytes
 .../common/code_languages/lua_small.png       | Bin 1510 -> 3614 bytes
 .../common/code_languages/php_small.png       | Bin 0 -> 3353 bytes
 .../common/code_languages/python_small.png    | Bin 17483 -> 4192 bytes
 .../common/code_languages/ruby_small.png      | Bin 0 -> 2797 bytes
 .../common/code_languages/swift_small.png     | Bin 0 -> 2631 bytes
 app/views/HomeView.coffee                     |   2 +-
 15 files changed, 1 insertion(+), 1 deletion(-)
 create mode 100644 app/assets/images/common/code_languages/c_small.png
 create mode 100644 app/assets/images/common/code_languages/cpp_small.png
 create mode 100644 app/assets/images/common/code_languages/csharp_small.png
 create mode 100644 app/assets/images/common/code_languages/go_small.png
 create mode 100644 app/assets/images/common/code_languages/java_small.png
 create mode 100644 app/assets/images/common/code_languages/php_small.png
 create mode 100644 app/assets/images/common/code_languages/ruby_small.png
 create mode 100644 app/assets/images/common/code_languages/swift_small.png

diff --git a/app/assets/images/common/code_languages/c_small.png b/app/assets/images/common/code_languages/c_small.png
new file mode 100644
index 0000000000000000000000000000000000000000..23ba119bb4e99407c8412fbbca964105eec966df
GIT binary patch
literal 3538
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
M07*qoM6N<$f|2E`X#fBK

literal 0
HcmV?d00001

diff --git a/app/assets/images/common/code_languages/clojure_small.png b/app/assets/images/common/code_languages/clojure_small.png
index 38f4ae07ac830431c6b5c30c2a193fd13382541f..606af043342c1fc41c347a6835ea2ce36fba51ad 100644
GIT binary patch
literal 5202
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
M07*qoM6N<$f-f%aX8-^I

literal 6228
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

diff --git a/app/assets/images/common/code_languages/coffeescript_small.png b/app/assets/images/common/code_languages/coffeescript_small.png
index 8eb9742ea08e235aed90b0c7f9d0e422f6ff380e..86e49ea1cb25960e800848afb3eba36c38015a91 100644
GIT binary patch
literal 4544
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

literal 16254
zcmeI3c~leE9><5;hYF}iEY*tE7(j7JCX<l0BovY$RO14uSg<-t21rRVF%uwSTlW@J
zMCc+^6vY*N#ZuRb#is`JskKLI5toWoaC;QUd$^+bCSkj>IQE?WIde{!ANPKL-+S-p
zE;Ij3`t+%j2DlA(gCJ-?c$gxBymQIl*nY0$UzM+SE_v&33Y$YfkoyqF&jtE6Zx{qg
z`st#gEzzne5)E!(qgq^zv8@IZsfM7yAgc-0Bw`kZ8jIH%rObwsV@!rlD`n2+t2io?
z981uJrJAwG)TvRL)I^O~%M6ma1zIJffdR9i468wJBqUZT)9EWAV@EN}WH=?3L@6`a
z(I6vQHJu^H%@~8v=Cd>$F2WFs*$6*Cj35&kTn@s65f021vk*iQAe0~iM%%@dxsg$z
zSsN#bP=vNMNB$>eCRi*c2@I#Cq_9(XY}_0VBVw@_=5S#ymqjXA#6qJ5wX%$aPpe70
zj{+k!W}V5R!;K7wFRI3qEK(-Z(NM?LHZFrHLKmN4Av&5f5^V%Ymar8y!3diJo1GfC
z7YCK<)!7C^kC}ue0_z-RkL?ms3r!dtff0C;S%Z;spPsrvSd_`+_}X~AhLJKEGg^AI
zB4_>8Mm@E!)pX>TlFWMNRB1IZrpF9qI|NA(=@Eb_0k_~p0^UoL9o5b$=&50gF0L1V
zj+$Q6FsrVYG)GNqnsZgQE|x$NO6ww#s8Dkvrj>=FdIAfCyOnn?Fh`C`C7DJp9Gwx>
zD{xJcgGIPPmXxH^N)WC>B<FI43OOf4$w811WiUsiL_*}D;$VcY6gj<n&hOR+;7vBl
z){^#IK`7}YR0@RwA_P%#L-=xj2uB$r-~=N9h?3uK52SXp4L1@N)TqJ8E<0>>q^(%1
z)$)XxhNTe-1groK%43PN8k8l(#3C-LjS~rY!ggyQy_>ZHGwYHuZKxSHIQORsH4~U)
zrAwLZOTA-5w@ra_uSj&=`^4djNPfZqj*!a{kb@O-LpUJ<IVV`C5b!wx%0ReVYG;2)
z^T5_>?O&dtZh4)y?F@i%c3Dp3)Q0H@3vONrR5*I$IIbeG1uvJjSLk)GiK_z|c`is$
zjpHDc5h#h=K?5l3>~d>{qoGzo52Rmj_PeF`-bP9SW|Wanh5!~vz(Rykh)BW_k!zR5
z5lT3m_O3cry_*ntoFxS{W5My{_L8+eil(=pD-5}u;jcn9I-}#98P{(4a!&8wngrAs
zPi}X(J+Zx@Yf2#Om^Z!d<!NgzeR($9mqz#5cbpg!xfw&rRS|{bddjhM)pvHP(+X3d
z7OX2{lCG$oafeB(vWtfb*XrUH_T&N1lfwg0cJ(0N7PP1ZeJvMI3;1X?k~rLKKrJ$z
z0gcCClQBLJ?koh99nTDj9M|J!vRjyp7YO%M3}iW;7LK!;TtcXGvmk+Rx3aGKXvbNl
zPjc$X!-u@cHyrY6O9iXDrp|eFDp=h$wKH?3QD>2H+gj^V3}iVTX{|6K$rnLPCgAgV
z<O85<ao3FLIxD7+R_Ms57U4KP_~f{pIbADyOq|o1$P<H!Kt)?(>n;Ia*_@lGwUm4z
zB;Q5hj+fDw_gBZ6^*0BdBl??-K|8t;kOpN;<Dx_a3TRv)4a%6tMTrO$(6~SvlrfEq
z5)mk%ae*`_V;UDFB2Yl%0%=gjG%iX+pn%2&(x8lKT$G4F0gVf!K^fDyC=r1I8W%`|
zGNy4+A_4_8E|3OgOyi<N1PW+eAPvfx#zlz;6wtUp8k8}OixLqipmBjTC}SEIB_dEj
z;{s_=#xyQUM4*7i1=665X<U?uKmm;lq(K?exF`{U0vZ=cgEFRZQ6d5bG%k<^WlZCu
zL<9<GTp$g~n8rnk2o%t`KpK=Wjf)ZyD4=nHG$`X&;&SW!yc08$-*l#sA8#)B?C5^-
z!%v1LEJ6iAseTZ&WH|&qc|qRqK~NG0g6_{JzZuPeprLs7ys}UTdb2TH5gcW`dg+QT
zZEo#I*T$-izPBoD+u6An4k8%|u>~_@-a4@Vz^*M7<tqzzjT&DNHRHmO%@5_<S1|qi
zjXxNz4leU68a4d8^11!h_h<R}A^dtxfCOPL*kC^yc<AV+y!Uu1*;B?08gX9QV6JaI
z+ORk%qp0Z9@BWcoUNkIoz5V0W3xbaCEfyx9(CX6%ezF34EHsu!`pgN_tWXR*p7GeF
z)FaEa$o8b{un*$RyJ~$jQZ#tp{(YP6tgAcKezPt$jm#)%)P8nsRsYBD$j;>$udm3T
zef#13fi26Y+1aJ#4|CFa3r0xn8%9^i*hFHwepyg_3Y=hH_U|8mIYlU&ucw`@6$xv;
zwZ5|+J7=4C^Vc(r?w~~8vaLV#&-4hXxv8&Y&1C)_y`*8%j+ko6l#}_U)Y}2yd+(TC
zUb=R*DRI-ZlT|;s?7KLqs%)?Mc(WBt8!~6rq~byBk3H|%f<oR{dy2RGXw9HG=W0be
zE?)LF3qOB<@r6SR>w``t-ktp7u=<?(+1t2Ba825ESb-PTUA}cmee;u8?wg}4T_Vj#
zMrpz`D!;1iJNC|{LvFcV(P@3{)316I99v(#t>DkR-M>9ev~9P!&#3QfXUdQxl^%=!
z*om<FdVRXbNBXEDw`#d*+`!C@aPj!}4*9wr4fy8nPidESuks%-bb~s^QoCYt+V92g
z4>JajvyV3ZYhJ;$7ms{Kia2rhtsXa!GbzIco+c(VVK<sbKL{`SB~h>ycCYe?(N<sk
z<2|prh3Xl$`j)ikcXav7!fVrG2XlGu-0itHCS3NYTiQ@I8UJx$*{+}s#S>fZmE}F#
zw{qp4`)7a8iSfK5{qm_MqvhQTx_7+hdmc>xqTzhKaVQ}Xe{^is?fyS``86ExTdc-y
zg9mN@qNI9a-clj5$M<5|pPN3cJAY!tEuX<9o2oyT$<z9O@>^)rg^cH(!=E#em?4De
z>EkoSZ2z=?##^yNZ|(DcvY2REO*Ev7n%*{Ft11ss&OUfPJo!}h)XCE&(y_8FW!HDw
zXYv&bnJzICc%rRipt=b*6x&j_N4{eQuaxH&G_F8|oRJl(Hr`*IGS8<XRb-ZK$ylGH
z6&_mq-^?+aGPM6hhp)exFL?Ldo)6b~<{K1>`rYogyzk{4$XaKeSpDnpv0S0=tea0V
zmYmL$+_Aj7_UDEx%8xj+?8A+FJ+F)l&$d>2HzsF!WGG`t{jY_^9D8c5kXU!)S*dwV
zw$=Uer6)_|6MmdD#Qi^G*0{uuI91}BC0%{z{0A>qT6G>-hyBJ`zMFkxoAt(l@|}5t
z(6A<({{av9gAwb7?XoR9F-#x!%=rD?lC9aql)}PQVLt@neX<Xa&#m6<QuXQA2ZJi^
zu6oN)RtfoT3OkOUKK<bSSL_WrYZrZ7UYeVIJ3;-xl(fIkS$p#b&F6e4&i(pf%z|tF
zp1B(p#;`RTM8%U`VfKly;=F3>w1x>^mhp+Y$k3&>-8D5oos?!>44rniNVwW{h-s?%
zAy2bAf6czws+_$K9({AwR%(mLTNhdBbMMZg$NBhTwH0d4d?O3hY#WujW9-k@Ez&Hj
zRGC@(XU#RA;{`SBc}0Ca&w4~%U4MvIsA07<&U1CcQug}1@%(Vb`+Q<X$(P=VPmulT
zg|6dkc>~_MAo)VPcW9>fuBNK=l+Ytfl9b!h4ULogcs*zL$*+8xxNUO~v&mX?pe4%w
aGt`hUIw1A^s(y|y<inLy6-6QQm;E1aLau!P

diff --git a/app/assets/images/common/code_languages/cpp_small.png b/app/assets/images/common/code_languages/cpp_small.png
new file mode 100644
index 0000000000000000000000000000000000000000..df701f002614696f4149caab96d59b95b9559770
GIT binary patch
literal 4040
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

literal 0
HcmV?d00001

diff --git a/app/assets/images/common/code_languages/csharp_small.png b/app/assets/images/common/code_languages/csharp_small.png
new file mode 100644
index 0000000000000000000000000000000000000000..86c26aea365c9912adde5cefc5432820c64bdd9a
GIT binary patch
literal 3686
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
Ef{4rIpa1{>

literal 0
HcmV?d00001

diff --git a/app/assets/images/common/code_languages/go_small.png b/app/assets/images/common/code_languages/go_small.png
new file mode 100644
index 0000000000000000000000000000000000000000..7ff974e0733c20cabd6f7228bad89f46515066b7
GIT binary patch
literal 4015
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
VyAkKPI_v-d002ovPDHLkV1j1Kq+|d9

literal 0
HcmV?d00001

diff --git a/app/assets/images/common/code_languages/io_small.png b/app/assets/images/common/code_languages/io_small.png
index c9d3360df53ae92b34639116094d6160c34e9c12..2bbd5c51e5faca7ebd7d1b91de23fb7dd92b1c45 100644
GIT binary patch
delta 2816
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
S<;R`?0000<MNUMnLSTZH7HjVS

literal 15390
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
DznCwh

diff --git a/app/assets/images/common/code_languages/java_small.png b/app/assets/images/common/code_languages/java_small.png
new file mode 100644
index 0000000000000000000000000000000000000000..76126650c3be1938cc579cf10b6c757a20ca0511
GIT binary patch
literal 3914
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
Y05Xd%@(P(SDF6Tf07*qoM6N<$f`qJr3;+NC

literal 0
HcmV?d00001

diff --git a/app/assets/images/common/code_languages/javascript_small.png b/app/assets/images/common/code_languages/javascript_small.png
index ec8b134ae20775085642757fb04bcee548e1e15a..4472bea9de52ca311e926d3117145950c193b9e5 100644
GIT binary patch
delta 2336
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
GLSTXly>V;+

literal 3828
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

diff --git a/app/assets/images/common/code_languages/lua_small.png b/app/assets/images/common/code_languages/lua_small.png
index 724fa0cfc30ce8bbad793a608edab7f234e6d28e..c1f183c58c4ff7de164a9e69af07a8ad8adc6269 100644
GIT binary patch
delta 3576
zcmV<U4F~e(3!WU1NPi8$Nkl<Zc-rh*32;>P8UK>qWV1(-&9S)%NnpciLc);{ia_X8
zM5!ZED^{_<)T4|Cpy*6TN3gatRck$}BU-gG;5Bvxth5};C6b^iB!Pq+Yz`pzwVPy*
zBzyGxzPImX-yR`owd0K6%zxhdzkToj{@?feeaHX*7T`zu0e?uY(V(aHLz;7#p8~~r
z*obW<wmsOWe-ztZ>Yp`rng3sg_0Fjr+gfZD{__d*xtVU<y=cKSSWq|}o_%RA7&G;d
zbIlYueEb{?4BF|Tm+;|j-=hM)hGo%dReT(@4$*uz<9y!nf2i@{^#z{#6OVg59XmYO
z_q_eg%^p|V+kf2O`SRU-?R!*W6TR<=2XFLz{?VhJe$#f(t;_Q~Z$5Xs$I<+%=jlgo
z;`w09qWhIT&t?$<qD1S|Fl|a2I7fycQl)`4s~0g!S9p28ul2sAETMNkw((|gyItV%
zxZ&+rH-I`S9PIW1*tFpWIC8uax_WKv@ZN2{ia=D95`W?o68L=j)HE<4HHSy+tVr1z
zlP}!<Lfj=KcBAt8m}vF4)}p1Y4+aJteC~ET!Q~u5<Lbca9Ae|@<Ko%as0c`icr6KO
z$vVD?BrY}z6^lem2yCjUYZc#dB*=S-ulk#BEP$t<SpAJAP8N5$Mx_4he?JUIPn`Gp
zUCwIf$bT?oWhFzy#hzGSYRN(^4H&170;O^^s1YIs`4i#AXYPaur3%8r!a$*n0IPKb
z-uuT%Jz0mSK+oE27THV5nl#a?k(pEDQ5ng2FoH-#LA0ztZAv-@qUwB^kEo-BQ=%5V
zR78X(&4|>u!jhs47#VhO^ObdX6yd!(7#gyHb$_t;f8ron>3Ye4`MK%fal8Ex8ItwG
zy~li_l`m|CbB$6TLoc+p^@1T@%@F%Ho7DonJuNUe&=d6c@wW2nPH6A4@_9_G2H&TF
zuTPsKmaxCLTv9(ZWt2!ksYQ~Jo=D8(^V<4WZvaRUFO4Z5AE?JTKLW`H4IDh)3>((u
z!GCMJDqz*}Y%n!jI6p0%n<m|V;EN`BZD$1x+JwpG%`m`In-@SLD$<Hhuk^Blm_iXu
zlw<=Nzt}(gf=U%BAmSRv=r9Zs5fKm`u3$$e>yQ$jF*Moo$K$YUQ6|iqo(Rc_T1;LM
z+$Z_-<BRz?IYSRt+c2CcYk`xeTlx3rUVkr>jZ<;H3%0&c0yEHXm)d(}zAK{_&e0zc
zNJVOiir8&-<hvczYE(p_U}~u%6`<Cr0-^`Wwiiob)%Dr1<(|2WLa0c?R!pSOtVV@m
z!H8|=?(;#7LdwMDYb9#&cy5nh5D8RdiRkRaL7UBrNQ6r_5w#|yM1w{hDVtnJw|@;f
zx@>UWwHc5*Jwcj0T|fDsHmI!WmgpiVp@BR^Yr))9&}kwd36&zB2qh|2gyf^a5XsA#
zAk|_@|A$2m#>D7k&K~ad7+)iA-&F}~ZkdisB=Yr!ix$}aZY3)aN)CO|47ztCVCD5j
zxMf*3qY~==B@43PU!PU6A&r?)V}H42eo!A#Dix#UaacHK**P=fF+@j7nmqsJX?XIX
z`67ql(20wDZ9GCK?b=-fC5YO6cjUrBeAa4{TYKd)BWN{BrnKY}=(|cqWY97F6cM6>
zMk6mVDD*DKGoa51)H0#vbEhRpG~2be7T(=cGcF~xNGU>r#-R4p%ctOx-+#=8lV{qY
zvs)-PeztHT)3vd&or4So8)N3=pgtF%h*&UE#`G26<j4H)u`v}^UMCD(f)g085;Vd4
zewD+@5CX5ie-1wT@)93k*|vnQlk7Rvz+*>8Yh*q$mWUo*94ceV>LF~E=er>(LCxnx
zk-xlkX52{Ji%Mwl=wZ|&V1F|rK>>h*11aP2zT+$!iqP^;T5gv!z|iR_(K1D@Try;g
zQmJTm3ZL&eXbRwVD49Gl2BV%bAe)m>NC=q@Z&rW&fdbL>q(tZ&h$Oa*I3;Hvw<6Ix
z6-TAYnjYZ|*gijbdEB*AXOCTa&bRp*f@msUe*uxE<V)}M54%#yZGV<Rw_c`*MjLt^
zF*NK1En4)R)ic;??UX~j&N&{Td*Aq=N`}T>^o52?{n9<9sEGL6#`SsVBWhXH5|X0(
z%27+9P=uTaEnqGo{1mNnu*B~4Q{wK`GvUn-tH)I4lg}FAY;6w|<tIaFc?UH5C_zHM
ziS#XHbdsSP-|L&vLw}*8yqeN_eqOTR=pNyvzA`C2dR$}B<oy+pFR;Y%$fqL4oP2ke
zB_L{zV+jXL0}8)nHFDfw6Y!NkJUm}Izy0S^7)hQaI{rgzXYsZ9h>m<5fm#$12W`Wl
zd?IA{m5I$}_j7dhs5Tzq7>Ix;M8FO_CsbeFQ3)S>S`Rn<G=Fn6L^A?H5N6c;hV+S2
zELNLiY-;uOT4dRsHX<&!55TQOQ!)BD*kXqGr~pd_(!>)SG3=~fk&WdK$i~T;8Yexo
zbU_;C2sQK%4)Y4p7Y$O#Y8}D_onvf7`uhh)oy+a?*8VP@%;Az2KGJGYhRPKHp@>I)
zLZdJ*2|nC+0e=y>AghkAnG!EW=D+SZi}SFfB0>VRSO!6_*Gd%AYE_8HPyixk|5YN<
zi%_8?MEhGOOU|<OZo6?Zb5|7+4l9;s!Yez^dFSkb-*1{HJ%6OM6%LoSzyo*XV8pZI
z8e9jbDmply&_q|SFv^rAMT?74B}5*(Hy^DoSUe>;27fMJY=_LuWXZ`5hFC^qXqc1a
zQBjfdUW=o6pnp&*->p`=L@)A@VSK=DABL|gI)w<9tB2zGsqpEMW@x%R08hSH7Ssvp
zeyd&1ZBcoW5BCWRCo+mAO33_M{!|K2ZJY;Z>V(Lck`x1V=bL1{AyQ4;*OI8!XO{1b
z40!29TYotPbBydG0|RzgQ9Kc{Cg`A}bAUN;|C*TsZ9<5@62W&&qT#k1CP`U+MR5jb
zqZC+mTNn+S&EZ$bIs>lBd}L^7$VY3tROh6n2w}6e-NNs(+DG91eT~r9XN9b^Xjr#u
z>Nnr^nGg-z9-PDDlD}-&dIE|IQ@Ky?BQ#oDdVe4yLg}TvgPq;t7m7ti%KI$Hx1rIv
zZ9{6gyjw5HNjj!ieM1-f!n|AqtXgh_8dER#mmtNSeXKAbl3hs(aGb5E1Q(Ma)Lr-A
zIg`)rj$tr0^}_7jiO_{Uq1OwP@A4)=vw2XW)mc;5QBe^KQOoL=Kl;&U#C1G{;0q1i
zQh&nAO4GrPy$w)R*T?-#q}wx(7Q!!=Pa2bIyo;C}2U{PQ16%ISMI{vc{BwV+ghuqW
z8QFU7lMm2DGbhGDYbzn5kRlfCNt-QJ_FMm`)r8KD{@{`&Lqa7kE|yD#d9#i1&wV94
zkUmz!;cw;Qc%I0PkLzLWE!n7m0&ZQN#ec2pf*GnW$iE8_Vl#1~Ng{GM;ii^BXvX$y
ze4ej+qt*pPpCXb*6%Mo^6zfH#yUPrTs0c+Y$}!#z^if4bXD1ZIwL9gL36R2z8FKj7
z-Z}_9-2)ICqs9U=j6<+ag=nN{p{l+QE$DzHg(-s7jj`N<*Ha!20(5`bxo()3lYa<?
zIQdpnePcH}y4xw_88RIC1{qTH7jKR+ONtQ3a*YOPXg0GF21A03TC{2;L`Y7bZG}mb
zl1A$viwzbRr0~QD1#0K9(Y0VcbL{JOzJBbhcF0JMfL|;#24sH9+SPSkFm<wlX(j9<
zL`nW3mMSgn99fU~mnh|}9fSFkaewXJ*4{Z<uJl=$UbJ>6RBBD#;6O*DJtwkKPtPDs
z$}(UMP~fC8CCX3|{P%HT;WY!1*?+tR?pkSNho=5-Z=VL2F7-%b$%;edKTUGZtaM@3
z<jv?}wM&Zn<dAZIMUI-9&H2|Brn9ezVlp*@(U{2}dzLQBf$eYY=gFt0>3>0~K>qgG
zuzavVOsr3B=B3nhA8O6b5m3%Z(@K>9f#7hA;MnruP*u~;{*l7VU=O1qL@cv}2q__E
zb$>;URn>NHvOAnWp?Jqf=Qv5y4&*h{65+1f3ZVGfnf&>!s<s_cQe$}{?|)JaQEC+w
z6=r>tuRCmn=$I&<T;_zb3V&g*IXq0@TPLFX&U>X$UEPdPEfHdLkw{;rT)FsVS6UKw
z_StHZ<F)IYPPhKh7fqm!RKo0;$-E<8i}_;j{%WYLGqIBN`Db=+8uSl1;J`5x`c^M2
zEX>4Z=~b=M;Bu=Oo`0i+ztm=>$MLncHZ$x!P|M$E>Kc1t|FH%rDSvB*mX=;zE?ePL
zxu7H+T`te>aNgxIML6-rYvV4q^cTCFZdhD65u&w`to_1y>7Ylep$}oCQh+fd4iXcz
zSOD7K)alD$vyU{PGWx|uSBJ{^`c61;s@Yst(Gt~ssSmOzB|v*y9~>!ZW`m^|bhs=|
zgP+XB*qNw>$rJTp8Gjgpb9Ee=35gA;h$G++1L9}uv?N{Dtmy`6sYwwfJUmR|B{`x3
z{e$|b1l=;53f_5n6Z8gDu=%n)f6zFT*nA~3T@PP=)kKCMj&H{H0`0HSXNMS_3XP@b
zjdPdF%}BVt>-N^pL0r%C_nP&--`K-Kd}7{BWl)H(w`MWqiE)nR4d1lMx7Fvjp!?Fk
zWtO)c#pjp$d@)|@{lu*&g<_*s{GEjpG#ZUqG2(Q;gU_rF`4^5L3W;l!CVa5zJNjcl
yR<N<X@6Y!tD;j|AI~MS7hacrf`R?Su0t^5KNoW;c40FT)0000<MNUMnLSTXrQth7r

delta 1456
zcmV;h1yA~(9Oes<NPh*0Nkl<Zc-qujzi%5i6y~V{nk_O=pdAYM1Qe(@%TvAeJT;xH
zOzCE6>S*aN&}sA}Wy~aL>!$M-Pd*O?vRT<$pg}L2w<tgd4+YxyQKU@WkrYp&ob~|}
zsXHF;eSAOpq=4;+;y8}PFrzVANMp1)jb|IKD%Ygv<GFgL>VJ{(4t4v~UV?EjOs%Gw
zT2p|YQoEsXVp$pU2h>`*>nVM7sh{~^z9n{=$$nGGQQs)8f$#ALYX2D82Pvgs3lP|)
zOX^ck62;DUgz62&)oc2Q);tQy*MpKTYd|%8F>j+Nid$*QMvl|Fl`?8XUGp(OfCxkx
zRXq)M;IBfV4u7FAew85@=11@;jMchz^wD$0U3Jh~h_@>|k&Sss>@3H4L1RQu41!Mv
zZ#AKDV$gk8ny*tW7+>2Af_oJJ{Zs5-S<ls^Hl;P_`8elZSyE!1%Pmxk$BmvLR%~n<
z*f?5SY+O7QU~NQm<9fxQQn5KMK;8HY2A)Ak)w`wjC4cj6VOKWS`y7MM3@-LSA8onK
zxcK%GZZ>3LSYuhXG>IqFexf_?>3wfVNUvxd2(_&#0DhtNqm*8tGjM8i3y8+H%-3p9
z*kJGjYqeIF8jokJ-@j2oLCwZ4YX&(Gp~bLW^mQ#^_ph(dc(2u!`8_*1nXuXHPF^~4
z$*1x*(tooUcGHI{jYg+N5K>yx=?mTqnhI?wm;em90EDhJ7d~AZBYM8<0nJ5f&E~=K
ztM2{cD6p>sk{HqtZ!Xpa#4_hN{WcfRv|hBo0z}wGXo=X5PKs(7)n2vdiV|UU^hrSQ
zD3{GOyl8D@paR)9c&js?%q7Wh&U0^W-kVaI!hcj8&ZKH}4Qdto1Ok_urkRs85L0xf
zV@PXefyi)cMTzhvZnO*CM;vK1zH*Htg}llXM;eBm*GdBs*~ZA)d|NPz2#&FO9a5;*
zUz$J|dBUO3b{^T+T?7EQQH@tA1qPmev%@Be4TT58swKM&+5d-TRegfEeLjVjH*81}
z(tl7@Cm-!`uZ(w-!Mv)}mAn-dkk$5j-?Jd-uUv<10UT^(@y>|P%hPc9hIPAFrD|ig
zqwZ|i`T!7+(9zK=4jP6I*W2kFuQ?GGv!ANr1{2keof143R7t8DKwxakjvtP}tKh1Z
z>PYG<>ou!H%Do^Y055oW_@$clnt0Nw)_=I76yNf<cUp*(f${eCXC9l*&%fi>)<pi9
z1_V!drHve#(xY7g!Op{5Aqej6UGN4cph*^0nwau031niZnoNA1Kk^1F?O-x_yNvLV
zh~><Z8IHU>;jJpCEuHoy!ni_Rs-mVClHfMwuHsk=MxQ?YyZ}Vb!8(_hzb{hlvwy=S
zKwQtc;J(2=x+~=%*hv&cS(>If?xK%s`V8Z|zyF&z9bH|$W3ONT!FTuBvv2qg9~^wa
zE-rrM9_jAxFFprj%#kXFhCm4BF+M*2nm?mRqpgb{sW7TQH5$Y+^+2yY;<c8w0X^5%
zhl$k@wRZl@o|)X6sQAr45s0w?#D7Y$q(tpE76s?WO$Mo*<bU{dscZ2cHAUG}WB9E7
zUjU(tdlkJX*||X~<3|Ex1JTr#r*smTn_Qg&=E#zxd9Vq)Iz9YY`ar>&^tfsM4V<6#
zdyC?kp9&CL{BE8Yc&RBH&0JJ#B_-15VSGtikO!l>*u`xCv=>DMD~LfUV}H+Ql@^z*
zq}AM)?+N=!9MleL4i_rQ0j%2yIG?WVH0$hsMW7s(I~vE4CSS@*yc33<y1cUtkWh%X
zy^C|cE^1TvR%h5gUlJ<+{_(!H+PhL^!}mcVkt`s40?-jss3|FvGX<WQfOH)Gvb6F{
zLnNY^>oYd0dIFLPqm0x{S}6uN@yD})C}^Zg=_x6@^CtRNfB^v4m4`140g|);0000<
KMNUMnLSTXqoyPG1

diff --git a/app/assets/images/common/code_languages/php_small.png b/app/assets/images/common/code_languages/php_small.png
new file mode 100644
index 0000000000000000000000000000000000000000..62a5010f39a54a3ee9f6b7e1aef1c1a8fddcae14
GIT binary patch
literal 3353
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

literal 0
HcmV?d00001

diff --git a/app/assets/images/common/code_languages/python_small.png b/app/assets/images/common/code_languages/python_small.png
index f16d48c07a02e5f23d0a79e76c64ef0e53037dfd..aa303a518a05e192b3d4d022dbb0ba65d384c4d9 100644
GIT binary patch
literal 4192
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

literal 17483
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

diff --git a/app/assets/images/common/code_languages/ruby_small.png b/app/assets/images/common/code_languages/ruby_small.png
new file mode 100644
index 0000000000000000000000000000000000000000..9839340f75d91f6ff98a1649a2e93644243f8b0b
GIT binary patch
literal 2797
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

literal 0
HcmV?d00001

diff --git a/app/assets/images/common/code_languages/swift_small.png b/app/assets/images/common/code_languages/swift_small.png
new file mode 100644
index 0000000000000000000000000000000000000000..95d9c049ae0942535af58b704349c802b24f0771
GIT binary patch
literal 2631
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

literal 0
HcmV?d00001

diff --git a/app/views/HomeView.coffee b/app/views/HomeView.coffee
index c055214bf..05e9f78f0 100644
--- a/app/views/HomeView.coffee
+++ b/app/views/HomeView.coffee
@@ -52,7 +52,7 @@ module.exports = class HomeView extends RootView
     @updateLanguageLogos codeLanguage
 
   updateLanguageLogos: (codeLanguage) ->
-    @$el.find('.game-mode-wrapper .code-language-logo').css('background-image', "url(/images/common/code_languages/#{codeLanguage}_small.png)").toggleClass 'inverted', (codeLanguage in ['io', 'coffeescript'])
+    @$el.find('.game-mode-wrapper .code-language-logo').css('background-image', "url(/images/common/code_languages/#{codeLanguage}_small.png)")
 
   onCodeLanguageSelected: (e) ->
     target = $(e.target).closest('.code-language')

From 1537754a1688af6050652c68a06a96558a44f6ce Mon Sep 17 00:00:00 2001
From: Nick Winter <livelily@gmail.com>
Date: Sat, 19 Jul 2014 20:26:13 -0700
Subject: [PATCH 57/58] A few bugfixes, plus gigantic child window convenience
 for me editing levels.

---
 app/lib/Angel.coffee                        | 2 ++
 app/views/editor/level/edit.coffee          | 5 ++++-
 app/views/play/level/tome/spell.coffee      | 1 +
 app/views/play/level/tome/spell_view.coffee | 2 +-
 4 files changed, 8 insertions(+), 2 deletions(-)

diff --git a/app/lib/Angel.coffee b/app/lib/Angel.coffee
index 4beeffa97..3b5f59a75 100644
--- a/app/lib/Angel.coffee
+++ b/app/lib/Angel.coffee
@@ -213,6 +213,8 @@ module.exports = class Angel extends CocoClass
     work.t1 = now()
     Math.random = work.testWorld.rand.randf  # so user code is predictable
     Aether.replaceBuiltin('Math', Math)
+    replacedLoDash = _.runInContext(window)
+    _[key] = replacedLoDash[key] for key, val of replacedLoDash
     i = 0
     while i < work.testWorld.totalFrames
       frame = work.testWorld.getFrame i++
diff --git a/app/views/editor/level/edit.coffee b/app/views/editor/level/edit.coffee
index 6683d6a54..62666f44a 100644
--- a/app/views/editor/level/edit.coffee
+++ b/app/views/editor/level/edit.coffee
@@ -94,7 +94,10 @@ module.exports = class EditorLevelView extends RootView
       # Create a new Window with a blank LevelView
       scratchLevelID = @level.get('slug') + '?dev=true'
       scratchLevelID += "&team=#{team}" if team
-      @childWindow = window.open("/play/level/#{scratchLevelID}", 'child_window', 'width=1024,height=560,left=10,top=10,location=0,menubar=0,scrollbars=0,status=0,titlebar=0,toolbar=0', true)
+      if me.get('name') is 'Nick!'
+        @childWindow = window.open("/play/level/#{scratchLevelID}", 'child_window', 'width=2560,height=1080,left=0,top=-1600,location=1,menubar=1,scrollbars=1,status=0,titlebar=1,toolbar=1', true)
+      else
+        @childWindow = window.open("/play/level/#{scratchLevelID}", 'child_window', 'width=1024,height=560,left=10,top=10,location=0,menubar=0,scrollbars=0,status=0,titlebar=0,toolbar=0', true)
       @childWindow.onPlayLevelViewLoaded = (e) => sendLevel()  # still a hack
     @childWindow.focus()
 
diff --git a/app/views/play/level/tome/spell.coffee b/app/views/play/level/tome/spell.coffee
index 0572542b3..72a897ee2 100644
--- a/app/views/play/level/tome/spell.coffee
+++ b/app/views/play/level/tome/spell.coffee
@@ -90,6 +90,7 @@ module.exports = class Spell
           problems = spellThang.aether.problems
         #console.log 'aether transpiled', source.length, 'to', spellThang.aether.pure.length, 'for', thangID, @spellKey
       else
+        spellThang.aether.raw = source
         spellThang.aether.pure = pure
         spellThang.aether.problems = problems
         #console.log 'aether reused transpilation for', thangID, @spellKey
diff --git a/app/views/play/level/tome/spell_view.coffee b/app/views/play/level/tome/spell_view.coffee
index 3f6ec643d..46fb62e4e 100644
--- a/app/views/play/level/tome/spell_view.coffee
+++ b/app/views/play/level/tome/spell_view.coffee
@@ -396,7 +396,7 @@ module.exports = class SpellView extends CocoView
 
   displayAether: (aether, isCast=false) ->
     @displayedAether = aether
-    isCast = isCast or not _.isEmpty(aether.metrics) or _.some aether.problems.errors, {type: 'runtime'}
+    isCast = isCast or not _.isEmpty(aether.metrics) or _.some aether.getAllProblems(), {type: 'runtime'}
     problem.destroy() for problem in @problems  # Just in case another problem was added since clearAetherDisplay() ran.
     @problems = []
     annotations = []

From 9724c4f2180511a43d56f81fb58d5b31fca3846c Mon Sep 17 00:00:00 2001
From: Melondonut <psamy1@nate.com>
Date: Sun, 20 Jul 2014 23:19:41 +0900
Subject: [PATCH 58/58] Update ko.coffee
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Hi there.
I'm not sure that if it is okay to to this .. but anyway I thought there were a lot of thing that I could help so I did translate a bit. I checked out the code combat website but they just says "go to github, and translate."
thank you,
Melondonut.

안녕하세요. 제가 이래도 되는 건지는 모르겠지만, 제가 도움이 될 수 있을 것 같아 시험삼아 조금 번역해보았습니다. 코드 컴뱃 사이트를 확인했는데, 깃헙에 가서 번역한 다음 리퀘스트하라는 말만 있더라구요; 확인해주시면 감사하겠습니다.
---
 app/locale/ko.coffee | 44 ++++++++++++++++++++++----------------------
 1 file changed, 22 insertions(+), 22 deletions(-)

diff --git a/app/locale/ko.coffee b/app/locale/ko.coffee
index fdc645eb4..25b6159ac 100644
--- a/app/locale/ko.coffee
+++ b/app/locale/ko.coffee
@@ -90,11 +90,11 @@ module.exports = nativeDescription: "한국어", englishDescription: "Korean", t
 #    required: "You need to log in before you can go that way."
 
   home:
-    slogan: "쉽고 간단한 게임배우기"
+    slogan: "쉽고 간단한 게임 배우기"
     no_ie: "죄송하지만 코드컴뱃은 인터넷 익스플로러 9에서는 동작하지 않습니다."
     no_mobile: "코드 컴뱃은 모바일 기기용으로 제작되지 않았습니다. 아마 동작하지 않을 가능성이 높습니다."
     play: "시작"
-    old_browser: "브라우저가 너무 오래된 버전이라 코드컴뱃을 실행할 수 없습니다."
+    old_browser: "브라우저가 너무 오래된 버전이라 코드 컴뱃을 실행할 수 없습니다."
     old_browser_suffix: "시도해볼 수는 있겠지만..안될수도 있습니다."
     campaign: "캠페인"
     for_beginners: "초보자용"
@@ -109,7 +109,7 @@ module.exports = nativeDescription: "한국어", englishDescription: "Korean", t
 
   play:
     choose_your_level: "레벨을 선택하세요."
-    adventurer_prefix: "아래에 있는 어떤 레벨도 바로 시작하실 수 있습니다.또는 포럼에서 레벨에 관해 토론하세요 :"
+    adventurer_prefix: "아래에 있는 아무 레벨이나 바로 시작하실 수 있습니다. 또는 포럼에서 레벨에 관해 토론하세요 :"
     adventurer_forum: "모험가들의 포럼"
     adventurer_suffix: "."
     campaign_beginner: "초보자 캠페인"
@@ -125,7 +125,7 @@ module.exports = nativeDescription: "한국어", englishDescription: "Korean", t
     spectate: "관중모드"
 
   contact:
-    contact_us: "코드컴뱃에 전할말"
+    contact_us: "코드컴뱃에 전할 말"
     welcome: "의견은 언제든지 환영합니다. 이 양식을 이메일에 사용해 주세요!"
     contribute_prefix: "혹시 같이 코드컴뱃에 공헌하고 싶으시다면 홈페이지에 들러주세요 "
     contribute_page: "참여하기 페이지"
@@ -139,15 +139,15 @@ module.exports = nativeDescription: "한국어", englishDescription: "Korean", t
 
   diplomat_suggestion:
     title: "코드 컴뱃 번역을 도와주세요!"
-    sub_heading: "우리는 당신의 언어 능력이필요합니다."
-    pitch_body: "우리는 영어로 코드컴뱃을 개발하기 시작했지만, 이미 전세계의 유저들이 코드컴뱃을 이용하고 있습니다. 그중 많은 사람들이 한국어로 플레이하기를 바랍니다. 혹시 당신이 영어/한국어에 모두 능숙하다면, Diplomat 으로 코드컴뱃에 참여해서 모든 레벨 뿐 아니라 웹사이트를 한국어로 번역할 수 있습니다."
+    sub_heading: "우리는 당신의 언어 능력이 필요합니다."
+    pitch_body: "우리는 영어로 코드컴뱃을 개발하기 시작했지만, 이미 전세계의 유저들이 코드컴뱃을 이용하고 있습니다. 그 중 많은 사람들이 한국어로 플레이하기를 바랍니다. 혹시 당신이 영어/한국어에 모두 능숙하다면, Diplomat 으로 코드컴뱃에 참여해서 모든 레벨 뿐 아니라 웹사이트를 한국어로 번역할 수 있습니다."
     missing_translations: "우리가 모든 내용을 한국어로 번역할때까지 기본은 영어로 제공됩니다."
-    learn_more: "외교관에 대해서 좀더 자세히알기"
-    subscribe_as_diplomat: "훌륭한 외교관으로써, 정기 구독하기"
+    learn_more: "외교관에 대해서 좀 더 자세히 알아보기"
+    subscribe_as_diplomat: "외교관을 위한 정기 구독"
 
   wizard_settings:
     title: "마법사 설장"
-    customize_avatar: "당신의 분신을 직접 꾸미세요"
+    customize_avatar: "당신의 아바타를 직접 꾸미세요"
 #    active: "Active"
 #    color: "Color"
 #    group: "Group"
@@ -163,7 +163,7 @@ module.exports = nativeDescription: "한국어", englishDescription: "Korean", t
 
   account_settings:
     title: "계정 설정"
-    not_logged_in: "로그인 하시거나 계정을 생성하여 주세요."
+    not_logged_in: "로그인하시거나 계정을 생성하세요."
     autosave: "변경 사항은 자동 저장 됩니다"
     me_tab: "나"
     picture_tab: "사진"
@@ -192,17 +192,17 @@ module.exports = nativeDescription: "한국어", englishDescription: "Korean", t
     error_saving: "오류 저장"
     saved: "변경사항 저장 완료"
     password_mismatch: "비밀번호가 일치하지 않습니다."
-#    password_repeat: "Please repeat your password."
+    password_repeat: "비밀번호를 한번 더 입력해 주세요."
 #    job_profile: "Job Profile"
 #    job_profile_approved: "Your job profile has been approved by CodeCombat. Employers will be able to see it until you either mark it inactive or it has not been changed for four weeks."
 #    job_profile_explanation: "Hi! Fill this out, and we will get in touch about finding you a software developer job."
 #    sample_profile: "See a sample profile"
-#    view_profile: "View Your Profile"
+    view_profile: "나의 프로필 보기"
 
   account_profile:
-#    settings: "Settings"
-#    edit_profile: "Edit Profile"
-#    done_editing: "Done Editing"
+    settings: "설정"
+    edit_profile: "프로필 수정하기"
+    done_editing: "수정 완료"
     profile_for_prefix: "프로필 "
     profile_for_suffix: ""
 #    featured: "Featured"
@@ -357,10 +357,10 @@ module.exports = nativeDescription: "한국어", englishDescription: "Korean", t
     multiplayer: "멀티 플레이어"
     restart: "재시작"
     goals: "목표"
-#    success: "Success!"
-#    incomplete: "Incomplete"
-#    timed_out: "Ran out of time"
-#    failing: "Failing"
+    success: "성공!"
+    incomplete: "목표 미완료"
+    timed_out: "제한 시간 초과"
+    failing: "다시 한번 더 도전해보세요."
     action_timeline: "액션 타임라인"
     click_to_select: "유닛을 선택하기 위해서 유닛을 마우스로 클릭하세요."
     reload_title: "모든 코드가 다시 로딩 되었나요?"
@@ -400,8 +400,8 @@ module.exports = nativeDescription: "한국어", englishDescription: "Korean", t
     editor_config: "에디터 설정"
     editor_config_title: "에디터 설정"
 #    editor_config_level_language_label: "Language for This Level"
-#    editor_config_level_language_description: "Define the programming language for this particular level."
-#    editor_config_default_language_label: "Default Programming Language"
+    editor_config_level_language_description: "이 레벨에서 사용할 언어를 선택하세요."
+    editor_config_default_language_label: "기본 프로그래밍 언어"
 #    editor_config_default_language_description: "Define the programming language you want to code in when starting new levels."
     editor_config_keybindings_label: "단축키 설정"
     editor_config_keybindings_default: "기본(Ace)"
@@ -414,7 +414,7 @@ module.exports = nativeDescription: "한국어", englishDescription: "Korean", t
     editor_config_indentguides_description: "들여쓰기 확인위해 세로줄 표시하기."
     editor_config_behaviors_label: "자동 기능"
     editor_config_behaviors_description: "괄호, 인용부호, 따옴표 자동 완성."
-#    keyboard_shortcuts: "Key Shortcuts"
+    keyboard_shortcuts: "단축키"
 #    loading_ready: "Ready!"
 #    tip_insert_positions: "Shift+Click a point on the map to insert it into the spell editor."
 #    tip_toggle_play: "Toggle play/paused with Ctrl+P."