From 1f20402bb02cef33ea0760e20e648adbeaaa6a26 Mon Sep 17 00:00:00 2001 From: Imperadeiro98 Date: Thu, 12 Feb 2015 18:31:01 +0000 Subject: [PATCH 01/10] Update pt-PT.coffee --- app/locale/pt-PT.coffee | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/app/locale/pt-PT.coffee b/app/locale/pt-PT.coffee index 6e4010c96..b48c99d50 100644 --- a/app/locale/pt-PT.coffee +++ b/app/locale/pt-PT.coffee @@ -548,24 +548,24 @@ module.exports = nativeDescription: "Português (Portugal)", englishDescription: # for_girls_1: "There are three game modes in CodeCombat: building, puzzles, and combat. We have intentionally designed each to appeal to both boys and girls and think that the building and puzzle levels especially differentiate the game from violent triple A titles that repel female players." what_cover_title: "O que abordamos?" # what_cover_1: "There are 20 levels in the Hour of Code tutorial that teach and reinforce 6 specific computer science concepts:" -# what_cover_notation_1: "Formal notation" + what_cover_notation_1: "Notação formal" # what_cover_notation_2: "- builds an understanding of the importance of syntax in programming." -# what_cover_methods_1: "Calling methods" + what_cover_methods_1: "Chamar métodos" # what_cover_methods_2: "- familiarizes students with the syntax of object-oriented method calls." -# what_cover_parameters_1: "Parameters" + what_cover_parameters_1: "Parâmetros" # what_cover_parameters_2: "- trains how to pass parameters to functions." -# what_cover_strings_1: "Strings" + what_cover_strings_1: "'Strings'" # what_cover_strings_2: "- teaches students about string notation and passing strings as parameters." -# what_cover_loops_1: "Loops" + what_cover_loops_1: "'Loops'" # what_cover_loops_2: "- develops the abstraction of designing short programs with loops." -# what_cover_variables_1: "Variables" + what_cover_variables_1: "Variáveis" # what_cover_variables_2: "- adds the skill of referencing values that change over time." # what_cover_2: "Students may continue past level 20, depending on their speed and interest, to learn two additional concepts in later levels:" -# what_cover_logic_1: "Conditional logic" + what_cover_logic_1: "Lógica condicional" # what_cover_logic_2: "- when and how to use if/else to control in-game outcomes." # what_cover_input_1: "Handling player input" # what_cover_input_2: "- responding to input events to create a user interface." -# sys_requirements_title: "System Requirements" + sys_requirements_title: "Requisitos do Sistema" # sys_requirements_1: "Because CodeCombat is a game, it is more intensive for computers to run smoothly than video or written tutorials. We have optimized it to run quickly on all modern browsers and on older machines so that everyone can play. That said, here are our suggestions for getting the most out of your Hour of Code experience:" # sys_requirements_2: "Use newer versions of Chrome or Firefox." # sys_requirements_3: "Although CodeCombat will work on browsers as old as IE9, the performance is not as good. Chrome is best." @@ -769,8 +769,8 @@ module.exports = nativeDescription: "Português (Portugal)", englishDescription: achievement_search_title: "Procurar Conquistas" read_only_warning2: "Nota: não podes guardar nenhuma edição feita aqui, porque não tens sessão iniciada." no_achievements: "Ainda não foram adicionadas conquistas a este nível." -# achievement_query_misc: "Key achievement off of miscellanea" -# achievement_query_goals: "Key achievement off of level goals" + achievement_query_misc: "Conquista-chave de uma lista de variados" + achievement_query_goals: "Conquista-chave dos objetivos do nível" level_completion: "Completação do Nível" pop_i18n: "Propagar I18N" tasks: "Tarefas" @@ -794,7 +794,7 @@ module.exports = nativeDescription: "Português (Portugal)", englishDescription: join_desc_2: "para começares, e assinalar a caixa abaixo para te declarares um bravo Arcomago e receberes as últimas notícias por e-mail. Queres falar sobre o que fazer ou como te envolveres mais profundamente no projeto? " join_desc_3: " ou encontra-nos na nossa " join_desc_4: "e começamos a partir daí!" - join_url_email: "Envia-nos uma mensagem" + join_url_email: "Contacta-nos" join_url_hipchat: "sala HipChat pública" archmage_subscribe_desc: "Receber e-mails relativos a novas oportunidades de programação e anúncios." artisan_introduction_pref: "Temos de construir mais níveis! As pessoas estão a pedir mais conteúdo, e nós mesmos só podemos construir estes tantos. Neste momento, a tua estação de trabalho é o nível um; o nosso editor de nível é pouco utilizável, até mesmo pelos seus criadores, por isso fica atento. Se tens visões de campanhas que abranjam 'for-loops' para o" From 8936d5fa407d1731842195c0b63ce353b8d374d8 Mon Sep 17 00:00:00 2001 From: Nick Winter Date: Thu, 12 Feb 2015 10:59:26 -0800 Subject: [PATCH 02/10] Simulator version 2 takes into account flag history when simulating matches. --- app/lib/simulator/Simulator.coffee | 8 +++++++- server/queues/scoring.coffee | 2 +- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/app/lib/simulator/Simulator.coffee b/app/lib/simulator/Simulator.coffee index 2ec95bfef..8b8f9f92f 100644 --- a/app/lib/simulator/Simulator.coffee +++ b/app/lib/simulator/Simulator.coffee @@ -5,7 +5,7 @@ GoalManager = require 'lib/world/GoalManager' God = require 'lib/God' {createAetherOptions} = require 'lib/aether_utils' -SIMULATOR_VERSION = 1 +SIMULATOR_VERSION = 2 simulatorInfo = {} if $.browser @@ -225,6 +225,12 @@ module.exports = class Simulator extends CocoClass @god.setLevelSessionIDs (session.sessionID for session in @task.getSessions()) @god.setWorldClassMap @world.classMap @god.setGoalManager new GoalManager(@world, @level.get 'goals') + humanFlagHistory = _.filter @session.get('state')?.flagHistory ? [], (event) => event.source isnt 'code' and event.team is (@session.get('team') ? 'humans') + ogreFlagHistory = _.filter @otherSession.get('state')?.flagHistory ? [], (event) => event.source isnt 'code' and event.team is (@otherSession.get('team') ? 'ogres') + @god.lastFlagHistory = humanFlagHistory.concat ogreFlagHistory + #console.log 'got flag history', @god.lastFlagHistory, 'from', humanFlagHistory, ogreFlagHistory, @session.get('state'), @otherSession.get('state') + @god.lastSubmissionCount = 0 # TODO: figure out how to combine submissionCounts from both players so we can use submissionCount random seeds again. + @god.lastDifficulty = 0 commenceSimulationAndSetupCallback: -> Backbone.Mediator.subscribeOnce 'god:infinite-loop', @onInfiniteLoop, @ diff --git a/server/queues/scoring.coffee b/server/queues/scoring.coffee index 74f822243..c2cf71be4 100644 --- a/server/queues/scoring.coffee +++ b/server/queues/scoring.coffee @@ -15,7 +15,7 @@ bayes = new (require 'bayesian-battle')() scoringTaskQueue = undefined scoringTaskTimeoutInSeconds = 600 -SIMULATOR_VERSION = 1 +SIMULATOR_VERSION = 2 module.exports.setup = (app) -> connectToScoringQueue() From 6b9d8161ef16aa1153d952f3a60e9bd36ca81372 Mon Sep 17 00:00:00 2001 From: Nick Winter Date: Thu, 12 Feb 2015 11:17:23 -0800 Subject: [PATCH 03/10] Found another place missing cache: false. --- app/models/CocoModel.coffee | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/models/CocoModel.coffee b/app/models/CocoModel.coffee index bb5e12727..a377467fe 100644 --- a/app/models/CocoModel.coffee +++ b/app/models/CocoModel.coffee @@ -182,6 +182,7 @@ class CocoModel extends Backbone.Model options ?= {} options.data ?= {} options.data.project = @project.join(',') if @project + #console.error @constructor.className, @, "fetching with cache?", options.cache, "options", options # Useful for debugging cached IE fetches @jqxhr = super(options) @loading = true @jqxhr @@ -364,7 +365,7 @@ class CocoModel extends Backbone.Model achievements = new NewAchievementCollection achievements.fetch success: (collection) -> - me.fetch (success: -> Backbone.Mediator.publish('achievements:new', earnedAchievements: collection)) unless _.isEmpty(collection.models) + me.fetch (cache: false, success: -> Backbone.Mediator.publish('achievements:new', earnedAchievements: collection)) unless _.isEmpty(collection.models) error: -> console.error 'Miserably failed to fetch unnotified achievements', arguments cache: false From e01e71d5e8717823589235a78af2910bf2278525 Mon Sep 17 00:00:00 2001 From: Nick Winter Date: Thu, 12 Feb 2015 11:59:38 -0800 Subject: [PATCH 04/10] Fixed #2181, I hope. --- .../play/common/LadderSubmissionView.coffee | 31 +++++++++---------- 1 file changed, 15 insertions(+), 16 deletions(-) diff --git a/app/views/play/common/LadderSubmissionView.coffee b/app/views/play/common/LadderSubmissionView.coffee index c5dfe772c..3ee59666b 100644 --- a/app/views/play/common/LadderSubmissionView.coffee +++ b/app/views/play/common/LadderSubmissionView.coffee @@ -56,27 +56,26 @@ module.exports = class LadderSubmissionView extends CocoView failure = (jqxhr, textStatus, errorThrown) => console.log jqxhr.responseText @setRankingButtonText 'failed' unless @destroyed - transpiledCode = @transpileSession() + @transpileSession (transpiledCode) => - ajaxData = - session: @session.id - levelID: @level.id - originalLevelID: @level.get('original') - levelMajorVersion: @level.get('version').major - transpiledCode: transpiledCode + ajaxData = + session: @session.id + levelID: @level.id + originalLevelID: @level.get('original') + levelMajorVersion: @level.get('version').major + transpiledCode: transpiledCode - $.ajax '/queue/scoring', { - type: 'POST' - data: ajaxData - success: success - error: failure - } + $.ajax '/queue/scoring', { + type: 'POST' + data: ajaxData + success: success + error: failure + } - transpileSession: -> + transpileSession: (callback) -> submittedCode = @session.get('code') codeLanguage = @session.get('codeLanguage') or 'javascript' @session.set('submittedCodeLanguage', codeLanguage) - @session.save() # TODO: maybe actually use a callback to make sure this works? transpiledCode = {} for thang, spells of submittedCode transpiledCode[thang] = {} @@ -85,7 +84,7 @@ module.exports = class LadderSubmissionView extends CocoView aetherOptions = createAetherOptions functionName: spellID, codeLanguage: codeLanguage aether = new Aether aetherOptions transpiledCode[thang][spellID] = aether.transpile spell - transpiledCode + @session.save null, success: -> callback transpiledCode onHelpSimulate: -> @playSound 'menu-button-click' From d937feb3de905bd867aa658815eb072fbd6977ac Mon Sep 17 00:00:00 2001 From: Matt Lott Date: Thu, 12 Feb 2015 13:38:34 -0800 Subject: [PATCH 05/10] :bug:Fix share progress title wrap on IE11 Fixes #2301 --- app/styles/play/modal/share-progress-modal.sass | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/styles/play/modal/share-progress-modal.sass b/app/styles/play/modal/share-progress-modal.sass index fa35df618..4498ba26a 100644 --- a/app/styles/play/modal/share-progress-modal.sass +++ b/app/styles/play/modal/share-progress-modal.sass @@ -35,7 +35,7 @@ width: 300px h1 - font-size: 29px + font-size: 28px font-weight: bold color: black From c4f46faf2565f353691bc42fa0cd7db847043b39 Mon Sep 17 00:00:00 2001 From: Matt Lott Date: Thu, 12 Feb 2015 14:19:19 -0800 Subject: [PATCH 06/10] :bug:Fix leaderboard level popup stacked buttons MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit CSS initial keyword isn’t supported in IE. Fixes #2301 --- app/styles/play/campaign-view.sass | 38 +++++++++++++++--------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/app/styles/play/campaign-view.sass b/app/styles/play/campaign-view.sass index be3c2783f..737ab74f1 100644 --- a/app/styles/play/campaign-view.sass +++ b/app/styles/play/campaign-view.sass @@ -63,7 +63,7 @@ $gameControlMargin: 30px height: 100% background-size: 100% @include user-select(none) - + .level, .level-shadow position: absolute border-radius: 50% @@ -108,26 +108,26 @@ $gameControlMargin: 30px &.complete border: 3px solid gold @include box-shadow(0px 0px 35px skyblue) - + img.banner position: absolute bottom: 38% left: -50% width: 200% pointer-events: none - + img.star width: 100% bottom: 7% position: absolute pointer-events: none - + .glyphicon-star position: absolute color: lightblue font-size: 21px left: 1.5px - + &.started .glyphicon-star left: 0.5px @@ -138,7 +138,7 @@ $gameControlMargin: 30px left: 75% margin-left: 0 margin-bottom: 0 - + img.hero-portrait position: absolute border: 1px solid black @@ -258,10 +258,10 @@ $gameControlMargin: 30px border-radius: 50% opacity: 1 padding: 3px 9px - + &.complete .start-level, .view-solutions - min-width: initial + min-width: calc(50% - 5px) display: inline-block width: calc(50% - 5px) @@ -277,10 +277,10 @@ $gameControlMargin: 30px z-index: 1 font-size: 2vw text-shadow: 0 0 0.3vw white, 0 0 0.3vw white - + &:hover text-decoration: none - + .next-level-line transform-origin: 0 100% height: 8px @@ -314,9 +314,9 @@ $gameControlMargin: 30px margin-left: $gameControlMargin width: $gameControlSize height: $gameControlSize - + background: url(/images/pages/play/menu_icons.png) no-repeat - + position: relative img position: absolute @@ -324,21 +324,21 @@ $gameControlMargin: 30px top: 0 width: 100% height: 100% - + background-size: cover @include transition(0.5s ease) @include box-shadow(2px 2px 4px black) border: 0 border-radius: 12px // IE9 shows a blank white button with this MS gradient filter in place - filter: none - + filter: none + &:hover @include box-shadow(0 0 12px #bbf) &:active @include box-shadow(0 0 20px white) - + &.heroes background-position: (-1 * $gameControlSize) 0px &.achievements @@ -369,7 +369,7 @@ $gameControlMargin: 30px .user-status-line position: relative - + button.btn.btn-illustrated margin-left: 10px min-width: 90px @@ -390,7 +390,7 @@ $gameControlMargin: 30px margin-left: 45px $spriteSheetSize: 30px - + .player-level-icon, .player-hero-icon background: transparent url(/images/pages/play/play-spritesheet.png) background-size: cover @@ -420,7 +420,7 @@ $gameControlMargin: 30px background-position: (-11 * $spriteSheetSize) 0 &.sorcerer background-position: (-12 * $spriteSheetSize) 0 - + #volume-button position: absolute From 1aa738b2566c0e6df9a1914ff7eb926f32f7f26a Mon Sep 17 00:00:00 2001 From: Nick Winter Date: Thu, 12 Feb 2015 16:06:27 -0800 Subject: [PATCH 07/10] Fixed up headless client, I hope. --- app/core/utils.coffee | 4 +- app/lib/LevelLoader.coffee | 2 +- app/views/play/level/tome/Spell.coffee | 2 +- headless_client.coffee | 7 +++- headless_client/jQlone.coffee | 2 +- headless_client/test.js | 51 +++++++++++++------------- headless_client/worker_world.coffee | 24 ++++++++---- package.json | 2 +- 8 files changed, 53 insertions(+), 41 deletions(-) diff --git a/app/core/utils.coffee b/app/core/utils.coffee index eecf06a7f..18b20fa8b 100644 --- a/app/core/utils.coffee +++ b/app/core/utils.coffee @@ -144,7 +144,7 @@ module.exports.getUTCDay = (offset=0) -> # Fast, basic way to replace text in an element when you don't need much. # http://stackoverflow.com/a/4962398/540620 -if document? +if document?.createElement dummy = document.createElement 'div' dummy.innerHTML = 'text' TEXT = if dummy.textContent is 'text' then 'textContent' else 'innerText' @@ -155,7 +155,7 @@ if document? # Add a stylesheet rule # http://stackoverflow.com/questions/524696/how-to-create-a-style-tag-with-javascript/26230472#26230472 # Don't use wantonly, or we'll have to implement a simple mechanism for clearing out old rules. -if document? +if document?.createElement module.exports.injectCSS = ((doc) -> # wrapper for all injected styles and temp el to create them wrap = doc.createElement("div") diff --git a/app/lib/LevelLoader.coffee b/app/lib/LevelLoader.coffee index 048487ec1..2b22c98c7 100644 --- a/app/lib/LevelLoader.coffee +++ b/app/lib/LevelLoader.coffee @@ -94,7 +94,7 @@ module.exports = class LevelLoader extends CocoClass if session is @session codeLanguage = session.get('codeLanguage') or me.get('aceConfig')?.language or 'python' modulePath = "vendor/aether-#{codeLanguage}" - loading = application.moduleLoader.load(modulePath) + loading = application.moduleLoader?.load(modulePath) if loading @languageModuleResource = @supermodel.addSomethingResource 'language_module' @listenTo application.moduleLoader, 'loaded', (e) -> diff --git a/app/views/play/level/tome/Spell.coffee b/app/views/play/level/tome/Spell.coffee index 9c4c98f6f..6cb53bc9e 100644 --- a/app/views/play/level/tome/Spell.coffee +++ b/app/views/play/level/tome/Spell.coffee @@ -206,7 +206,7 @@ module.exports = class Spell @problemContext = { stringReferences: [], thisMethods: [], thisProperties: [] } # TODO: These should be read from the database - @problemContext.commonThisMethods = ['moveRight', 'moveLeft', 'moveUp', 'moveDown', 'attack', 'findNearestEnemy', 'buildXY', 'moveXY', 'say', 'move', 'distance', 'findEnemies', 'getFriends', 'addFlag', 'getFlag', 'removeFlag', 'getFlags', 'attackRange', 'cast', 'buildTypes', 'jump', 'jumpTo', 'attackXY'] + @problemContext.commonThisMethods = ['moveRight', 'moveLeft', 'moveUp', 'moveDown', 'attack', 'findNearestEnemy', 'buildXY', 'moveXY', 'say', 'move', 'distance', 'findEnemies', 'findFriends', 'addFlag', 'findFlag', 'removeFlag', 'findFlags', 'attackRange', 'cast', 'buildTypes', 'jump', 'jumpTo', 'attackXY'] return @problemContext unless thang? # Populate stringReferences diff --git a/headless_client.coffee b/headless_client.coffee index 1c426bdba..27fca376b 100644 --- a/headless_client.coffee +++ b/headless_client.coffee @@ -22,7 +22,8 @@ options = simulateOnlyOneGame: simulateOneGame options.heapdump = require('heapdump') if options.heapdump -server = if options.testing then 'http://127.0.0.1:3000' else 'https://codecombat.com' +server = if options.testing then 'http://127.0.0.1:3000' else 'http://direct.codecombat.com' +# Use direct instead of live site because jQlone's requests proxy doesn't do caching properly and CloudFlare gets too aggressive. # Disabled modules disable = [ @@ -62,12 +63,16 @@ hookedLoader = (request, parent, isMain) -> if request in disable or ~request.indexOf('templates') console.log 'Ignored ' + request if options.debug return class fake + else if /node_modules[\\\/]aether[\\\/]/.test parent.id + null # Let it through else if '/' in request and not (request[0] is '.') or request is 'application' + #console.log 'making path', path + '/app/' + request, 'from', path, request, 'with parent', parent request = path + '/app/' + request else if request is 'underscore' request = 'lodash' console.log 'loading ' + request if options.debug originalLoader request, parent, isMain + unhook = () -> m._load = originalLoader hook = () -> diff --git a/headless_client/jQlone.coffee b/headless_client/jQlone.coffee index 12f806bf1..422ac9ed7 100644 --- a/headless_client/jQlone.coffee +++ b/headless_client/jQlone.coffee @@ -9,7 +9,7 @@ module.exports = $ = (input) -> # Non-standard jQuery stuff. Don't use outside of server. $._debug = false -$._server = 'https://codecombat.com' +$._server = 'http://direct.codecombat.com' $._cookies = request.jar() $.when = Deferred.when diff --git a/headless_client/test.js b/headless_client/test.js index 3c92b64e0..860ff8c75 100644 --- a/headless_client/test.js +++ b/headless_client/test.js @@ -1,42 +1,41 @@ module.exports = { - "messageGenerated": 1409357317134, + "messageGenerated": 1423774918949, "sessions": [{ - "sessionID": "539bb9f86e1d92310506f138", + "sessionID": "54dd0fc8f927955405a61620", + "submitDate": "2015-02-12T20:56:02.631Z", "team": "humans", "transpiledCode": { - "mak-fod": {}, - "tharin": { - "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 rjust, debug_coin, use_terrify, player, items, tmp93, tmp94, tmp95, tmp96, tmp97, tmp103, tmp104, tmp105, tmp106, tmp107, 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; for(var __argIndexer = 0; __argIndexer < arguments.length; ++__argIndexer) arguments[__argIndexer] = _aether.createAPIClone(_aether, arguments[__argIndexer]);\n _aether.logStatementStart([{ofs: 0, row: 0, col: 0}, {ofs: 234, row: 9, col: 2}]); rjust = function (s, n, fill) {\n var num_pad_chars, out, i, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8, tmp9, tmp10, tmp11, tmp12, tmp13, tmp14, tmp15, tmp16, tmp17, tmp18, tmp19, tmp20, tmp21, tmp22, tmp23, tmp24, tmp27, tmp28, tmp29, tmp30, tmp31; s = _aether.createAPIClone(_aether, s); n = _aether.createAPIClone(_aether, n); fill = _aether.createAPIClone(_aether, fill); for(var __argIndexer = 0; __argIndexer < arguments.length; ++__argIndexer) arguments[__argIndexer] = _aether.createAPIClone(_aether, arguments[__argIndexer]);\n _aether.logStatementStart([{ofs: 43, row: 1, col: 8}, {ofs: 45, row: 1, col: 10}]); tmp2 = ''; _aether.logStatement([{ofs: 43, row: 1, col: 8}, {ofs: 45, row: 1, col: 10}], _aether._userInfo, false);\n tmp6 = 'Math';\n tmp7 = tmp6 in __global;\n if (tmp7) {\n tmp4 = __global[tmp6];\n } else { _aether.logStatementStart([{ofs: 46, row: 1, col: 11}, {ofs: 50, row: 1, col: 15}]);\n tmp8 = 'ReferenceError';\n tmp9 = __global[tmp8];\n tmp10 = new tmp9('ReferenceError: ' + (tmp6 + ' is not defined'));\n throw tmp10;\n _aether.logStatement([{ofs: 46, row: 1, col: 11}, {ofs: 50, row: 1, col: 15}], _aether._userInfo, false); }\n tmp5 = 'floor';\n tmp12 = s;\n _aether.logStatementStart([{ofs: 59, row: 1, col: 24}, {ofs: 61, row: 1, col: 26}]); tmp13 = 10; _aether.logStatement([{ofs: 59, row: 1, col: 24}, {ofs: 61, row: 1, col: 26}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 57, row: 1, col: 22}, {ofs: 61, row: 1, col: 26}]); tmp11 = tmp12 * tmp13; _aether.logStatement([{ofs: 57, row: 1, col: 22}, {ofs: 61, row: 1, col: 26}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 46, row: 1, col: 11}, {ofs: 62, row: 1, col: 27}]); tmp3 = _aether.createAPIClone(_aether, tmp4[tmp5](_aether.restoreAPIClone(_aether, tmp11))); _aether.logStatement([{ofs: 46, row: 1, col: 11}, {ofs: 62, row: 1, col: 27}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 39, row: 1, col: 4}, {ofs: 63, row: 1, col: 28}]); s = tmp2 + tmp3; _aether.logStatement([{ofs: 39, row: 1, col: 4}, {ofs: 63, row: 1, col: 28}], _aether._userInfo, false);\n tmp14 = n;\n tmp16 = s;\n tmp17 = 'length';\n _aether.logStatementStart([{ofs: 92, row: 2, col: 28}, {ofs: 100, row: 2, col: 36}]); tmp15 = tmp16[tmp17]; _aether.logStatement([{ofs: 92, row: 2, col: 28}, {ofs: 100, row: 2, col: 36}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 68, row: 2, col: 4}, {ofs: 101, row: 2, col: 37}]); num_pad_chars = tmp14 - tmp15; _aether.logStatement([{ofs: 68, row: 2, col: 4}, {ofs: 101, row: 2, col: 37}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 106, row: 3, col: 4}, {ofs: 119, row: 3, col: 17}]); out = ''; _aether.logStatement([{ofs: 106, row: 3, col: 4}, {ofs: 119, row: 3, col: 17}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 128, row: 4, col: 8}, {ofs: 137, row: 4, col: 17}]); i = 0; _aether.logStatement([{ofs: 128, row: 4, col: 8}, {ofs: 137, row: 4, col: 17}], _aether._userInfo, false);\n tmp19 = i;\n tmp20 = num_pad_chars;\n _aether.logStatementStart([{ofs: 139, row: 4, col: 19}, {ofs: 156, row: 4, col: 36}]); tmp18 = tmp19 < tmp20; _aether.logStatement([{ofs: 139, row: 4, col: 19}, {ofs: 156, row: 4, col: 36}], _aether._userInfo, false);\n tmp25: {\n while (tmp18) {\n tmp26: {\n tmp27 = out;\n tmp28 = fill;\n _aether.logStatementStart([{ofs: 173, row: 5, col: 8}, {ofs: 190, row: 5, col: 25}]); out = tmp27 + tmp28; _aether.logStatement([{ofs: 173, row: 5, col: 8}, {ofs: 190, row: 5, col: 25}], _aether._userInfo, false);\n }\n tmp23 = i;\n tmp24 = 1;\n i = tmp23 + tmp24;\n tmp21 = i;\n tmp22 = num_pad_chars;\n _aether.logStatementStart([{ofs: 139, row: 4, col: 19}, {ofs: 156, row: 4, col: 36}]); tmp18 = tmp21 < tmp22; _aether.logStatement([{ofs: 139, row: 4, col: 19}, {ofs: 156, row: 4, col: 36}], _aether._userInfo, false);\n }\n }\n tmp29 = out;\n tmp30 = s;\n _aether.logStatementStart([{ofs: 201, row: 7, col: 4}, {ofs: 215, row: 7, col: 18}]); out = tmp29 + tmp30; _aether.logStatement([{ofs: 201, row: 7, col: 4}, {ofs: 215, row: 7, col: 18}], _aether._userInfo, false);\n tmp31 = out;\n return _aether.restoreAPIClone(_aether, tmp31);\n }; _aether.logStatement([{ofs: 0, row: 0, col: 0}, {ofs: 234, row: 9, col: 2}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 236, row: 11, col: 0}, {ofs: 449, row: 15, col: 2}]); debug_coin = function (dist_and_coin) {\n var dist, coin, 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, 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; dist_and_coin = _aether.createAPIClone(_aether, dist_and_coin); for(var __argIndexer = 0; __argIndexer < arguments.length; ++__argIndexer) arguments[__argIndexer] = _aether.createAPIClone(_aether, arguments[__argIndexer]);\n tmp32 = dist_and_coin;\n _aether.logStatementStart([{ofs: 308, row: 12, col: 29}, {ofs: 309, row: 12, col: 30}]); tmp33 = 0; _aether.logStatement([{ofs: 308, row: 12, col: 29}, {ofs: 309, row: 12, col: 30}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 283, row: 12, col: 4}, {ofs: 311, row: 12, col: 32}]); dist = tmp32[tmp33]; _aether.logStatement([{ofs: 283, row: 12, col: 4}, {ofs: 311, row: 12, col: 32}], _aether._userInfo, false);\n tmp34 = dist_and_coin;\n _aether.logStatementStart([{ofs: 341, row: 13, col: 29}, {ofs: 342, row: 13, col: 30}]); tmp35 = 1; _aether.logStatement([{ofs: 341, row: 13, col: 29}, {ofs: 342, row: 13, col: 30}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 316, row: 13, col: 4}, {ofs: 344, row: 13, col: 32}]); coin = tmp34[tmp35]; _aether.logStatement([{ofs: 316, row: 13, col: 4}, {ofs: 344, row: 13, col: 32}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 356, row: 14, col: 11}, {ofs: 358, row: 14, col: 13}]); tmp51 = ''; _aether.logStatement([{ofs: 356, row: 14, col: 11}, {ofs: 358, row: 14, col: 13}], _aether._userInfo, false);\n tmp55 = 'Math';\n tmp56 = tmp55 in __global;\n if (tmp56) {\n tmp53 = __global[tmp55];\n } else { _aether.logStatementStart([{ofs: 359, row: 14, col: 14}, {ofs: 363, row: 14, col: 18}]);\n tmp57 = 'ReferenceError';\n tmp58 = __global[tmp57];\n tmp59 = new tmp58('ReferenceError: ' + (tmp55 + ' is not defined'));\n throw tmp59;\n _aether.logStatement([{ofs: 359, row: 14, col: 14}, {ofs: 363, row: 14, col: 18}], _aether._userInfo, false); }\n tmp54 = 'floor';\n tmp60 = dist;\n _aether.logStatementStart([{ofs: 359, row: 14, col: 14}, {ofs: 375, row: 14, col: 30}]); tmp52 = _aether.createAPIClone(_aether, tmp53[tmp54](_aether.restoreAPIClone(_aether, tmp60))); _aether.logStatement([{ofs: 359, row: 14, col: 14}, {ofs: 375, row: 14, col: 30}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 356, row: 14, col: 11}, {ofs: 375, row: 14, col: 30}]); tmp49 = tmp51 + tmp52; _aether.logStatement([{ofs: 356, row: 14, col: 11}, {ofs: 375, row: 14, col: 30}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 376, row: 14, col: 31}, {ofs: 379, row: 14, col: 34}]); tmp50 = ','; _aether.logStatement([{ofs: 376, row: 14, col: 31}, {ofs: 379, row: 14, col: 34}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 356, row: 14, col: 11}, {ofs: 379, row: 14, col: 34}]); tmp47 = tmp49 + tmp50; _aether.logStatement([{ofs: 356, row: 14, col: 11}, {ofs: 379, row: 14, col: 34}], _aether._userInfo, false);\n tmp63 = 'Math';\n tmp64 = tmp63 in __global;\n if (tmp64) {\n tmp61 = __global[tmp63];\n } else { _aether.logStatementStart([{ofs: 380, row: 14, col: 35}, {ofs: 384, row: 14, col: 39}]);\n tmp65 = 'ReferenceError';\n tmp66 = __global[tmp65];\n tmp67 = new tmp66('ReferenceError: ' + (tmp63 + ' is not defined'));\n throw tmp67;\n _aether.logStatement([{ofs: 380, row: 14, col: 35}, {ofs: 384, row: 14, col: 39}], _aether._userInfo, false); }\n tmp62 = 'floor';\n tmp71 = coin;\n tmp72 = 'pos';\n _aether.logStatementStart([{ofs: 391, row: 14, col: 46}, {ofs: 399, row: 14, col: 54}]); tmp69 = tmp71[tmp72]; _aether.logStatement([{ofs: 391, row: 14, col: 46}, {ofs: 399, row: 14, col: 54}], _aether._userInfo, false);\n tmp70 = 'x';\n _aether.logStatementStart([{ofs: 391, row: 14, col: 46}, {ofs: 401, row: 14, col: 56}]); tmp68 = tmp69[tmp70]; _aether.logStatement([{ofs: 391, row: 14, col: 46}, {ofs: 401, row: 14, col: 56}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 380, row: 14, col: 35}, {ofs: 402, row: 14, col: 57}]); tmp48 = _aether.createAPIClone(_aether, tmp61[tmp62](_aether.restoreAPIClone(_aether, tmp68))); _aether.logStatement([{ofs: 380, row: 14, col: 35}, {ofs: 402, row: 14, col: 57}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 356, row: 14, col: 11}, {ofs: 402, row: 14, col: 57}]); tmp45 = tmp47 + tmp48; _aether.logStatement([{ofs: 356, row: 14, col: 11}, {ofs: 402, row: 14, col: 57}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 403, row: 14, col: 58}, {ofs: 406, row: 14, col: 61}]); tmp46 = ','; _aether.logStatement([{ofs: 403, row: 14, col: 58}, {ofs: 406, row: 14, col: 61}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 356, row: 14, col: 11}, {ofs: 406, row: 14, col: 61}]); tmp43 = tmp45 + tmp46; _aether.logStatement([{ofs: 356, row: 14, col: 11}, {ofs: 406, row: 14, col: 61}], _aether._userInfo, false);\n tmp75 = 'Math';\n tmp76 = tmp75 in __global;\n if (tmp76) {\n tmp73 = __global[tmp75];\n } else { _aether.logStatementStart([{ofs: 407, row: 14, col: 62}, {ofs: 411, row: 14, col: 66}]);\n tmp77 = 'ReferenceError';\n tmp78 = __global[tmp77];\n tmp79 = new tmp78('ReferenceError: ' + (tmp75 + ' is not defined'));\n throw tmp79;\n _aether.logStatement([{ofs: 407, row: 14, col: 62}, {ofs: 411, row: 14, col: 66}], _aether._userInfo, false); }\n tmp74 = 'floor';\n tmp83 = coin;\n tmp84 = 'pos';\n _aether.logStatementStart([{ofs: 418, row: 14, col: 73}, {ofs: 426, row: 14, col: 81}]); tmp81 = tmp83[tmp84]; _aether.logStatement([{ofs: 418, row: 14, col: 73}, {ofs: 426, row: 14, col: 81}], _aether._userInfo, false);\n tmp82 = 'y';\n _aether.logStatementStart([{ofs: 418, row: 14, col: 73}, {ofs: 428, row: 14, col: 83}]); tmp80 = tmp81[tmp82]; _aether.logStatement([{ofs: 418, row: 14, col: 73}, {ofs: 428, row: 14, col: 83}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 407, row: 14, col: 62}, {ofs: 429, row: 14, col: 84}]); tmp44 = _aether.createAPIClone(_aether, tmp73[tmp74](_aether.restoreAPIClone(_aether, tmp80))); _aether.logStatement([{ofs: 407, row: 14, col: 62}, {ofs: 429, row: 14, col: 84}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 356, row: 14, col: 11}, {ofs: 429, row: 14, col: 84}]); tmp41 = tmp43 + tmp44; _aether.logStatement([{ofs: 356, row: 14, col: 11}, {ofs: 429, row: 14, col: 84}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 430, row: 14, col: 85}, {ofs: 433, row: 14, col: 88}]); tmp42 = ','; _aether.logStatement([{ofs: 430, row: 14, col: 85}, {ofs: 433, row: 14, col: 88}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 356, row: 14, col: 11}, {ofs: 433, row: 14, col: 88}]); tmp39 = tmp41 + tmp42; _aether.logStatement([{ofs: 356, row: 14, col: 11}, {ofs: 433, row: 14, col: 88}], _aether._userInfo, false);\n tmp85 = coin;\n tmp86 = 'id';\n _aether.logStatementStart([{ofs: 434, row: 14, col: 89}, {ofs: 441, row: 14, col: 96}]); tmp40 = tmp85[tmp86]; _aether.logStatement([{ofs: 434, row: 14, col: 89}, {ofs: 441, row: 14, col: 96}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 356, row: 14, col: 11}, {ofs: 441, row: 14, col: 96}]); tmp37 = tmp39 + tmp40; _aether.logStatement([{ofs: 356, row: 14, col: 11}, {ofs: 441, row: 14, col: 96}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 442, row: 14, col: 97}, {ofs: 445, row: 14, col: 100}]); tmp38 = '|'; _aether.logStatement([{ofs: 442, row: 14, col: 97}, {ofs: 445, row: 14, col: 100}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 356, row: 14, col: 11}, {ofs: 445, row: 14, col: 100}]); tmp36 = tmp37 + tmp38; _aether.logStatement([{ofs: 356, row: 14, col: 11}, {ofs: 445, row: 14, col: 100}], _aether._userInfo, false);\n return _aether.restoreAPIClone(_aether, tmp36);\n }; _aether.logStatement([{ofs: 236, row: 11, col: 0}, {ofs: 449, row: 15, col: 2}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 451, row: 17, col: 0}, {ofs: 543, row: 20, col: 2}]); use_terrify = function (player) {\n var tmp87, tmp88, tmp89, tmp90, tmp91, tmp92; player = _aether.createAPIClone(_aether, player); for(var __argIndexer = 0; __argIndexer < arguments.length; ++__argIndexer) arguments[__argIndexer] = _aether.createAPIClone(_aether, arguments[__argIndexer]);\n tmp87 = player;\n tmp88 = 'terrify';\n _aether.logStatementStart([{ofs: 492, row: 18, col: 4}, {ofs: 508, row: 18, col: 20}]); tmp89 = _aether.createAPIClone(_aether, tmp87[tmp88]()); _aether.logStatement([{ofs: 492, row: 18, col: 4}, {ofs: 508, row: 18, col: 20}], _aether._userInfo, false);\n tmp90 = player;\n tmp91 = 'usedTerrify';\n _aether.logStatementStart([{ofs: 514, row: 19, col: 4}, {ofs: 540, row: 19, col: 30}]); tmp92 = true; _aether.logStatement([{ofs: 514, row: 19, col: 4}, {ofs: 540, row: 19, col: 30}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 514, row: 19, col: 4}, {ofs: 539, row: 19, col: 29}]); tmp90[tmp91] = tmp92; _aether.logStatement([{ofs: 514, row: 19, col: 4}, {ofs: 539, row: 19, col: 29}], _aether._userInfo, false);\n return;\n }; _aether.logStatement([{ofs: 451, row: 17, col: 0}, {ofs: 543, row: 20, col: 2}], _aether._userInfo, false);\n player = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp93 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp94 = 'getItems';\n _aether.logStatementStart([{ofs: 633, row: 25, col: 0}, {ofs: 661, row: 25, col: 28}]); items = _aether.createAPIClone(_aether, tmp93[tmp94]()); _aether.logStatement([{ofs: 633, row: 25, col: 0}, {ofs: 661, row: 25, col: 28}], _aether._userInfo, false);\n tmp95 = items;\n tmp96 = 'filter';\n _aether.logStatementStart([{ofs: 683, row: 26, col: 21}, {ofs: 723, row: 26, col: 61}]); tmp97 = function (x) {\n var tmp98, tmp99, tmp100, tmp101, tmp102; x = _aether.createAPIClone(_aether, x); for(var __argIndexer = 0; __argIndexer < arguments.length; ++__argIndexer) arguments[__argIndexer] = _aether.createAPIClone(_aether, arguments[__argIndexer]);\n tmp101 = x;\n tmp102 = 'bountyGold';\n _aether.logStatementStart([{ofs: 704, row: 26, col: 42}, {ofs: 716, row: 26, col: 54}]); tmp99 = tmp101[tmp102]; _aether.logStatement([{ofs: 704, row: 26, col: 42}, {ofs: 716, row: 26, col: 54}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 719, row: 26, col: 57}, {ofs: 720, row: 26, col: 58}]); tmp100 = 2; _aether.logStatement([{ofs: 719, row: 26, col: 57}, {ofs: 720, row: 26, col: 58}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 704, row: 26, col: 42}, {ofs: 720, row: 26, col: 58}]); tmp98 = tmp99 > tmp100; _aether.logStatement([{ofs: 704, row: 26, col: 42}, {ofs: 720, row: 26, col: 58}], _aether._userInfo, false);\n return _aether.restoreAPIClone(_aether, tmp98);\n }; _aether.logStatement([{ofs: 683, row: 26, col: 21}, {ofs: 723, row: 26, col: 61}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 662, row: 26, col: 0}, {ofs: 725, row: 26, col: 63}]); items = _aether.createAPIClone(_aether, tmp95[tmp96](_aether.restoreAPIClone(_aether, tmp97))); _aether.logStatement([{ofs: 662, row: 26, col: 0}, {ofs: 725, row: 26, col: 63}], _aether._userInfo, false);\n tmp105 = items;\n tmp106 = 'map';\n _aether.logStatementStart([{ofs: 744, row: 27, col: 18}, {ofs: 806, row: 27, col: 80}]); tmp107 = function (x) {\n var tmp108, tmp109, tmp110, tmp111, tmp112, tmp113, tmp114, tmp115, tmp116, tmp117; x = _aether.createAPIClone(_aether, x); for(var __argIndexer = 0; __argIndexer < arguments.length; ++__argIndexer) arguments[__argIndexer] = _aether.createAPIClone(_aether, arguments[__argIndexer]);\n tmp111 = rjust;\n tmp115 = player;\n tmp116 = 'distance';\n tmp117 = x;\n _aether.logStatementStart([{ofs: 772, row: 27, col: 46}, {ofs: 790, row: 27, col: 64}]); tmp112 = _aether.createAPIClone(_aether, tmp115[tmp116](_aether.restoreAPIClone(_aether, tmp117))); _aether.logStatement([{ofs: 772, row: 27, col: 46}, {ofs: 790, row: 27, col: 64}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 792, row: 27, col: 66}, {ofs: 793, row: 27, col: 67}]); tmp113 = 7; _aether.logStatement([{ofs: 792, row: 27, col: 66}, {ofs: 793, row: 27, col: 67}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 795, row: 27, col: 69}, {ofs: 798, row: 27, col: 72}]); tmp114 = '0'; _aether.logStatement([{ofs: 795, row: 27, col: 69}, {ofs: 798, row: 27, col: 72}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 766, row: 27, col: 40}, {ofs: 799, row: 27, col: 73}]); tmp109 = _aether.createAPIClone(_aether, tmp111(_aether.restoreAPIClone(_aether, tmp112), _aether.restoreAPIClone(_aether, tmp113), _aether.restoreAPIClone(_aether, tmp114))); _aether.logStatement([{ofs: 766, row: 27, col: 40}, {ofs: 799, row: 27, col: 73}], _aether._userInfo, false);\n tmp110 = x;\n _aether.logStatementStart([{ofs: 765, row: 27, col: 39}, {ofs: 803, row: 27, col: 77}]); tmp108 = [\n tmp109,\n tmp110\n ]; _aether.logStatement([{ofs: 765, row: 27, col: 39}, {ofs: 803, row: 27, col: 77}], _aether._userInfo, false);\n return _aether.restoreAPIClone(_aether, tmp108);\n }; _aether.logStatement([{ofs: 744, row: 27, col: 18}, {ofs: 806, row: 27, col: 80}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 734, row: 27, col: 8}, {ofs: 807, row: 27, col: 81}]); tmp103 = _aether.createAPIClone(_aether, tmp105[tmp106](_aether.restoreAPIClone(_aether, tmp107))); _aether.logStatement([{ofs: 734, row: 27, col: 8}, {ofs: 807, row: 27, col: 81}], _aether._userInfo, false);\n tmp104 = 'sort';\n _aether.logStatementStart([{ofs: 726, row: 27, col: 0}, {ofs: 815, row: 27, col: 89}]); items = _aether.createAPIClone(_aether, tmp103[tmp104]()); _aether.logStatement([{ofs: 726, row: 27, col: 0}, {ofs: 815, row: 27, col: 89}], _aether._userInfo, false);\n tmp118 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp119 = 'say';\n tmp121 = items;\n tmp122 = 'map';\n tmp123 = debug_coin;\n _aether.logStatementStart([{ofs: 825, row: 28, col: 9}, {ofs: 846, row: 28, col: 30}]); tmp120 = _aether.createAPIClone(_aether, tmp121[tmp122](_aether.restoreAPIClone(_aether, tmp123))); _aether.logStatement([{ofs: 825, row: 28, col: 9}, {ofs: 846, row: 28, col: 30}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 816, row: 28, col: 0}, {ofs: 847, row: 28, col: 31}]); tmp124 = _aether.createAPIClone(_aether, tmp118[tmp119](_aether.restoreAPIClone(_aether, tmp120))); _aether.logStatement([{ofs: 816, row: 28, col: 0}, {ofs: 847, row: 28, col: 31}], _aether._userInfo, false);\n tmp127 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp128 = 'usedTerrify';\n _aether.logStatementStart([{ofs: 854, row: 30, col: 4}, {ofs: 870, row: 30, col: 20}]); tmp126 = tmp127[tmp128]; _aether.logStatement([{ofs: 854, row: 30, col: 4}, {ofs: 870, row: 30, col: 20}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 853, row: 30, col: 3}, {ofs: 870, row: 30, col: 20}]); tmp125 = !tmp126; _aether.logStatement([{ofs: 853, row: 30, col: 3}, {ofs: 870, row: 30, col: 20}], _aether._userInfo, false);\n if (tmp125) {\n tmp132 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp133 = 'distance';\n tmp135 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp136 = 'getNearestEnemy';\n _aether.logStatementStart([{ofs: 895, row: 31, col: 21}, {ofs: 917, row: 31, col: 43}]); tmp134 = _aether.createAPIClone(_aether, tmp135[tmp136]()); _aether.logStatement([{ofs: 895, row: 31, col: 21}, {ofs: 917, row: 31, col: 43}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 881, row: 31, col: 7}, {ofs: 918, row: 31, col: 44}]); tmp130 = _aether.createAPIClone(_aether, tmp132[tmp133](_aether.restoreAPIClone(_aether, tmp134))); _aether.logStatement([{ofs: 881, row: 31, col: 7}, {ofs: 918, row: 31, col: 44}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 921, row: 31, col: 47}, {ofs: 922, row: 31, col: 48}]); tmp131 = 5; _aether.logStatement([{ofs: 921, row: 31, col: 47}, {ofs: 922, row: 31, col: 48}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 881, row: 31, col: 7}, {ofs: 922, row: 31, col: 48}]); tmp129 = tmp130 < tmp131; _aether.logStatement([{ofs: 881, row: 31, col: 7}, {ofs: 922, row: 31, col: 48}], _aether._userInfo, false);\n if (tmp129) {\n tmp138 = use_terrify;\n tmp139 = player;\n _aether.logStatementStart([{ofs: 941, row: 32, col: 15}, {ofs: 960, row: 32, col: 34}]); tmp137 = _aether.createAPIClone(_aether, tmp138(_aether.restoreAPIClone(_aether, tmp139))); _aether.logStatement([{ofs: 941, row: 32, col: 15}, {ofs: 960, row: 32, col: 34}], _aether._userInfo, false);\n _aether.logCallEnd(); return _aether.restoreAPIClone(_aether, tmp137);\n } else {\n ;\n }\n tmp143 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp144 = 'now';\n _aether.logStatementStart([{ofs: 975, row: 34, col: 7}, {ofs: 985, row: 34, col: 17}]); tmp141 = _aether.createAPIClone(_aether, tmp143[tmp144]()); _aether.logStatement([{ofs: 975, row: 34, col: 7}, {ofs: 985, row: 34, col: 17}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 988, row: 34, col: 20}, {ofs: 990, row: 34, col: 22}]); tmp142 = 40; _aether.logStatement([{ofs: 988, row: 34, col: 20}, {ofs: 990, row: 34, col: 22}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 975, row: 34, col: 7}, {ofs: 990, row: 34, col: 22}]); tmp140 = tmp141 > tmp142; _aether.logStatement([{ofs: 975, row: 34, col: 7}, {ofs: 990, row: 34, col: 22}], _aether._userInfo, false);\n if (tmp140) {\n tmp146 = use_terrify;\n tmp147 = player;\n _aether.logStatementStart([{ofs: 1009, row: 35, col: 15}, {ofs: 1028, row: 35, col: 34}]); tmp145 = _aether.createAPIClone(_aether, tmp146(_aether.restoreAPIClone(_aether, tmp147))); _aether.logStatement([{ofs: 1009, row: 35, col: 15}, {ofs: 1028, row: 35, col: 34}], _aether._userInfo, false);\n _aether.logCallEnd(); return _aether.restoreAPIClone(_aether, tmp145);\n } else {\n ;\n }\n } else {\n ;\n }\n tmp149 = items;\n _aether.logStatementStart([{ofs: 1049, row: 39, col: 10}, {ofs: 1050, row: 39, col: 11}]); tmp150 = 0; _aether.logStatement([{ofs: 1049, row: 39, col: 10}, {ofs: 1050, row: 39, col: 11}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 1043, row: 39, col: 4}, {ofs: 1051, row: 39, col: 12}]); tmp148 = tmp149[tmp150]; _aether.logStatement([{ofs: 1043, row: 39, col: 4}, {ofs: 1051, row: 39, col: 12}], _aether._userInfo, false);\n if (tmp148) {\n tmp151 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp152 = 'move';\n tmp158 = items;\n _aether.logStatementStart([{ofs: 1075, row: 40, col: 20}, {ofs: 1076, row: 40, col: 21}]); tmp159 = 0; _aether.logStatement([{ofs: 1075, row: 40, col: 20}, {ofs: 1076, row: 40, col: 21}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 1069, row: 40, col: 14}, {ofs: 1077, row: 40, col: 22}]); tmp156 = tmp158[tmp159]; _aether.logStatement([{ofs: 1069, row: 40, col: 14}, {ofs: 1077, row: 40, col: 22}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 1078, row: 40, col: 23}, {ofs: 1079, row: 40, col: 24}]); tmp157 = 1; _aether.logStatement([{ofs: 1078, row: 40, col: 23}, {ofs: 1079, row: 40, col: 24}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 1069, row: 40, col: 14}, {ofs: 1080, row: 40, col: 25}]); tmp154 = tmp156[tmp157]; _aether.logStatement([{ofs: 1069, row: 40, col: 14}, {ofs: 1080, row: 40, col: 25}], _aether._userInfo, false);\n tmp155 = 'pos';\n _aether.logStatementStart([{ofs: 1069, row: 40, col: 14}, {ofs: 1084, row: 40, col: 29}]); tmp153 = tmp154[tmp155]; _aether.logStatement([{ofs: 1069, row: 40, col: 14}, {ofs: 1084, row: 40, col: 29}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 1059, row: 40, col: 4}, {ofs: 1085, row: 40, col: 30}]); tmp160 = _aether.createAPIClone(_aether, tmp151[tmp152](_aether.restoreAPIClone(_aether, tmp153))); _aether.logStatement([{ofs: 1059, row: 40, col: 4}, {ofs: 1085, row: 40, col: 30}], _aether._userInfo, false);\n } else {\n tmp161 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp162 = 'moveXY';\n _aether.logStatementStart([{ofs: 1112, row: 42, col: 16}, {ofs: 1114, row: 42, col: 18}]); tmp163 = 64; _aether.logStatement([{ofs: 1112, row: 42, col: 16}, {ofs: 1114, row: 42, col: 18}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 1116, row: 42, col: 20}, {ofs: 1118, row: 42, col: 22}]); tmp164 = 40; _aether.logStatement([{ofs: 1116, row: 42, col: 20}, {ofs: 1118, row: 42, col: 22}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 1100, row: 42, col: 4}, {ofs: 1119, row: 42, col: 23}]); tmp165 = _aether.createAPIClone(_aether, tmp161[tmp162](_aether.restoreAPIClone(_aether, tmp163), _aether.restoreAPIClone(_aether, tmp164))); _aether.logStatement([{ofs: 1100, row: 42, col: 4}, {ofs: 1119, row: 42, col: 23}], _aether._userInfo, false);\n }\n _aether.logCallEnd(); return;\n };\n tmp0 = 'chooseAction';\n __global[tmp0] = tmp1;\n}(this));" - }, - "coin-generator-9000": {} + "hero-placeholder": { + "plan": "var __interceptThis=(function(){var G=this;return function($this,sandbox){if($this==G){return sandbox;}return $this;};})();\nreturn (function(__global) {\n var tmp0,\n tmp1;\n tmp1 = function() {\n var __argIndexer,\n __gentmp2,\n __resulttmp2,\n _yieldValue,\n self,\n tmp2,\n tmp22,\n tmp3,\n tmp4;\n var $arguments = arguments;\n return $traceurRuntime.generatorWrap(function($ctx) {\n while (true)\n switch ($ctx.state) {\n case 0:\n 'use strict';\n $ctx.state = 20;\n break;\n case 20:\n _aether.logCallStart(_aether._userInfo);\n $ctx.state = 22;\n break;\n case 22:\n ;\n $ctx.state = 24;\n break;\n case 24:\n for (__argIndexer = 0; __argIndexer < $arguments.length; ++__argIndexer)\n $arguments[__argIndexer] = _aether.createAPIClone(_aether, $arguments[__argIndexer]);\n $ctx.state = 26;\n break;\n case 26:\n self = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n $ctx.state = 28;\n break;\n case 28:\n tmp3 = function() {\n var __argIndexer,\n __yieldCount0,\n _yieldValue,\n enemy,\n tmp10,\n tmp11,\n tmp12,\n tmp13,\n tmp14,\n tmp15,\n tmp16,\n tmp17,\n tmp18,\n tmp19,\n tmp20,\n tmp21,\n tmp5,\n tmp8,\n tmp9;\n var $arguments = arguments;\n return $traceurRuntime.generatorWrap(function($ctx) {\n while (true)\n switch ($ctx.state) {\n case 0:\n ;\n $ctx.state = 129;\n break;\n case 129:\n for (__argIndexer = 0; __argIndexer < $arguments.length; ++__argIndexer)\n $arguments[__argIndexer] = _aether.createAPIClone(_aether, $arguments[__argIndexer]);\n $ctx.state = 131;\n break;\n case 131:\n _aether.logStatementStart([{\n ofs: 42,\n row: 2,\n col: 6\n }, {\n ofs: 46,\n row: 2,\n col: 10\n }]);\n $ctx.state = 133;\n break;\n case 133:\n tmp5 = true;\n $ctx.state = 135;\n break;\n case 135:\n _aether.logStatement([{\n ofs: 42,\n row: 2,\n col: 6\n }, {\n ofs: 46,\n row: 2,\n col: 10\n }], _aether._userInfo, false);\n $ctx.state = 137;\n break;\n case 137:\n if (tmp5) {\n $ctx.state = 115;\n break;\n } else {\n $ctx.state = 3;\n break;\n }\n case 115:\n __yieldCount0 = 0;\n $ctx.state = 116;\n break;\n case 116:\n tmp8 = self;\n $ctx.state = 85;\n break;\n case 85:\n tmp9 = 'findNearestEnemy';\n $ctx.state = 87;\n break;\n case 87:\n _aether.logStatementStart([{\n ofs: 157,\n row: 5,\n col: 4\n }, {\n ofs: 162,\n row: 5,\n col: 9\n }]);\n $ctx.state = 89;\n break;\n case 89:\n enemy = _aether.convertToNativeType(_aether.createAPIClone(_aether, tmp8[tmp9]()));\n $ctx.state = 91;\n break;\n case 91:\n _aether.logStatement([{\n ofs: 157,\n row: 5,\n col: 4\n }, {\n ofs: 162,\n row: 5,\n col: 9\n }], _aether._userInfo, false);\n $ctx.state = 93;\n break;\n case 93:\n if (_aether._shouldYield) {\n $ctx.state = 11;\n break;\n } else {\n $ctx.state = 18;\n break;\n }\n case 11:\n _yieldValue = _aether._shouldYield;\n $ctx.state = 12;\n break;\n case 12:\n _aether._shouldYield = false;\n $ctx.state = 14;\n break;\n case 14:\n if (this.onAetherYield) {\n this.onAetherYield(_yieldValue);\n }\n $ctx.state = 16;\n break;\n case 16:\n $ctx.state = 8;\n return _yieldValue;\n case 8:\n if ($ctx.action === 'throw') {\n $ctx.action = 'next';\n throw $ctx.sent;\n }\n $ctx.state = 10;\n break;\n case 10:\n if (typeof __yieldCount0 !== 'undefined' && __yieldCount0 !== null) {\n __yieldCount0++;\n }\n $ctx.state = 18;\n break;\n case 18:\n tmp11 = self;\n $ctx.state = 95;\n break;\n case 95:\n tmp12 = 'isReady';\n $ctx.state = 97;\n break;\n case 97:\n _aether.logStatementStart([{\n ofs: 214,\n row: 7,\n col: 20\n }, {\n ofs: 222,\n row: 7,\n col: 28\n }]);\n $ctx.state = 99;\n break;\n case 99:\n tmp13 = 'cleave';\n $ctx.state = 101;\n break;\n case 101:\n _aether.logStatement([{\n ofs: 214,\n row: 7,\n col: 20\n }, {\n ofs: 222,\n row: 7,\n col: 28\n }], _aether._userInfo, false);\n $ctx.state = 103;\n break;\n case 103:\n _aether.logStatementStart([{\n ofs: 201,\n row: 7,\n col: 7\n }, {\n ofs: 223,\n row: 7,\n col: 29\n }]);\n $ctx.state = 105;\n break;\n case 105:\n tmp10 = _aether.convertToNativeType(_aether.createAPIClone(_aether, tmp11[tmp12](_aether.restoreAPIClone(_aether, tmp13))));\n $ctx.state = 107;\n break;\n case 107:\n _aether.logStatement([{\n ofs: 201,\n row: 7,\n col: 7\n }, {\n ofs: 223,\n row: 7,\n col: 29\n }], _aether._userInfo, false);\n $ctx.state = 109;\n break;\n case 109:\n if (_aether._shouldYield) {\n $ctx.state = 24;\n break;\n } else {\n $ctx.state = 31;\n break;\n }\n case 24:\n _yieldValue = _aether._shouldYield;\n $ctx.state = 25;\n break;\n case 25:\n _aether._shouldYield = false;\n $ctx.state = 27;\n break;\n case 27:\n if (this.onAetherYield) {\n this.onAetherYield(_yieldValue);\n }\n $ctx.state = 29;\n break;\n case 29:\n $ctx.state = 21;\n return _yieldValue;\n case 21:\n if ($ctx.action === 'throw') {\n $ctx.action = 'next';\n throw $ctx.sent;\n }\n $ctx.state = 23;\n break;\n case 23:\n if (typeof __yieldCount0 !== 'undefined' && __yieldCount0 !== null) {\n __yieldCount0++;\n }\n $ctx.state = 31;\n break;\n case 31:\n if (tmp10) {\n $ctx.state = 46;\n break;\n } else {\n $ctx.state = 71;\n break;\n }\n case 46:\n tmp14 = self;\n $ctx.state = 47;\n break;\n case 47:\n tmp15 = 'cleave';\n $ctx.state = 49;\n break;\n case 49:\n tmp16 = enemy;\n $ctx.state = 51;\n break;\n case 51:\n _aether.logStatementStart([{\n ofs: 242,\n row: 9,\n col: 8\n }, {\n ofs: 260,\n row: 9,\n col: 26\n }]);\n $ctx.state = 53;\n break;\n case 53:\n tmp17 = _aether.convertToNativeType(_aether.createAPIClone(_aether, tmp14[tmp15](_aether.restoreAPIClone(_aether, tmp16))));\n $ctx.state = 55;\n break;\n case 55:\n _aether.logStatement([{\n ofs: 242,\n row: 9,\n col: 8\n }, {\n ofs: 260,\n row: 9,\n col: 26\n }], _aether._userInfo, false);\n $ctx.state = 57;\n break;\n case 57:\n if (_aether._shouldYield) {\n $ctx.state = 37;\n break;\n } else {\n $ctx.state = 6;\n break;\n }\n case 37:\n _yieldValue = _aether._shouldYield;\n $ctx.state = 38;\n break;\n case 38:\n _aether._shouldYield = false;\n $ctx.state = 40;\n break;\n case 40:\n if (this.onAetherYield) {\n this.onAetherYield(_yieldValue);\n }\n $ctx.state = 42;\n break;\n case 42:\n $ctx.state = 34;\n return _yieldValue;\n case 34:\n if ($ctx.action === 'throw') {\n $ctx.action = 'next';\n throw $ctx.sent;\n }\n $ctx.state = 36;\n break;\n case 36:\n if (typeof __yieldCount0 !== 'undefined' && __yieldCount0 !== null) {\n __yieldCount0++;\n }\n $ctx.state = 6;\n break;\n case 71:\n tmp18 = self;\n $ctx.state = 72;\n break;\n case 72:\n tmp19 = 'attack';\n $ctx.state = 74;\n break;\n case 74:\n tmp20 = enemy;\n $ctx.state = 76;\n break;\n case 76:\n _aether.logStatementStart([{\n ofs: 280,\n row: 12,\n col: 8\n }, {\n ofs: 298,\n row: 12,\n col: 26\n }]);\n $ctx.state = 78;\n break;\n case 78:\n tmp21 = _aether.convertToNativeType(_aether.createAPIClone(_aether, tmp18[tmp19](_aether.restoreAPIClone(_aether, tmp20))));\n $ctx.state = 80;\n break;\n case 80:\n _aether.logStatement([{\n ofs: 280,\n row: 12,\n col: 8\n }, {\n ofs: 298,\n row: 12,\n col: 26\n }], _aether._userInfo, false);\n $ctx.state = 82;\n break;\n case 82:\n if (_aether._shouldYield) {\n $ctx.state = 62;\n break;\n } else {\n $ctx.state = 6;\n break;\n }\n case 62:\n _yieldValue = _aether._shouldYield;\n $ctx.state = 63;\n break;\n case 63:\n _aether._shouldYield = false;\n $ctx.state = 65;\n break;\n case 65:\n if (this.onAetherYield) {\n this.onAetherYield(_yieldValue);\n }\n $ctx.state = 67;\n break;\n case 67:\n $ctx.state = 59;\n return _yieldValue;\n case 59:\n if ($ctx.action === 'throw') {\n $ctx.action = 'next';\n throw $ctx.sent;\n }\n $ctx.state = 61;\n break;\n case 61:\n if (typeof __yieldCount0 !== 'undefined' && __yieldCount0 !== null) {\n __yieldCount0++;\n }\n $ctx.state = 6;\n break;\n case 6:\n _aether.logStatementStart([{\n ofs: 42,\n row: 2,\n col: 6\n }, {\n ofs: 46,\n row: 2,\n col: 10\n }]);\n $ctx.state = 118;\n break;\n case 118:\n tmp5 = true;\n $ctx.state = 120;\n break;\n case 120:\n _aether.logStatement([{\n ofs: 42,\n row: 2,\n col: 6\n }, {\n ofs: 46,\n row: 2,\n col: 10\n }], _aether._userInfo, false);\n $ctx.state = 122;\n break;\n case 122:\n if (this.onAetherYield) {\n this.onAetherYield('simple loop');\n }\n $ctx.state = 124;\n break;\n case 124:\n if (__yieldCount0 === 0) {\n $ctx.state = 110;\n break;\n } else {\n $ctx.state = 137;\n break;\n }\n case 110:\n $ctx.state = 111;\n return 'simple loop...';\n case 111:\n if ($ctx.action === 'throw') {\n $ctx.action = 'next';\n throw $ctx.sent;\n }\n $ctx.state = 137;\n break;\n case 3:\n $ctx.state = -2;\n break;\n case -2:\n return $ctx;\n case -3:\n throw $ctx.storedException;\n default:\n throw 'traceur compiler bug: invalid state in state machine: ' + $ctx.state;\n }\n }, this);\n };\n $ctx.state = 30;\n break;\n case 30:\n tmp4 = 'call';\n $ctx.state = 32;\n break;\n case 32:\n tmp22 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n $ctx.state = 34;\n break;\n case 34:\n __gentmp2 = _aether.convertToNativeType(_aether.createAPIClone(_aether, tmp3[tmp4](_aether.restoreAPIClone(_aether, tmp22))));\n $ctx.state = 36;\n break;\n case 36:\n if (true) {\n $ctx.state = 5;\n break;\n } else {\n $ctx.state = 16;\n break;\n }\n case 5:\n __resulttmp2 = __gentmp2.next();\n $ctx.state = 6;\n break;\n case 6:\n if (__resulttmp2.done) {\n $ctx.state = 9;\n break;\n } else {\n $ctx.state = 8;\n break;\n }\n case 9:\n tmp2 = __resulttmp2.value;\n $ctx.state = 16;\n break;\n case 8:\n _yieldValue = __resulttmp2.value;\n $ctx.state = 13;\n break;\n case 13:\n if (this.onAetherYield) {\n this.onAetherYield(_yieldValue);\n }\n $ctx.state = 15;\n break;\n case 15:\n $ctx.state = 2;\n return _yieldValue;\n case 2:\n if ($ctx.action === 'throw') {\n $ctx.action = 'next';\n throw $ctx.sent;\n }\n $ctx.state = 36;\n break;\n case 16:\n ;\n $ctx.state = 38;\n break;\n case 38:\n _aether.logCallEnd();\n $ctx.state = 40;\n break;\n case 40:\n $ctx.returnValue = _aether.restoreAPIClone(_aether, tmp2);\n $ctx.state = -2;\n break;\n case -2:\n return $ctx;\n case -3:\n throw $ctx.storedException;\n default:\n throw 'traceur compiler bug: invalid state in state machine: ' + $ctx.state;\n }\n }, this);\n };\n tmp0 = 'plan';\n __global[tmp0] = tmp1;\n}(this));\n" + } }, - "submittedCodeLanguage": "javascript", + "submittedCodeLanguage": "python", "teamSpells": { - "common": ["coin-generator-9000/chooseAction"], - "humans": ["tharin/chooseAction"], - "ogres": ["mak-fod/chooseAction"] + "humans": ["hero-placeholder/plan"], + "ogres": ["hero-placeholder-1/plan"] }, - "levelID": "gold-rush", - "creatorName": "s-krackas", - "creator": "539b4c9cb4c4f93805452aba", - "totalScore": 36.389248829587835 + "levelID": "dueling-grounds", + "creator": "54d520a09136715505d15297", + "totalScore": 40.47590719392207 }, { - "sessionID": "53fdc33abfe0d7f308a6906a", + "sessionID": "548881e93ab3c0ba091631b0", + "submitDate": "2014-12-10T17:27:26.031Z", "team": "ogres", "transpiledCode": { - "mak-fod": { - "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 items, saystring, currdistance, currindex, i, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8, tmp9, tmp10, tmp11, tmp12, tmp13, tmp14, tmp15, 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, tmp62, tmp63, tmp64; 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 = 'getItems';\n _aether.logStatementStart([{ofs: 173, row: 4, col: 0}, {ofs: 201, row: 4, col: 28}]); items = _aether.convertToNativeType(_aether.createAPIClone(_aether, tmp2[tmp3]())); _aether.logStatement([{ofs: 173, row: 4, col: 0}, {ofs: 201, row: 4, col: 28}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 202, row: 5, col: 0}, {ofs: 221, row: 5, col: 19}]); saystring = ''; _aether.logStatement([{ofs: 202, row: 5, col: 0}, {ofs: 221, row: 5, col: 19}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 242, row: 6, col: 20}, {ofs: 243, row: 6, col: 21}]); tmp4 = 1; _aether.logStatement([{ofs: 242, row: 6, col: 20}, {ofs: 243, row: 6, col: 21}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 222, row: 6, col: 0}, {ofs: 244, row: 6, col: 22}]); currdistance = -tmp4; _aether.logStatement([{ofs: 222, row: 6, col: 0}, {ofs: 244, row: 6, col: 22}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 245, row: 7, col: 0}, {ofs: 263, row: 7, col: 18}]); currindex = 0; _aether.logStatement([{ofs: 245, row: 7, col: 0}, {ofs: 263, row: 7, col: 18}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 268, row: 8, col: 4}, {ofs: 277, row: 8, col: 13}]); i = 0; _aether.logStatement([{ofs: 268, row: 8, col: 4}, {ofs: 277, row: 8, col: 13}], _aether._userInfo, false);\n tmp6 = i;\n tmp8 = items;\n tmp9 = 'length';\n _aether.logStatementStart([{ofs: 283, row: 8, col: 19}, {ofs: 295, row: 8, col: 31}]); tmp7 = tmp8[tmp9]; _aether.logStatement([{ofs: 283, row: 8, col: 19}, {ofs: 295, row: 8, col: 31}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 279, row: 8, col: 15}, {ofs: 295, row: 8, col: 31}]); tmp5 = tmp6 < tmp7; _aether.logStatement([{ofs: 279, row: 8, col: 15}, {ofs: 295, row: 8, col: 31}], _aether._userInfo, false);\n tmp16: {\n while (tmp5) {\n tmp17: {\n tmp19 = i;\n _aether.logStatementStart([{ofs: 325, row: 9, col: 21}, {ofs: 327, row: 9, col: 23}]); tmp20 = ''; _aether.logStatement([{ofs: 325, row: 9, col: 21}, {ofs: 327, row: 9, col: 23}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 308, row: 9, col: 4}, {ofs: 328, row: 9, col: 24}]); tmp18 = tmp19 + tmp20; _aether.logStatement([{ofs: 308, row: 9, col: 4}, {ofs: 328, row: 9, col: 24}], _aether._userInfo, false);\n tmp21 = saystring;\n tmp22 = tmp18;\n saystring = tmp21 + tmp22;\n tmp24 = currdistance;\n _aether.logStatementStart([{ofs: 353, row: 10, col: 24}, {ofs: 354, row: 10, col: 25}]); tmp26 = 1; _aether.logStatement([{ofs: 353, row: 10, col: 24}, {ofs: 354, row: 10, col: 25}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 352, row: 10, col: 23}, {ofs: 354, row: 10, col: 25}]); tmp25 = -tmp26; _aether.logStatement([{ofs: 352, row: 10, col: 23}, {ofs: 354, row: 10, col: 25}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 336, row: 10, col: 7}, {ofs: 354, row: 10, col: 25}]); tmp23 = tmp24 == tmp25; _aether.logStatement([{ofs: 336, row: 10, col: 7}, {ofs: 354, row: 10, col: 25}], _aether._userInfo, false);\n if (tmp23) {\n tmp27 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp28 = 'distance';\n tmp30 = items;\n tmp31 = i;\n _aether.logStatementStart([{ofs: 395, row: 11, col: 37}, {ofs: 403, row: 11, col: 45}]); tmp29 = tmp30[tmp31]; _aether.logStatement([{ofs: 395, row: 11, col: 37}, {ofs: 403, row: 11, col: 45}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 366, row: 11, col: 8}, {ofs: 405, row: 11, col: 47}]); currdistance = _aether.convertToNativeType(_aether.createAPIClone(_aether, tmp27[tmp28](_aether.restoreAPIClone(_aether, tmp29)))); _aether.logStatement([{ofs: 366, row: 11, col: 8}, {ofs: 405, row: 11, col: 47}], _aether._userInfo, false);\n } else {\n ;\n }\n tmp35 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp36 = 'distance';\n tmp38 = items;\n tmp39 = i;\n _aether.logStatementStart([{ofs: 433, row: 13, col: 21}, {ofs: 441, row: 13, col: 29}]); tmp37 = tmp38[tmp39]; _aether.logStatement([{ofs: 433, row: 13, col: 21}, {ofs: 441, row: 13, col: 29}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 419, row: 13, col: 7}, {ofs: 442, row: 13, col: 30}]); tmp33 = _aether.convertToNativeType(_aether.createAPIClone(_aether, tmp35[tmp36](_aether.restoreAPIClone(_aether, tmp37)))); _aether.logStatement([{ofs: 419, row: 13, col: 7}, {ofs: 442, row: 13, col: 30}], _aether._userInfo, false);\n tmp34 = currdistance;\n _aether.logStatementStart([{ofs: 419, row: 13, col: 7}, {ofs: 457, row: 13, col: 45}]); tmp32 = tmp33 < tmp34; _aether.logStatement([{ofs: 419, row: 13, col: 7}, {ofs: 457, row: 13, col: 45}], _aether._userInfo, false);\n if (tmp32) {\n tmp40 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp41 = 'distance';\n tmp43 = items;\n tmp44 = i;\n _aether.logStatementStart([{ofs: 498, row: 14, col: 37}, {ofs: 506, row: 14, col: 45}]); tmp42 = tmp43[tmp44]; _aether.logStatement([{ofs: 498, row: 14, col: 37}, {ofs: 506, row: 14, col: 45}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 469, row: 14, col: 8}, {ofs: 508, row: 14, col: 47}]); currdistance = _aether.convertToNativeType(_aether.createAPIClone(_aether, tmp40[tmp41](_aether.restoreAPIClone(_aether, tmp42)))); _aether.logStatement([{ofs: 469, row: 14, col: 8}, {ofs: 508, row: 14, col: 47}], _aether._userInfo, false);\n currindex = i;\n } else {\n ;\n }\n }\n tmp14 = i;\n tmp15 = 1;\n i = tmp14 + tmp15;\n tmp10 = i;\n tmp12 = items;\n tmp13 = 'length';\n _aether.logStatementStart([{ofs: 283, row: 8, col: 19}, {ofs: 295, row: 8, col: 31}]); tmp11 = tmp12[tmp13]; _aether.logStatement([{ofs: 283, row: 8, col: 19}, {ofs: 295, row: 8, col: 31}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 279, row: 8, col: 15}, {ofs: 295, row: 8, col: 31}]); tmp5 = tmp10 < tmp11; _aether.logStatement([{ofs: 279, row: 8, col: 15}, {ofs: 295, row: 8, col: 31}], _aether._userInfo, false);\n }\n }\n tmp45 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp46 = 'say';\n tmp47 = currindex;\n _aether.logStatementStart([{ofs: 546, row: 20, col: 0}, {ofs: 565, row: 20, col: 19}]); tmp48 = _aether.convertToNativeType(_aether.createAPIClone(_aether, tmp45[tmp46](_aether.restoreAPIClone(_aether, tmp47)))); _aether.logStatement([{ofs: 546, row: 20, col: 0}, {ofs: 565, row: 20, col: 19}], _aether._userInfo, false);\n tmp50 = items;\n tmp51 = currindex;\n _aether.logStatementStart([{ofs: 571, row: 21, col: 4}, {ofs: 587, row: 21, col: 20}]); tmp49 = tmp50[tmp51]; _aether.logStatement([{ofs: 571, row: 21, col: 4}, {ofs: 587, row: 21, col: 20}], _aether._userInfo, false);\n if (tmp49) {\n tmp52 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp53 = 'move';\n tmp57 = items;\n tmp58 = currindex;\n _aether.logStatementStart([{ofs: 605, row: 22, col: 14}, {ofs: 621, row: 22, col: 30}]); tmp55 = tmp57[tmp58]; _aether.logStatement([{ofs: 605, row: 22, col: 14}, {ofs: 621, row: 22, col: 30}], _aether._userInfo, false);\n tmp56 = 'pos';\n _aether.logStatementStart([{ofs: 605, row: 22, col: 14}, {ofs: 625, row: 22, col: 34}]); tmp54 = tmp55[tmp56]; _aether.logStatement([{ofs: 605, row: 22, col: 14}, {ofs: 625, row: 22, col: 34}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 595, row: 22, col: 4}, {ofs: 626, row: 22, col: 35}]); tmp59 = _aether.convertToNativeType(_aether.createAPIClone(_aether, tmp52[tmp53](_aether.restoreAPIClone(_aether, tmp54)))); _aether.logStatement([{ofs: 595, row: 22, col: 4}, {ofs: 626, row: 22, col: 35}], _aether._userInfo, false);\n } else {\n tmp60 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n tmp61 = 'moveXY';\n _aether.logStatementStart([{ofs: 653, row: 24, col: 16}, {ofs: 655, row: 24, col: 18}]); tmp62 = 18; _aether.logStatement([{ofs: 653, row: 24, col: 16}, {ofs: 655, row: 24, col: 18}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 657, row: 24, col: 20}, {ofs: 659, row: 24, col: 22}]); tmp63 = 36; _aether.logStatement([{ofs: 657, row: 24, col: 20}, {ofs: 659, row: 24, col: 22}], _aether._userInfo, false);\n _aether.logStatementStart([{ofs: 641, row: 24, col: 4}, {ofs: 660, row: 24, col: 23}]); tmp64 = _aether.convertToNativeType(_aether.createAPIClone(_aether, tmp60[tmp61](_aether.restoreAPIClone(_aether, tmp62), _aether.restoreAPIClone(_aether, tmp63)))); _aether.logStatement([{ofs: 641, row: 24, col: 4}, {ofs: 660, row: 24, col: 23}], _aether._userInfo, false);\n }\n _aether.logCallEnd(); return;\n };\n tmp0 = 'chooseAction';\n __global[tmp0] = tmp1;\n}(this));" + "hero-placeholder-1": { + "plan": "var __interceptThis=(function(){var G=this;return function($this,sandbox){if($this==G){return sandbox;}return $this;};})();\nreturn (function(__global) {\n var tmp0,\n tmp1;\n tmp1 = function() {\n var __argIndexer,\n __yieldCount0,\n _yieldValue,\n tmp10,\n tmp11,\n tmp12,\n tmp13,\n tmp14,\n tmp15,\n tmp16,\n tmp17,\n tmp18,\n tmp19,\n tmp2,\n tmp20,\n tmp21,\n tmp22,\n tmp23,\n tmp24,\n tmp25,\n tmp26,\n tmp27,\n tmp28,\n tmp29,\n tmp30,\n tmp31,\n tmp32,\n tmp33,\n tmp34,\n tmp35,\n tmp36,\n tmp5,\n tmp6,\n tmp7,\n tmp8,\n tmp9;\n var $arguments = arguments;\n return $traceurRuntime.generatorWrap(function($ctx) {\n while (true)\n switch ($ctx.state) {\n case 0:\n 'use strict';\n $ctx.state = 158;\n break;\n case 158:\n _aether.logCallStart(_aether._userInfo);\n $ctx.state = 160;\n break;\n case 160:\n ;\n $ctx.state = 162;\n break;\n case 162:\n for (__argIndexer = 0; __argIndexer < $arguments.length; ++__argIndexer)\n $arguments[__argIndexer] = _aether.createAPIClone(_aether, $arguments[__argIndexer]);\n $ctx.state = 164;\n break;\n case 164:\n _aether.logStatementStart([{\n ofs: 44,\n row: 2,\n col: 7\n }, {\n ofs: 48,\n row: 2,\n col: 11\n }]);\n $ctx.state = 166;\n break;\n case 166:\n tmp2 = true;\n $ctx.state = 168;\n break;\n case 168:\n _aether.logStatement([{\n ofs: 44,\n row: 2,\n col: 7\n }, {\n ofs: 48,\n row: 2,\n col: 11\n }], _aether._userInfo, false);\n $ctx.state = 170;\n break;\n case 170:\n if (tmp2) {\n $ctx.state = 144;\n break;\n } else {\n $ctx.state = 3;\n break;\n }\n case 144:\n __yieldCount0 = 0;\n $ctx.state = 145;\n break;\n case 145:\n tmp7 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n $ctx.state = 112;\n break;\n case 112:\n tmp8 = 'findNearestEnemy';\n $ctx.state = 114;\n break;\n case 114:\n _aether.logStatementStart([{\n ofs: 152,\n row: 5,\n col: 4\n }, {\n ofs: 184,\n row: 5,\n col: 36\n }]);\n $ctx.state = 116;\n break;\n case 116:\n tmp6 = _aether.convertToNativeType(_aether.createAPIClone(_aether, tmp7[tmp8]()));\n $ctx.state = 118;\n break;\n case 118:\n _aether.logStatement([{\n ofs: 152,\n row: 5,\n col: 4\n }, {\n ofs: 184,\n row: 5,\n col: 36\n }], _aether._userInfo, false);\n $ctx.state = 120;\n break;\n case 120:\n if (_aether._shouldYield) {\n $ctx.state = 11;\n break;\n } else {\n $ctx.state = 18;\n break;\n }\n case 11:\n _yieldValue = _aether._shouldYield;\n $ctx.state = 12;\n break;\n case 12:\n _aether._shouldYield = false;\n $ctx.state = 14;\n break;\n case 14:\n if (this.onAetherYield) {\n this.onAetherYield(_yieldValue);\n }\n $ctx.state = 16;\n break;\n case 16:\n $ctx.state = 8;\n return _yieldValue;\n case 8:\n if ($ctx.action === 'throw') {\n $ctx.action = 'next';\n throw $ctx.sent;\n }\n $ctx.state = 10;\n break;\n case 10:\n if (typeof __yieldCount0 !== 'undefined' && __yieldCount0 !== null) {\n __yieldCount0++;\n }\n $ctx.state = 18;\n break;\n case 18:\n _aether.logStatementStart([{\n ofs: 152,\n row: 5,\n col: 4\n }, {\n ofs: 183,\n row: 5,\n col: 35\n }]);\n $ctx.state = 122;\n break;\n case 122:\n tmp5 = 'enemy';\n $ctx.state = 124;\n break;\n case 124:\n _aether.logStatement([{\n ofs: 152,\n row: 5,\n col: 4\n }, {\n ofs: 183,\n row: 5,\n col: 35\n }], _aether._userInfo, false);\n $ctx.state = 126;\n break;\n case 126:\n _aether.logStatementStart([{\n ofs: 152,\n row: 5,\n col: 4\n }, {\n ofs: 183,\n row: 5,\n col: 35\n }]);\n $ctx.state = 128;\n break;\n case 128:\n __global[tmp5] = tmp6;\n $ctx.state = 130;\n break;\n case 130:\n _aether.logStatement([{\n ofs: 152,\n row: 5,\n col: 4\n }, {\n ofs: 183,\n row: 5,\n col: 35\n }], _aether._userInfo, false);\n $ctx.state = 132;\n break;\n case 132:\n tmp10 = 'enemy';\n $ctx.state = 134;\n break;\n case 134:\n tmp11 = tmp10 in __global;\n $ctx.state = 136;\n break;\n case 136:\n if (tmp11) {\n tmp9 = __global[tmp10];\n } else {\n _aether.logStatementStart([{\n ofs: 192,\n row: 6,\n col: 7\n }, {\n ofs: 197,\n row: 6,\n col: 12\n }]);\n tmp12 = 'ReferenceError';\n tmp13 = __global[tmp12];\n tmp14 = new tmp13('ReferenceError: ' + (tmp10 + ' is not defined'));\n throw tmp14;\n _aether.logStatement([{\n ofs: 192,\n row: 6,\n col: 7\n }, {\n ofs: 197,\n row: 6,\n col: 12\n }], _aether._userInfo, false);\n }\n $ctx.state = 138;\n break;\n case 138:\n if (tmp9) {\n $ctx.state = 92;\n break;\n } else {\n $ctx.state = 108;\n break;\n }\n case 92:\n tmp16 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n $ctx.state = 93;\n break;\n case 93:\n tmp17 = 'isReady';\n $ctx.state = 95;\n break;\n case 95:\n _aether.logStatementStart([{\n ofs: 224,\n row: 7,\n col: 24\n }, {\n ofs: 232,\n row: 7,\n col: 32\n }]);\n $ctx.state = 97;\n break;\n case 97:\n tmp18 = 'cleave';\n $ctx.state = 99;\n break;\n case 99:\n _aether.logStatement([{\n ofs: 224,\n row: 7,\n col: 24\n }, {\n ofs: 232,\n row: 7,\n col: 32\n }], _aether._userInfo, false);\n $ctx.state = 101;\n break;\n case 101:\n _aether.logStatementStart([{\n ofs: 211,\n row: 7,\n col: 11\n }, {\n ofs: 233,\n row: 7,\n col: 33\n }]);\n $ctx.state = 103;\n break;\n case 103:\n tmp15 = _aether.convertToNativeType(_aether.createAPIClone(_aether, tmp16[tmp17](_aether.restoreAPIClone(_aether, tmp18))));\n $ctx.state = 105;\n break;\n case 105:\n _aether.logStatement([{\n ofs: 211,\n row: 7,\n col: 11\n }, {\n ofs: 233,\n row: 7,\n col: 33\n }], _aether._userInfo, false);\n $ctx.state = 107;\n break;\n case 107:\n if (_aether._shouldYield) {\n $ctx.state = 24;\n break;\n } else {\n $ctx.state = 31;\n break;\n }\n case 24:\n _yieldValue = _aether._shouldYield;\n $ctx.state = 25;\n break;\n case 25:\n _aether._shouldYield = false;\n $ctx.state = 27;\n break;\n case 27:\n if (this.onAetherYield) {\n this.onAetherYield(_yieldValue);\n }\n $ctx.state = 29;\n break;\n case 29:\n $ctx.state = 21;\n return _yieldValue;\n case 21:\n if ($ctx.action === 'throw') {\n $ctx.action = 'next';\n throw $ctx.sent;\n }\n $ctx.state = 23;\n break;\n case 23:\n if (typeof __yieldCount0 !== 'undefined' && __yieldCount0 !== null) {\n __yieldCount0++;\n }\n $ctx.state = 31;\n break;\n case 31:\n if (tmp15) {\n $ctx.state = 46;\n break;\n } else {\n $ctx.state = 75;\n break;\n }\n case 46:\n tmp19 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n $ctx.state = 47;\n break;\n case 47:\n tmp20 = 'cleave';\n $ctx.state = 49;\n break;\n case 49:\n tmp22 = 'enemy';\n $ctx.state = 51;\n break;\n case 51:\n tmp23 = tmp22 in __global;\n $ctx.state = 53;\n break;\n case 53:\n if (tmp23) {\n tmp21 = __global[tmp22];\n } else {\n _aether.logStatementStart([{\n ofs: 260,\n row: 8,\n col: 24\n }, {\n ofs: 265,\n row: 8,\n col: 29\n }]);\n tmp24 = 'ReferenceError';\n tmp25 = __global[tmp24];\n tmp26 = new tmp25('ReferenceError: ' + (tmp22 + ' is not defined'));\n throw tmp26;\n _aether.logStatement([{\n ofs: 260,\n row: 8,\n col: 24\n }, {\n ofs: 265,\n row: 8,\n col: 29\n }], _aether._userInfo, false);\n }\n $ctx.state = 55;\n break;\n case 55:\n _aether.logStatementStart([{\n ofs: 248,\n row: 8,\n col: 12\n }, {\n ofs: 266,\n row: 8,\n col: 30\n }]);\n $ctx.state = 57;\n break;\n case 57:\n tmp27 = _aether.convertToNativeType(_aether.createAPIClone(_aether, tmp19[tmp20](_aether.restoreAPIClone(_aether, tmp21))));\n $ctx.state = 59;\n break;\n case 59:\n _aether.logStatement([{\n ofs: 248,\n row: 8,\n col: 12\n }, {\n ofs: 266,\n row: 8,\n col: 30\n }], _aether._userInfo, false);\n $ctx.state = 61;\n break;\n case 61:\n if (_aether._shouldYield) {\n $ctx.state = 37;\n break;\n } else {\n $ctx.state = 6;\n break;\n }\n case 37:\n _yieldValue = _aether._shouldYield;\n $ctx.state = 38;\n break;\n case 38:\n _aether._shouldYield = false;\n $ctx.state = 40;\n break;\n case 40:\n if (this.onAetherYield) {\n this.onAetherYield(_yieldValue);\n }\n $ctx.state = 42;\n break;\n case 42:\n $ctx.state = 34;\n return _yieldValue;\n case 34:\n if ($ctx.action === 'throw') {\n $ctx.action = 'next';\n throw $ctx.sent;\n }\n $ctx.state = 36;\n break;\n case 36:\n if (typeof __yieldCount0 !== 'undefined' && __yieldCount0 !== null) {\n __yieldCount0++;\n }\n $ctx.state = 6;\n break;\n case 75:\n tmp28 = _aether.createAPIClone(_aether, __interceptThis(this, __global));\n $ctx.state = 76;\n break;\n case 76:\n tmp29 = 'attack';\n $ctx.state = 78;\n break;\n case 78:\n tmp31 = 'enemy';\n $ctx.state = 80;\n break;\n case 80:\n tmp32 = tmp31 in __global;\n $ctx.state = 82;\n break;\n case 82:\n if (tmp32) {\n tmp30 = __global[tmp31];\n } else {\n _aether.logStatementStart([{\n ofs: 319,\n row: 11,\n col: 24\n }, {\n ofs: 324,\n row: 11,\n col: 29\n }]);\n tmp33 = 'ReferenceError';\n tmp34 = __global[tmp33];\n tmp35 = new tmp34('ReferenceError: ' + (tmp31 + ' is not defined'));\n throw tmp35;\n _aether.logStatement([{\n ofs: 319,\n row: 11,\n col: 24\n }, {\n ofs: 324,\n row: 11,\n col: 29\n }], _aether._userInfo, false);\n }\n $ctx.state = 84;\n break;\n case 84:\n _aether.logStatementStart([{\n ofs: 307,\n row: 11,\n col: 12\n }, {\n ofs: 325,\n row: 11,\n col: 30\n }]);\n $ctx.state = 86;\n break;\n case 86:\n tmp36 = _aether.convertToNativeType(_aether.createAPIClone(_aether, tmp28[tmp29](_aether.restoreAPIClone(_aether, tmp30))));\n $ctx.state = 88;\n break;\n case 88:\n _aether.logStatement([{\n ofs: 307,\n row: 11,\n col: 12\n }, {\n ofs: 325,\n row: 11,\n col: 30\n }], _aether._userInfo, false);\n $ctx.state = 90;\n break;\n case 90:\n if (_aether._shouldYield) {\n $ctx.state = 66;\n break;\n } else {\n $ctx.state = 6;\n break;\n }\n case 66:\n _yieldValue = _aether._shouldYield;\n $ctx.state = 67;\n break;\n case 67:\n _aether._shouldYield = false;\n $ctx.state = 69;\n break;\n case 69:\n if (this.onAetherYield) {\n this.onAetherYield(_yieldValue);\n }\n $ctx.state = 71;\n break;\n case 71:\n $ctx.state = 63;\n return _yieldValue;\n case 63:\n if ($ctx.action === 'throw') {\n $ctx.action = 'next';\n throw $ctx.sent;\n }\n $ctx.state = 65;\n break;\n case 65:\n if (typeof __yieldCount0 !== 'undefined' && __yieldCount0 !== null) {\n __yieldCount0++;\n }\n $ctx.state = 6;\n break;\n case 108:\n {\n ;\n }\n $ctx.state = 6;\n break;\n case 6:\n _aether.logStatementStart([{\n ofs: 44,\n row: 2,\n col: 7\n }, {\n ofs: 48,\n row: 2,\n col: 11\n }]);\n $ctx.state = 147;\n break;\n case 147:\n tmp2 = true;\n $ctx.state = 149;\n break;\n case 149:\n _aether.logStatement([{\n ofs: 44,\n row: 2,\n col: 7\n }, {\n ofs: 48,\n row: 2,\n col: 11\n }], _aether._userInfo, false);\n $ctx.state = 151;\n break;\n case 151:\n if (this.onAetherYield) {\n this.onAetherYield('simple loop');\n }\n $ctx.state = 153;\n break;\n case 153:\n if (__yieldCount0 === 0) {\n $ctx.state = 139;\n break;\n } else {\n $ctx.state = 170;\n break;\n }\n case 139:\n $ctx.state = 140;\n return 'simple loop...';\n case 140:\n if ($ctx.action === 'throw') {\n $ctx.action = 'next';\n throw $ctx.sent;\n }\n $ctx.state = 170;\n break;\n case 3:\n _aether.logCallEnd();\n $ctx.state = 172;\n break;\n case 172:\n $ctx.state = -2;\n break;\n case -2:\n return $ctx;\n case -3:\n throw $ctx.storedException;\n default:\n throw 'traceur compiler bug: invalid state in state machine: ' + $ctx.state;\n }\n }, this);\n };\n tmp0 = 'plan';\n __global[tmp0] = tmp1;\n}(this));\n" } }, "submittedCodeLanguage": "javascript", "teamSpells": { - "common": ["coin-generator-9000/chooseAction"], - "humans": ["tharin/chooseAction"], - "ogres": ["mak-fod/chooseAction"] + "humans": ["hero-placeholder/plan"], + "ogres": ["hero-placeholder-1/plan"] }, - "levelID": "gold-rush", - "creatorName": "monkboll", - "creator": "53fdb782716abde208a0e7a4", - "totalScore": 24.174942315603005 - }] + "levelID": "dueling-grounds", + "creator": "5481b0fab5cf8a5f052ab62c", + "creatorName": "Lukucio Skriaudejas", + "totalScore": 29.794723041533086 + }], + "taskID": "54dd14c68bf17b9b05a92592", + "receiptHandle": "cbb4bc48f52de5f52dc38303ed960c0fc856ae61" } diff --git a/headless_client/worker_world.coffee b/headless_client/worker_world.coffee index b9896f9cf..981266376 100644 --- a/headless_client/worker_world.coffee +++ b/headless_client/worker_world.coffee @@ -100,12 +100,12 @@ work = () -> self.postMessage type: 'start-load-frames' - self.world.loadFrames self.onWorldLoaded, self.onWorldError, self.onWorldLoadProgress, true + self.world.loadFrames self.onWorldLoaded, self.onWorldError, self.onWorldLoadProgress, null, true self.onWorldLoaded = onWorldLoaded = -> self.goalManager.worldGenerationEnded() goalStates = self.goalManager.getGoalStates() - self.postMessage type: 'end-load-frames', goalStates: goalStates + self.postMessage type: 'end-load-frames', goalStates: goalStates, overallStatus: goalManager.checkOverallStatus() t1 = new Date() diff = t1 - self.t0 @@ -176,9 +176,19 @@ work = () -> self.postMessage type: 'worker-initialized' -worldCode = fs.readFileSync './public/javascripts/world.js', 'utf8' -lodashCode = fs.readFileSync './public/javascripts/lodash.js', 'utf8' -aetherCode = fs.readFileSync './public/javascripts/aether.js', 'utf8' +codeFileContents = [] +for codeFile in [ + 'world.js' + 'lodash.js' + 'aether.js' + 'app/vendor/aether-clojure.js' + 'app/vendor/aether-coffeescript.js' + 'app/vendor/aether-io.js' + 'app/vendor/aether-javascript.js' + 'app/vendor/aether-lua.js' + 'app/vendor/aether-python.js' + ] + codeFileContents.push fs.readFileSync("./public/javascripts/#{codeFile}", 'utf8') #window.BOX2D_ENABLED = true; @@ -195,9 +205,7 @@ ret = """ try { // the world javascript file - #{worldCode}; - #{lodashCode}; - #{aetherCode}; + #{codeFileContents.join(';\n ')}; // Don't let user generated code access stuff from our file system! self.importScripts = importScripts = null; diff --git a/package.json b/package.json index ff398f86b..a23b19e6f 100644 --- a/package.json +++ b/package.json @@ -63,7 +63,7 @@ "aws-sdk": "~2.0.0", "bayesian-battle": "0.0.x", "redis": "", - "webworker-threads": "~0.4.11", + "webworker-threads": "~0.5.5", "node-gyp": "~0.13.0", "aether": "~0.3.0", "JASON": "~0.1.3", From 7000048beeb85cb5897b7d75cfb05c3b0c6f3cec Mon Sep 17 00:00:00 2001 From: Nick Winter Date: Thu, 12 Feb 2015 17:07:00 -0800 Subject: [PATCH 08/10] Fixed a few more issues with the headless simulator. --- app/assets/javascripts/workers/worker_world.js | 1 + app/lib/simulator/Simulator.coffee | 3 ++- app/lib/world/world.coffee | 4 ++-- app/schemas/models/level_session.coffee | 1 + app/views/ladder/MyMatchesTabView.coffee | 2 +- headless_client.coffee | 1 + headless_client/worker_world.coffee | 4 +++- server/queues/scoring.coffee | 3 ++- 8 files changed, 13 insertions(+), 6 deletions(-) diff --git a/app/assets/javascripts/workers/worker_world.js b/app/assets/javascripts/workers/worker_world.js index 171cb0be8..a9d998fac 100644 --- a/app/assets/javascripts/workers/worker_world.js +++ b/app/assets/javascripts/workers/worker_world.js @@ -478,6 +478,7 @@ self.onWorldError = function onWorldError(error) { else { console.log("Non-UserCodeError:", error.toString() + "\n" + error.stack || error.stackTrace); self.postMessage({type: 'non-user-code-problem', problem: {message: error.toString()}}); + return false; } /* We don't actually have the recoverable property any more; hmm if(!error.recoverable) { diff --git a/app/lib/simulator/Simulator.coffee b/app/lib/simulator/Simulator.coffee index 8b8f9f92f..6f86fa6a3 100644 --- a/app/lib/simulator/Simulator.coffee +++ b/app/lib/simulator/Simulator.coffee @@ -5,7 +5,7 @@ GoalManager = require 'lib/world/GoalManager' God = require 'lib/God' {createAetherOptions} = require 'lib/aether_utils' -SIMULATOR_VERSION = 2 +SIMULATOR_VERSION = 3 simulatorInfo = {} if $.browser @@ -334,6 +334,7 @@ module.exports = class Simulator extends CocoClass calculationTime: 500 sessions: [] simulator: @simulator + randomSeed: @task.world.randomSeed for session in @task.getSessions() sessionResult = diff --git a/app/lib/world/world.coffee b/app/lib/world/world.coffee index 538f4976a..37d304f5d 100644 --- a/app/lib/world/world.coffee +++ b/app/lib/world/world.coffee @@ -360,7 +360,7 @@ module.exports = class World #console.log "... world serializing frames from", startFrame, "to", endFrame, "of", @totalFrames [transferableObjects, nontransferableObjects] = [0, 0] delete flag.processed for flag in @flagHistory - o = {totalFrames: @totalFrames, maxTotalFrames: @maxTotalFrames, frameRate: @frameRate, dt: @dt, victory: @victory, userCodeMap: {}, trackedProperties: {}, flagHistory: @flagHistory, difficulty: @difficulty, scores: @getScores()} + o = {totalFrames: @totalFrames, maxTotalFrames: @maxTotalFrames, frameRate: @frameRate, dt: @dt, victory: @victory, userCodeMap: {}, trackedProperties: {}, flagHistory: @flagHistory, difficulty: @difficulty, scores: @getScores(), randomSeed: @randomSeed} o.trackedProperties[prop] = @[prop] for prop in @trackedProperties or [] for thangID, methods of @userCodeMap @@ -467,7 +467,7 @@ module.exports = class World w.userCodeMap[thangID][methodName][aetherStateKey] = serializedAether[aetherStateKey] else w = new World o.userCodeMap, classMap - [w.totalFrames, w.maxTotalFrames, w.frameRate, w.dt, w.scriptNotes, w.victory, w.flagHistory, w.difficulty, w.scores] = [o.totalFrames, o.maxTotalFrames, o.frameRate, o.dt, o.scriptNotes ? [], o.victory, o.flagHistory, o.difficulty, o.scores] + [w.totalFrames, w.maxTotalFrames, w.frameRate, w.dt, w.scriptNotes, w.victory, w.flagHistory, w.difficulty, w.scores, w.randomSeed] = [o.totalFrames, o.maxTotalFrames, o.frameRate, o.dt, o.scriptNotes ? [], o.victory, o.flagHistory, o.difficulty, o.scores, o.randomSeed] w[prop] = val for prop, val of o.trackedProperties perf.t1 = now() diff --git a/app/schemas/models/level_session.coffee b/app/schemas/models/level_session.coffee index 41f585f43..2d4c74405 100644 --- a/app/schemas/models/level_session.coffee +++ b/app/schemas/models/level_session.coffee @@ -286,6 +286,7 @@ _.extend LevelSessionSchema.properties, type: ['string', 'null'] # 'null' in case an opponent session got corrupted, don't care much here description: 'What submittedCodeLanguage the opponent used during the match' simulator: {type: 'object', description: 'Holds info on who simulated the match, and with what tools.'} + randomSeed: {type: 'integer', description: 'Stores the random seed that was used during this match.'} c.extendBasicProperties LevelSessionSchema, 'level.session' c.extendPermissionsProperties LevelSessionSchema, 'level.session' diff --git a/app/views/ladder/MyMatchesTabView.coffee b/app/views/ladder/MyMatchesTabView.coffee index 873875d27..327335b31 100644 --- a/app/views/ladder/MyMatchesTabView.coffee +++ b/app/views/ladder/MyMatchesTabView.coffee @@ -82,7 +82,7 @@ module.exports = class MyMatchesTabView extends CocoView stale: match.date < submitDate fresh: fresh codeLanguage: match.codeLanguage - simulator: JSON.stringify(match.simulator) + simulator: JSON.stringify(match.simulator) + ' | seed ' + match.randomSeed } for team in @teams diff --git a/headless_client.coffee b/headless_client.coffee index 27fca376b..7db937737 100644 --- a/headless_client.coffee +++ b/headless_client.coffee @@ -95,6 +95,7 @@ GLOBAL.Backbone = require bowerComponentsPath + 'backbone/backbone' unhook() Backbone.$ = $ require bowerComponentsPath + 'validated-backbone-mediator/backbone-mediator' +Backbone.Mediator.setValidationEnabled false GLOBAL.Aether = require 'aether' # Set up new loader. Again. hook() diff --git a/headless_client/worker_world.coffee b/headless_client/worker_world.coffee index 981266376..f32928f28 100644 --- a/headless_client/worker_world.coffee +++ b/headless_client/worker_world.coffee @@ -148,7 +148,9 @@ work = () -> self.postedErrors[errorKey] = error else console.log 'Non-UserCodeError:', error.toString() + "\n" + error.stack or error.stackTrace + self.postMessage type: 'non-user-code-problem', problem: {message: error.toString()} self.cleanUp() + return false return true self.onWorldLoadProgress = onWorldLoadProgress = (progress) -> @@ -178,8 +180,8 @@ work = () -> codeFileContents = [] for codeFile in [ - 'world.js' 'lodash.js' + 'world.js' 'aether.js' 'app/vendor/aether-clojure.js' 'app/vendor/aether-coffeescript.js' diff --git a/server/queues/scoring.coffee b/server/queues/scoring.coffee index c2cf71be4..66a947ce8 100644 --- a/server/queues/scoring.coffee +++ b/server/queues/scoring.coffee @@ -15,7 +15,7 @@ bayes = new (require 'bayesian-battle')() scoringTaskQueue = undefined scoringTaskTimeoutInSeconds = 600 -SIMULATOR_VERSION = 2 +SIMULATOR_VERSION = 3 module.exports.setup = (app) -> connectToScoringQueue() @@ -611,6 +611,7 @@ updateMatchesInSession = (matchObject, sessionID, callback) -> currentMatchObject.opponents = opponentsArray currentMatchObject.codeLanguage = matchObject.opponents[opponentsArray[0].sessionID].codeLanguage currentMatchObject.simulator = @clientResponseObject.simulator + currentMatchObject.randomSeed = @clientResponseObject.randomSeed LevelSession.findOne {'_id': sessionID}, (err, session) -> session = session.toObject() currentMatchObject.playtime = session.playtime ? 0 From a8dc353f86a0bdf6951d48a26fbb9714f006bbe6 Mon Sep 17 00:00:00 2001 From: Nick Winter Date: Thu, 12 Feb 2015 18:40:38 -0800 Subject: [PATCH 09/10] Aether now loading all code languages possibly used in a match before the level can begin. Hopefully, this will fix #1943 and fix #1892. --- app/lib/LevelLoader.coffee | 24 ++++++++++++++---------- app/schemas/models/level_session.coffee | 2 +- server/queues/scoring.coffee | 2 +- 3 files changed, 16 insertions(+), 12 deletions(-) diff --git a/app/lib/LevelLoader.coffee b/app/lib/LevelLoader.coffee index 2b22c98c7..a18d9cc82 100644 --- a/app/lib/LevelLoader.coffee +++ b/app/lib/LevelLoader.coffee @@ -91,18 +91,9 @@ module.exports = class LevelLoader extends CocoClass loadDependenciesForSession: (session) -> if me.id isnt session.get 'creator' session.patch = session.save = -> console.error "Not saving session, since we didn't create it." + @loadCodeLanguagesForSession session if session is @session - codeLanguage = session.get('codeLanguage') or me.get('aceConfig')?.language or 'python' - modulePath = "vendor/aether-#{codeLanguage}" - loading = application.moduleLoader?.load(modulePath) - if loading - @languageModuleResource = @supermodel.addSomethingResource 'language_module' - @listenTo application.moduleLoader, 'loaded', (e) -> - if e.id is modulePath - @languageModuleResource.markLoaded() - @stopListening application.moduleLoader @addSessionBrowserInfo session - # hero-ladder games require the correct session team in level:loaded team = @team ? @session.get('team') Backbone.Mediator.publish 'level:loaded', level: @level, team: team @@ -138,6 +129,19 @@ module.exports = class LevelLoader extends CocoClass if _.size(@sessionDependenciesRegistered) is 2 and @checkAllWorldNecessitiesRegisteredAndLoaded() @onWorldNecessitiesLoaded() + loadCodeLanguagesForSession: (session) -> + codeLanguages = _.uniq _.filter [session.get('codeLanguage') or 'python', session.get('submittedCodeLanguage')] + for codeLanguage in codeLanguages + do (codeLanguage) => + modulePath = "vendor/aether-#{codeLanguage}" + return unless application.moduleLoader?.load modulePath + languageModuleResource = @supermodel.addSomethingResource 'language_module' + onModuleLoaded = (e) -> + return unless e.id is modulePath + languageModuleResource.markLoaded() + @stopListening application.moduleLoader, 'loaded', onModuleLoaded # listenToOnce might work here instead, haven't tried + @listenTo application.moduleLoader, 'loaded', onModuleLoaded + addSessionBrowserInfo: (session) -> return unless me.id is session.get 'creator' return unless $.browser? diff --git a/app/schemas/models/level_session.coffee b/app/schemas/models/level_session.coffee index 2d4c74405..a4fca840e 100644 --- a/app/schemas/models/level_session.coffee +++ b/app/schemas/models/level_session.coffee @@ -286,7 +286,7 @@ _.extend LevelSessionSchema.properties, type: ['string', 'null'] # 'null' in case an opponent session got corrupted, don't care much here description: 'What submittedCodeLanguage the opponent used during the match' simulator: {type: 'object', description: 'Holds info on who simulated the match, and with what tools.'} - randomSeed: {type: 'integer', description: 'Stores the random seed that was used during this match.'} + randomSeed: {description: 'Stores the random seed that was used during this match.'} c.extendBasicProperties LevelSessionSchema, 'level.session' c.extendPermissionsProperties LevelSessionSchema, 'level.session' diff --git a/server/queues/scoring.coffee b/server/queues/scoring.coffee index 66a947ce8..9b895ec69 100644 --- a/server/queues/scoring.coffee +++ b/server/queues/scoring.coffee @@ -611,7 +611,7 @@ updateMatchesInSession = (matchObject, sessionID, callback) -> currentMatchObject.opponents = opponentsArray currentMatchObject.codeLanguage = matchObject.opponents[opponentsArray[0].sessionID].codeLanguage currentMatchObject.simulator = @clientResponseObject.simulator - currentMatchObject.randomSeed = @clientResponseObject.randomSeed + currentMatchObject.randomSeed = parseInt(@clientResponseObject.randomSeed or 0, 10) LevelSession.findOne {'_id': sessionID}, (err, session) -> session = session.toObject() currentMatchObject.playtime = session.playtime ? 0 From 991a374da2de6747ae7fa7339f2d0f29baefb24b Mon Sep 17 00:00:00 2001 From: Nick Winter Date: Thu, 12 Feb 2015 19:47:57 -0800 Subject: [PATCH 10/10] Fixed up SpectateView for hero ladder games. Addd player names to their heroes in spectate and observation mode. Fixed #1679. --- app/lib/surface/Lank.coffee | 2 ++ app/lib/surface/LankBoss.coffee | 2 ++ app/lib/surface/Surface.coffee | 7 ++++--- app/views/play/SpectateView.coffee | 16 +++++++++++----- app/views/play/level/PlayLevelView.coffee | 9 ++++++++- 5 files changed, 27 insertions(+), 9 deletions(-) diff --git a/app/lib/surface/Lank.coffee b/app/lib/surface/Lank.coffee index 4dd1628d2..8f86a3788 100644 --- a/app/lib/surface/Lank.coffee +++ b/app/lib/surface/Lank.coffee @@ -474,6 +474,8 @@ module.exports = Lank = class Lank extends CocoClass bar.scaleX = healthPct / @options.floatingLayer.resolutionFactor if @thang.showsName @setNameLabel(if @thang.health <= 0 then '' else @thang.id) + else if @options.playerName + @setNameLabel @options.playerName configureMouse: -> @sprite.cursor = 'pointer' if @thang?.isSelectable diff --git a/app/lib/surface/LankBoss.coffee b/app/lib/surface/LankBoss.coffee index 55a5bbc55..17cab9c9e 100644 --- a/app/lib/surface/LankBoss.coffee +++ b/app/lib/surface/LankBoss.coffee @@ -163,6 +163,8 @@ module.exports = class LankBoss extends CocoClass options = @createLankOptions thang: thang options.resolutionFactor = if thangType.get('kind') is 'Floor' then 2 else SPRITE_RESOLUTION_FACTOR + if @options.playerNames and /Hero Placeholder/.test thang.id + options.playerName = @options.playerNames[thang.team] lank = new Lank thangType, options @listenTo lank, 'sprite:mouse-up', @onLankMouseUp @addLank lank, null, layer diff --git a/app/lib/surface/Surface.coffee b/app/lib/surface/Surface.coffee index f001a6330..404075d48 100644 --- a/app/lib/surface/Surface.coffee +++ b/app/lib/surface/Surface.coffee @@ -113,7 +113,7 @@ module.exports = Surface = class Surface extends CocoClass canvasHeight = parseInt @normalCanvas.attr('height'), 10 @screenLayer.addChild new Letterbox canvasWidth: canvasWidth, canvasHeight: canvasHeight - @lankBoss = new LankBoss camera: @camera, webGLStage: @webGLStage, surfaceTextLayer: @surfaceTextLayer, world: @world, thangTypes: @options.thangTypes, choosing: @options.choosing, navigateToSelection: @options.navigateToSelection, showInvisible: @options.showInvisible + @lankBoss = new LankBoss camera: @camera, webGLStage: @webGLStage, surfaceTextLayer: @surfaceTextLayer, world: @world, thangTypes: @options.thangTypes, choosing: @options.choosing, navigateToSelection: @options.navigateToSelection, showInvisible: @options.showInvisible, playerNames: @options.playerNames @countdownScreen = new CountdownScreen camera: @camera, layer: @screenLayer, showsCountdown: @world.showsCountdown @playbackOverScreen = new PlaybackOverScreen camera: @camera, layer: @screenLayer @normalStage.addChildAt @playbackOverScreen.dimLayer, 0 # Put this below the other layers, actually, so we can more easily read text on the screen. @@ -549,8 +549,9 @@ module.exports = Surface = class Surface extends CocoClass @normalStage.scaleY *= newHeight / oldHeight @camera.onResize newWidth, newHeight if @options.spectateGame - # Since normalCanvas is absolutely positioned, it needs help aligning with webGLCanvas. But not further than +149px (1920px screen). - @normalCanvas.css 'left', Math.min 149, @webGLCanvas.offset().left + # Since normalCanvas is absolutely positioned, it needs help aligning with webGLCanvas. + offset = @webGLCanvas.offset().left - ($('#page-container').innerWidth() - $('#canvas-wrapper').innerWidth()) / 2 + @normalCanvas.css 'left', offset #- Camera focus on hero focusOnHero: -> diff --git a/app/views/play/SpectateView.coffee b/app/views/play/SpectateView.coffee index 2530e00d5..2d0f66833 100644 --- a/app/views/play/SpectateView.coffee +++ b/app/views/play/SpectateView.coffee @@ -187,13 +187,13 @@ module.exports = class SpectateLevelView extends RootView ctx.fillText("Loaded #{@modelsLoaded} thingies",50,50) insertSubviews: -> - @insertSubView @tome = new TomeView levelID: @levelID, session: @session, thangs: @world.thangs, supermodel: @supermodel, spectateView: true, spectateOpponentCodeLanguage: @otherSession?.get('submittedCodeLanguage'), level: @level - @insertSubView new PlaybackView {} + @insertSubView @tome = new TomeView levelID: @levelID, session: @session, otherSession: @otherSession, thangs: @world.thangs, supermodel: @supermodel, spectateView: true, spectateOpponentCodeLanguage: @otherSession?.get('submittedCodeLanguage'), level: @level + @insertSubView new PlaybackView session: @session, level: @level @insertSubView new GoldView {} - @insertSubView new HUDView {} + @insertSubView new HUDView {level: @level} worldName = utils.i18n @level.attributes, 'name' - @controlBar = @insertSubView new ControlBarView {worldName: worldName, session: @session, level: @level, supermodel: @supermodel, playableTeams: @world.playableTeams, spectateGame: true} + @controlBar = @insertSubView new ControlBarView {worldName: worldName, session: @session, level: @level, supermodel: @supermodel, spectateGame: true} # callbacks @@ -207,7 +207,7 @@ module.exports = class SpectateLevelView extends RootView initSurface: -> webGLSurface = $('canvas#webgl-surface', @$el) normalSurface = $('canvas#normal-surface', @$el) - @surface = new Surface(@world, normalSurface, webGLSurface, thangTypes: @supermodel.getModels(ThangType), playJingle: not @isEditorPreview, spectateGame: true, wizards: @level.get('type', true) isnt 'hero') + @surface = new Surface @world, normalSurface, webGLSurface, thangTypes: @supermodel.getModels(ThangType), playJingle: not @isEditorPreview, spectateGame: true, wizards: @level.get('type', true) is 'ladder', playerNames: @findPlayerNames() worldBounds = @world.getBounds() bounds = [{x:worldBounds.left, y:worldBounds.top}, {x:worldBounds.right, y:worldBounds.bottom}] @surface.camera.setBounds(bounds) @@ -215,6 +215,12 @@ module.exports = class SpectateLevelView extends RootView @surface.camera.zoomTo({x: (worldBounds.right - worldBounds.left) / 2, y: (worldBounds.top - worldBounds.bottom) / 2}, 0.1, 0) _.delay zoom, 4000 # call it later for some reason (TODO: figure this out) + findPlayerNames: -> + playerNames = {} + for session in [@session, @otherSession] when session?.get('team') + playerNames[session.get('team')] = session.get('creatorName') or 'Anoner' + playerNames + initGoalManager: -> @goalManager = new GoalManager(@world, @level.get('goals')) @god.setGoalManager @goalManager diff --git a/app/views/play/level/PlayLevelView.coffee b/app/views/play/level/PlayLevelView.coffee index 48b302763..26babb926 100644 --- a/app/views/play/level/PlayLevelView.coffee +++ b/app/views/play/level/PlayLevelView.coffee @@ -305,12 +305,19 @@ module.exports = class PlayLevelView extends RootView initSurface: -> webGLSurface = $('canvas#webgl-surface', @$el) normalSurface = $('canvas#normal-surface', @$el) - @surface = new Surface(@world, normalSurface, webGLSurface, thangTypes: @supermodel.getModels(ThangType), playJingle: not @isEditorPreview, wizards: not (@level.get('type', true) in ['hero', 'hero-ladder', 'hero-coop'])) + @surface = new Surface(@world, normalSurface, webGLSurface, thangTypes: @supermodel.getModels(ThangType), playJingle: not @isEditorPreview, wizards: not (@level.get('type', true) in ['hero', 'hero-ladder', 'hero-coop']), observing: @observing, playerNames: @findPlayerNames()) worldBounds = @world.getBounds() bounds = [{x: worldBounds.left, y: worldBounds.top}, {x: worldBounds.right, y: worldBounds.bottom}] @surface.camera.setBounds(bounds) @surface.camera.zoomTo({x: 0, y: 0}, 0.1, 0) + findPlayerNames: -> + return {} unless @observing + playerNames = {} + for session in [@session, @otherSession] when session?.get('team') + playerNames[session.get('team')] = session.get('creatorName') or 'Anoner' + playerNames + # Once Surface is Loaded #################################################### onLevelStarted: ->