text: !function(e){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{var f;"undefined"!=typeof window?f=window:"undefined"!=typeof global?f=global:"undefined"!=typeof self&&(f=self),f.SupRuntime=e()}}(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
  /// <reference path="../../../../typings/tsd.d.ts" />
  /// <reference path="../SupRuntime.d.ts" />
  /// <reference path="../../../../SupCore/SupCore.d.ts" />
  var async = require("async");
  var querystring = require("querystring");
  var fetch_1 = require("../../../../SupClient/src/fetch");
  var Player_1 = require("./Player");
  exports.Player = Player_1.default;
  // Any export here will be exposed as SupRuntime.* by browserify
  // (see ../gulpfile.js)
  exports.plugins = {};
  exports.resourcePlugins = {};
  function registerPlugin(name, plugin) {
      if (exports.plugins[name] != null) {
          console.error("SupRuntime.registerPlugin: Tried to register two or more plugins named \"" + name + "\"");
          return;
      }
      exports.plugins[name] = plugin;
  }
  exports.registerPlugin = registerPlugin;
  function registerResource(name, plugin) {
      if (exports.resourcePlugins[name] != null) {
          console.error("SupRuntime.registerResource: Tried to register two or more resources named \"" + name + "\"");
          return;
      }
      exports.resourcePlugins[name] = plugin;
  }
  exports.registerResource = registerResource;
  SupCore.system = new SupCore.System("", "");
  // In app, open links in a browser window
  var playerWindow;
  if (window.navigator.userAgent.indexOf("Electron") !== -1) {
      var nodeRequire = require;
      var electron = nodeRequire("electron");
      playerWindow = electron.remote.getCurrentWindow();
      document.body.addEventListener("click", function (event) {
          if (event.target.tagName !== "A")
              return;
          event.preventDefault();
          electron.shell.openExternal(event.target.href);
      });
  }
  var qs = querystring.parse(window.location.search.slice(1));
  document.body.addEventListener("keydown", function (event) {
      if (event.keyCode === window["KeyEvent"].DOM_VK_F12) {
          if (qs.project != null && playerWindow != null)
              playerWindow.webContents.toggleDevTools();
      }
  });
  // Prevent keypress events from leaking out to a parent window
  // They might trigger scrolling for instance
  document.body.addEventListener("keypress", function (event) { event.preventDefault(); });
  var progressBar = document.querySelector("progress");
  var loadingElt = document.getElementById("loading");
  var canvas = document.querySelector("canvas");
  if (qs.debug != null && playerWindow != null)
      playerWindow.webContents.openDevTools();
  var player;
  var onLoadProgress = function (value, max) {
      progressBar.value = value;
      progressBar.max = max;
  };
  var onLoaded = function (err) {
      if (err != null) {
          console.error(err);
          var aElt = loadingElt.querySelector("a");
          aElt.parentElement.removeChild(aElt);
          var errorElt = document.createElement("div");
          errorElt.className = "error";
          errorElt.textContent = err.message;
          loadingElt.appendChild(errorElt);
          return;
      }
      setTimeout(function () {
          loadingElt.classList.remove("start");
          loadingElt.classList.add("end");
          setTimeout(function () {
              loadingElt.parentElement.removeChild(loadingElt);
              player.run();
              return;
          }, (qs.project == null) ? 500 : 0);
      }, (qs.project == null) ? 500 : 0);
  };
  // Load plugins
  fetch_1.default("plugins.json", "json", function (err, pluginsInfo) {
      if (err != null) {
          console.log(err);
          onLoaded(new Error("Could not load plugins list."));
          return;
      }
      async.each(pluginsInfo.list, function (pluginName, pluginCallback) {
          async.each(pluginsInfo.publishedBundles, function (bundle, cb) {
              var script = document.createElement("script");
              script.src = "plugins/" + pluginName + "/bundles/" + bundle + ".js";
              script.addEventListener("load", function () { return cb(null); });
              script.addEventListener("error", function (err) { return cb(null); });
              document.body.appendChild(script);
          }, pluginCallback);
      }, function (err) {
          if (err != null)
              console.log(err);
          // Load game
          var buildPath = (qs.project != null) ? "/builds/" + qs.project + "/" + qs.build + "/" : "./";
          player = new Player_1.default(canvas, buildPath, { debug: qs.debug != null });
          player.load(onLoadProgress, onLoaded);
      });
  });
  loadingElt.classList.add("start");
  
  },{"../../../../SupClient/src/fetch":2,"./Player":8,"async":3,"querystring":7}],2:[function(require,module,exports){
  function fetch(url, type, callback) {
      var xhr = new XMLHttpRequest();
      xhr.open("GET", url, true);
      xhr.responseType = type;
      xhr.onload = function (event) {
          if (xhr.status !== 200 && xhr.status !== 0) {
              callback(new Error("HTTP " + xhr.status + ": " + xhr.statusText));
              return;
          }
          callback(null, xhr.response);
      };
      xhr.onerror = function (event) {
          console.log(event);
          callback(new Error("Network error: " + event.target.status));
      };
      xhr.send();
  }
  Object.defineProperty(exports, "__esModule", { value: true });
  exports.default = fetch;
  ;
  
  },{}],3:[function(require,module,exports){
  (function (process,global){
  /*!
   * async
   * https://github.com/caolan/async
   *
   * Copyright 2010-2014 Caolan McMahon
   * Released under the MIT license
   */
  (function () {
  
      var async = {};
      function noop() {}
      function identity(v) {
          return v;
      }
      function toBool(v) {
          return !!v;
      }
      function notId(v) {
          return !v;
      }
  
      // global on the server, window in the browser
      var previous_async;
  
      // Establish the root object, `window` (`self`) in the browser, `global`
      // on the server, or `this` in some virtual machines. We use `self`
      // instead of `window` for `WebWorker` support.
      var root = typeof self === 'object' && self.self === self && self ||
              typeof global === 'object' && global.global === global && global ||
              this;
  
      if (root != null) {
          previous_async = root.async;
      }
  
      async.noConflict = function () {
          root.async = previous_async;
          return async;
      };
  
      function only_once(fn) {
          return function() {
              if (fn === null) throw new Error("Callback was already called.");
              fn.apply(this, arguments);
              fn = null;
          };
      }
  
      function _once(fn) {
          return function() {
              if (fn === null) return;
              fn.apply(this, arguments);
              fn = null;
          };
      }
  
      //// cross-browser compatiblity functions ////
  
      var _toString = Object.prototype.toString;
  
      var _isArray = Array.isArray || function (obj) {
          return _toString.call(obj) === '[object Array]';
      };
  
      // Ported from underscore.js isObject
      var _isObject = function(obj) {
          var type = typeof obj;
          return type === 'function' || type === 'object' && !!obj;
      };
  
      function _isArrayLike(arr) {
          return _isArray(arr) || (
              // has a positive integer length property
              typeof arr.length === "number" &&
              arr.length >= 0 &&
              arr.length % 1 === 0
          );
      }
  
      function _arrayEach(arr, iterator) {
          var index = -1,
              length = arr.length;
  
          while (++index < length) {
              iterator(arr[index], index, arr);
          }
      }
  
      function _map(arr, iterator) {
          var index = -1,
              length = arr.length,
              result = Array(length);
  
          while (++index < length) {
              result[index] = iterator(arr[index], index, arr);
          }
          return result;
      }
  
      function _range(count) {
          return _map(Array(count), function (v, i) { return i; });
      }
  
      function _reduce(arr, iterator, memo) {
          _arrayEach(arr, function (x, i, a) {
              memo = iterator(memo, x, i, a);
          });
          return memo;
      }
  
      function _forEachOf(object, iterator) {
          _arrayEach(_keys(object), function (key) {
              iterator(object[key], key);
          });
      }
  
      function _indexOf(arr, item) {
          for (var i = 0; i < arr.length; i++) {
              if (arr[i] === item) return i;
          }
          return -1;
      }
  
      var _keys = Object.keys || function (obj) {
          var keys = [];
          for (var k in obj) {
              if (obj.hasOwnProperty(k)) {
                  keys.push(k);
              }
          }
          return keys;
      };
  
      function _keyIterator(coll) {
          var i = -1;
          var len;
          var keys;
          if (_isArrayLike(coll)) {
              len = coll.length;
              return function next() {
                  i++;
                  return i < len ? i : null;
              };
          } else {
              keys = _keys(coll);
              len = keys.length;
              return function next() {
                  i++;
                  return i < len ? keys[i] : null;
              };
          }
      }
  
      // Similar to ES6's rest param (http://ariya.ofilabs.com/2013/03/es6-and-rest-parameter.html)
      // This accumulates the arguments passed into an array, after a given index.
      // From underscore.js (https://github.com/jashkenas/underscore/pull/2140).
      function _restParam(func, startIndex) {
          startIndex = startIndex == null ? func.length - 1 : +startIndex;
          return function() {
              var length = Math.max(arguments.length - startIndex, 0);
              var rest = Array(length);
              for (var index = 0; index < length; index++) {
                  rest[index] = arguments[index + startIndex];
              }
              switch (startIndex) {
                  case 0: return func.call(this, rest);
                  case 1: return func.call(this, arguments[0], rest);
              }
              // Currently unused but handle cases outside of the switch statement:
              // var args = Array(startIndex + 1);
              // for (index = 0; index < startIndex; index++) {
              //     args[index] = arguments[index];
              // }
              // args[startIndex] = rest;
              // return func.apply(this, args);
          };
      }
  
      function _withoutIndex(iterator) {
          return function (value, index, callback) {
              return iterator(value, callback);
          };
      }
  
      //// exported async module functions ////
  
      //// nextTick implementation with browser-compatible fallback ////
  
      // capture the global reference to guard against fakeTimer mocks
      var _setImmediate = typeof setImmediate === 'function' && setImmediate;
  
      var _delay = _setImmediate ? function(fn) {
          // not a direct alias for IE10 compatibility
          _setImmediate(fn);
      } : function(fn) {
          setTimeout(fn, 0);
      };
  
      if (typeof process === 'object' && typeof process.nextTick === 'function') {
          async.nextTick = process.nextTick;
      } else {
          async.nextTick = _delay;
      }
      async.setImmediate = _setImmediate ? _delay : async.nextTick;
  
  
      async.forEach =
      async.each = function (arr, iterator, callback) {
          return async.eachOf(arr, _withoutIndex(iterator), callback);
      };
  
      async.forEachSeries =
      async.eachSeries = function (arr, iterator, callback) {
          return async.eachOfSeries(arr, _withoutIndex(iterator), callback);
      };
  
  
      async.forEachLimit =
      async.eachLimit = function (arr, limit, iterator, callback) {
          return _eachOfLimit(limit)(arr, _withoutIndex(iterator), callback);
      };
  
      async.forEachOf =
      async.eachOf = function (object, iterator, callback) {
          callback = _once(callback || noop);
          object = object || [];
  
          var iter = _keyIterator(object);
          var key, completed = 0;
  
          while ((key = iter()) != null) {
              completed += 1;
              iterator(object[key], key, only_once(done));
          }
  
          if (completed === 0) callback(null);
  
          function done(err) {
              completed--;
              if (err) {
                  callback(err);
              }
              // Check key is null in case iterator isn't exhausted
              // and done resolved synchronously.
              else if (key === null && completed <= 0) {
                  callback(null);
              }
          }
      };
  
      async.forEachOfSeries =
      async.eachOfSeries = function (obj, iterator, callback) {
          callback = _once(callback || noop);
          obj = obj || [];
          var nextKey = _keyIterator(obj);
          var key = nextKey();
          function iterate() {
              var sync = true;
              if (key === null) {
                  return callback(null);
              }
              iterator(obj[key], key, only_once(function (err) {
                  if (err) {
                      callback(err);
                  }
                  else {
                      key = nextKey();
                      if (key === null) {
                          return callback(null);
                      } else {
                          if (sync) {
                              async.setImmediate(iterate);
                          } else {
                              iterate();
                          }
                      }
                  }
              }));
              sync = false;
          }
          iterate();
      };
  
  
  
      async.forEachOfLimit =
      async.eachOfLimit = function (obj, limit, iterator, callback) {
          _eachOfLimit(limit)(obj, iterator, callback);
      };
  
      function _eachOfLimit(limit) {
  
          return function (obj, iterator, callback) {
              callback = _once(callback || noop);
              obj = obj || [];
              var nextKey = _keyIterator(obj);
              if (limit <= 0) {
                  return callback(null);
              }
              var done = false;
              var running = 0;
              var errored = false;
  
              (function replenish () {
                  if (done && running <= 0) {
                      return callback(null);
                  }
  
                  while (running < limit && !errored) {
                      var key = nextKey();
                      if (key === null) {
                          done = true;
                          if (running <= 0) {
                              callback(null);
                          }
                          return;
                      }
                      running += 1;
                      iterator(obj[key], key, only_once(function (err) {
                          running -= 1;
                          if (err) {
                              callback(err);
                              errored = true;
                          }
                          else {
                              replenish();
                          }
                      }));
                  }
              })();
          };
      }
  
  
      function doParallel(fn) {
          return function (obj, iterator, callback) {
              return fn(async.eachOf, obj, iterator, callback);
          };
      }
      function doParallelLimit(fn) {
          return function (obj, limit, iterator, callback) {
              return fn(_eachOfLimit(limit), obj, iterator, callback);
          };
      }
      function doSeries(fn) {
          return function (obj, iterator, callback) {
              return fn(async.eachOfSeries, obj, iterator, callback);
          };
      }
  
      function _asyncMap(eachfn, arr, iterator, callback) {
          callback = _once(callback || noop);
          arr = arr || [];
          var results = _isArrayLike(arr) ? [] : {};
          eachfn(arr, function (value, index, callback) {
              iterator(value, function (err, v) {
                  results[index] = v;
                  callback(err);
              });
          }, function (err) {
              callback(err, results);
          });
      }
  
      async.map = doParallel(_asyncMap);
      async.mapSeries = doSeries(_asyncMap);
      async.mapLimit = doParallelLimit(_asyncMap);
  
      // reduce only has a series version, as doing reduce in parallel won't
      // work in many situations.
      async.inject =
      async.foldl =
      async.reduce = function (arr, memo, iterator, callback) {
          async.eachOfSeries(arr, function (x, i, callback) {
              iterator(memo, x, function (err, v) {
                  memo = v;
                  callback(err);
              });
          }, function (err) {
              callback(err, memo);
          });
      };
  
      async.foldr =
      async.reduceRight = function (arr, memo, iterator, callback) {
          var reversed = _map(arr, identity).reverse();
          async.reduce(reversed, memo, iterator, callback);
      };
  
      async.transform = function (arr, memo, iterator, callback) {
          if (arguments.length === 3) {
              callback = iterator;
              iterator = memo;
              memo = _isArray(arr) ? [] : {};
          }
  
          async.eachOf(arr, function(v, k, cb) {
              iterator(memo, v, k, cb);
          }, function(err) {
              callback(err, memo);
          });
      };
  
      function _filter(eachfn, arr, iterator, callback) {
          var results = [];
          eachfn(arr, function (x, index, callback) {
              iterator(x, function (v) {
                  if (v) {
                      results.push({index: index, value: x});
                  }
                  callback();
              });
          }, function () {
              callback(_map(results.sort(function (a, b) {
                  return a.index - b.index;
              }), function (x) {
                  return x.value;
              }));
          });
      }
  
      async.select =
      async.filter = doParallel(_filter);
  
      async.selectLimit =
      async.filterLimit = doParallelLimit(_filter);
  
      async.selectSeries =
      async.filterSeries = doSeries(_filter);
  
      function _reject(eachfn, arr, iterator, callback) {
          _filter(eachfn, arr, function(value, cb) {
              iterator(value, function(v) {
                  cb(!v);
              });
          }, callback);
      }
      async.reject = doParallel(_reject);
      async.rejectLimit = doParallelLimit(_reject);
      async.rejectSeries = doSeries(_reject);
  
      function _createTester(eachfn, check, getResult) {
          return function(arr, limit, iterator, cb) {
              function done() {
                  if (cb) cb(getResult(false, void 0));
              }
              function iteratee(x, _, callback) {
                  if (!cb) return callback();
                  iterator(x, function (v) {
                      if (cb && check(v)) {
                          cb(getResult(true, x));
                          cb = iterator = false;
                      }
                      callback();
                  });
              }
              if (arguments.length > 3) {
                  eachfn(arr, limit, iteratee, done);
              } else {
                  cb = iterator;
                  iterator = limit;
                  eachfn(arr, iteratee, done);
              }
          };
      }
  
      async.any =
      async.some = _createTester(async.eachOf, toBool, identity);
  
      async.someLimit = _createTester(async.eachOfLimit, toBool, identity);
  
      async.all =
      async.every = _createTester(async.eachOf, notId, notId);
  
      async.everyLimit = _createTester(async.eachOfLimit, notId, notId);
  
      function _findGetResult(v, x) {
          return x;
      }
      async.detect = _createTester(async.eachOf, identity, _findGetResult);
      async.detectSeries = _createTester(async.eachOfSeries, identity, _findGetResult);
      async.detectLimit = _createTester(async.eachOfLimit, identity, _findGetResult);
  
      async.sortBy = function (arr, iterator, callback) {
          async.map(arr, function (x, callback) {
              iterator(x, function (err, criteria) {
                  if (err) {
                      callback(err);
                  }
                  else {
                      callback(null, {value: x, criteria: criteria});
                  }
              });
          }, function (err, results) {
              if (err) {
                  return callback(err);
              }
              else {
                  callback(null, _map(results.sort(comparator), function (x) {
                      return x.value;
                  }));
              }
  
          });
  
          function comparator(left, right) {
              var a = left.criteria, b = right.criteria;
              return a < b ? -1 : a > b ? 1 : 0;
          }
      };
  
      async.auto = function (tasks, concurrency, callback) {
          if (typeof arguments[1] === 'function') {
              // concurrency is optional, shift the args.
              callback = concurrency;
              concurrency = null;
          }
          callback = _once(callback || noop);
          var keys = _keys(tasks);
          var remainingTasks = keys.length;
          if (!remainingTasks) {
              return callback(null);
          }
          if (!concurrency) {
              concurrency = remainingTasks;
          }
  
          var results = {};
          var runningTasks = 0;
  
          var hasError = false;
  
          var listeners = [];
          function addListener(fn) {
              listeners.unshift(fn);
          }
          function removeListener(fn) {
              var idx = _indexOf(listeners, fn);
              if (idx >= 0) listeners.splice(idx, 1);
          }
          function taskComplete() {
              remainingTasks--;
              _arrayEach(listeners.slice(0), function (fn) {
                  fn();
              });
          }
  
          addListener(function () {
              if (!remainingTasks) {
                  callback(null, results);
              }
          });
  
          _arrayEach(keys, function (k) {
              if (hasError) return;
              var task = _isArray(tasks[k]) ? tasks[k]: [tasks[k]];
              var taskCallback = _restParam(function(err, args) {
                  runningTasks--;
                  if (args.length <= 1) {
                      args = args[0];
                  }
                  if (err) {
                      var safeResults = {};
                      _forEachOf(results, function(val, rkey) {
                          safeResults[rkey] = val;
                      });
                      safeResults[k] = args;
                      hasError = true;
  
                      callback(err, safeResults);
                  }
                  else {
                      results[k] = args;
                      async.setImmediate(taskComplete);
                  }
              });
              var requires = task.slice(0, task.length - 1);
              // prevent dead-locks
              var len = requires.length;
              var dep;
              while (len--) {
                  if (!(dep = tasks[requires[len]])) {
                      throw new Error('Has nonexistent dependency in ' + requires.join(', '));
                  }
                  if (_isArray(dep) && _indexOf(dep, k) >= 0) {
                      throw new Error('Has cyclic dependencies');
                  }
              }
              function ready() {
                  return runningTasks < concurrency && _reduce(requires, function (a, x) {
                      return (a && results.hasOwnProperty(x));
                  }, true) && !results.hasOwnProperty(k);
              }
              if (ready()) {
                  runningTasks++;
                  task[task.length - 1](taskCallback, results);
              }
              else {
                  addListener(listener);
              }
              function listener() {
                  if (ready()) {
                      runningTasks++;
                      removeListener(listener);
                      task[task.length - 1](taskCallback, results);
                  }
              }
          });
      };
  
  
  
      async.retry = function(times, task, callback) {
          var DEFAULT_TIMES = 5;
          var DEFAULT_INTERVAL = 0;
  
          var attempts = [];
  
          var opts = {
              times: DEFAULT_TIMES,
              interval: DEFAULT_INTERVAL
          };
  
          function parseTimes(acc, t){
              if(typeof t === 'number'){
                  acc.times = parseInt(t, 10) || DEFAULT_TIMES;
              } else if(typeof t === 'object'){
                  acc.times = parseInt(t.times, 10) || DEFAULT_TIMES;
                  acc.interval = parseInt(t.interval, 10) || DEFAULT_INTERVAL;
              } else {
                  throw new Error('Unsupported argument type for \'times\': ' + typeof t);
              }
          }
  
          var length = arguments.length;
          if (length < 1 || length > 3) {
              throw new Error('Invalid arguments - must be either (task), (task, callback), (times, task) or (times, task, callback)');
          } else if (length <= 2 && typeof times === 'function') {
              callback = task;
              task = times;
          }
          if (typeof times !== 'function') {
              parseTimes(opts, times);
          }
          opts.callback = callback;
          opts.task = task;
  
          function wrappedTask(wrappedCallback, wrappedResults) {
              function retryAttempt(task, finalAttempt) {
                  return function(seriesCallback) {
                      task(function(err, result){
                          seriesCallback(!err || finalAttempt, {err: err, result: result});
                      }, wrappedResults);
                  };
              }
  
              function retryInterval(interval){
                  return function(seriesCallback){
                      setTimeout(function(){
                          seriesCallback(null);
                      }, interval);
                  };
              }
  
              while (opts.times) {
  
                  var finalAttempt = !(opts.times-=1);
                  attempts.push(retryAttempt(opts.task, finalAttempt));
                  if(!finalAttempt && opts.interval > 0){
                      attempts.push(retryInterval(opts.interval));
                  }
              }
  
              async.series(attempts, function(done, data){
                  data = data[data.length - 1];
                  (wrappedCallback || opts.callback)(data.err, data.result);
              });
          }
  
          // If a callback is passed, run this as a controll flow
          return opts.callback ? wrappedTask() : wrappedTask;
      };
  
      async.waterfall = function (tasks, callback) {
          callback = _once(callback || noop);
          if (!_isArray(tasks)) {
              var err = new Error('First argument to waterfall must be an array of functions');
              return callback(err);
          }
          if (!tasks.length) {
              return callback();
          }
          function wrapIterator(iterator) {
              return _restParam(function (err, args) {
                  if (err) {
                      callback.apply(null, [err].concat(args));
                  }
                  else {
                      var next = iterator.next();
                      if (next) {
                          args.push(wrapIterator(next));
                      }
                      else {
                          args.push(callback);
                      }
                      ensureAsync(iterator).apply(null, args);
                  }
              });
          }
          wrapIterator(async.iterator(tasks))();
      };
  
      function _parallel(eachfn, tasks, callback) {
          callback = callback || noop;
          var results = _isArrayLike(tasks) ? [] : {};
  
          eachfn(tasks, function (task, key, callback) {
              task(_restParam(function (err, args) {
                  if (args.length <= 1) {
                      args = args[0];
                  }
                  results[key] = args;
                  callback(err);
              }));
          }, function (err) {
              callback(err, results);
          });
      }
  
      async.parallel = function (tasks, callback) {
          _parallel(async.eachOf, tasks, callback);
      };
  
      async.parallelLimit = function(tasks, limit, callback) {
          _parallel(_eachOfLimit(limit), tasks, callback);
      };
  
      async.series = function(tasks, callback) {
          _parallel(async.eachOfSeries, tasks, callback);
      };
  
      async.iterator = function (tasks) {
          function makeCallback(index) {
              function fn() {
                  if (tasks.length) {
                      tasks[index].apply(null, arguments);
                  }
                  return fn.next();
              }
              fn.next = function () {
                  return (index < tasks.length - 1) ? makeCallback(index + 1): null;
              };
              return fn;
          }
          return makeCallback(0);
      };
  
      async.apply = _restParam(function (fn, args) {
          return _restParam(function (callArgs) {
              return fn.apply(
                  null, args.concat(callArgs)
              );
          });
      });
  
      function _concat(eachfn, arr, fn, callback) {
          var result = [];
          eachfn(arr, function (x, index, cb) {
              fn(x, function (err, y) {
                  result = result.concat(y || []);
                  cb(err);
              });
          }, function (err) {
              callback(err, result);
          });
      }
      async.concat = doParallel(_concat);
      async.concatSeries = doSeries(_concat);
  
      async.whilst = function (test, iterator, callback) {
          callback = callback || noop;
          if (test()) {
              var next = _restParam(function(err, args) {
                  if (err) {
                      callback(err);
                  } else if (test.apply(this, args)) {
                      iterator(next);
                  } else {
                      callback.apply(null, [null].concat(args));
                  }
              });
              iterator(next);
          } else {
              callback(null);
          }
      };
  
      async.doWhilst = function (iterator, test, callback) {
          var calls = 0;
          return async.whilst(function() {
              return ++calls <= 1 || test.apply(this, arguments);
          }, iterator, callback);
      };
  
      async.until = function (test, iterator, callback) {
          return async.whilst(function() {
              return !test.apply(this, arguments);
          }, iterator, callback);
      };
  
      async.doUntil = function (iterator, test, callback) {
          return async.doWhilst(iterator, function() {
              return !test.apply(this, arguments);
          }, callback);
      };
  
      async.during = function (test, iterator, callback) {
          callback = callback || noop;
  
          var next = _restParam(function(err, args) {
              if (err) {
                  callback(err);
              } else {
                  args.push(check);
                  test.apply(this, args);
              }
          });
  
          var check = function(err, truth) {
              if (err) {
                  callback(err);
              } else if (truth) {
                  iterator(next);
              } else {
                  callback(null);
              }
          };
  
          test(check);
      };
  
      async.doDuring = function (iterator, test, callback) {
          var calls = 0;
          async.during(function(next) {
              if (calls++ < 1) {
                  next(null, true);
              } else {
                  test.apply(this, arguments);
              }
          }, iterator, callback);
      };
  
      function _queue(worker, concurrency, payload) {
          if (concurrency == null) {
              concurrency = 1;
          }
          else if(concurrency === 0) {
              throw new Error('Concurrency must not be zero');
          }
          function _insert(q, data, pos, callback) {
              if (callback != null && typeof callback !== "function") {
                  throw new Error("task callback must be a function");
              }
              q.started = true;
              if (!_isArray(data)) {
                  data = [data];
              }
              if(data.length === 0 && q.idle()) {
                  // call drain immediately if there are no tasks
                  return async.setImmediate(function() {
                      q.drain();
                  });
              }
              _arrayEach(data, function(task) {
                  var item = {
                      data: task,
                      callback: callback || noop
                  };
  
                  if (pos) {
                      q.tasks.unshift(item);
                  } else {
                      q.tasks.push(item);
                  }
  
                  if (q.tasks.length === q.concurrency) {
                      q.saturated();
                  }
              });
              async.setImmediate(q.process);
          }
          function _next(q, tasks) {
              return function(){
                  workers -= 1;
  
                  var removed = false;
                  var args = arguments;
                  _arrayEach(tasks, function (task) {
                      _arrayEach(workersList, function (worker, index) {
                          if (worker === task && !removed) {
                              workersList.splice(index, 1);
                              removed = true;
                          }
                      });
  
                      task.callback.apply(task, args);
                  });
                  if (q.tasks.length + workers === 0) {
                      q.drain();
                  }
                  q.process();
              };
          }
  
          var workers = 0;
          var workersList = [];
          var q = {
              tasks: [],
              concurrency: concurrency,
              payload: payload,
              saturated: noop,
              empty: noop,
              drain: noop,
              started: false,
              paused: false,
              push: function (data, callback) {
                  _insert(q, data, false, callback);
              },
              kill: function () {
                  q.drain = noop;
                  q.tasks = [];
              },
              unshift: function (data, callback) {
                  _insert(q, data, true, callback);
              },
              process: function () {
                  while(!q.paused && workers < q.concurrency && q.tasks.length){
  
                      var tasks = q.payload ?
                          q.tasks.splice(0, q.payload) :
                          q.tasks.splice(0, q.tasks.length);
  
                      var data = _map(tasks, function (task) {
                          return task.data;
                      });
  
                      if (q.tasks.length === 0) {
                          q.empty();
                      }
                      workers += 1;
                      workersList.push(tasks[0]);
                      var cb = only_once(_next(q, tasks));
                      worker(data, cb);
                  }
              },
              length: function () {
                  return q.tasks.length;
              },
              running: function () {
                  return workers;
              },
              workersList: function () {
                  return workersList;
              },
              idle: function() {
                  return q.tasks.length + workers === 0;
              },
              pause: function () {
                  q.paused = true;
              },
              resume: function () {
                  if (q.paused === false) { return; }
                  q.paused = false;
                  var resumeCount = Math.min(q.concurrency, q.tasks.length);
                  // Need to call q.process once per concurrent
                  // worker to preserve full concurrency after pause
                  for (var w = 1; w <= resumeCount; w++) {
                      async.setImmediate(q.process);
                  }
              }
          };
          return q;
      }
  
      async.queue = function (worker, concurrency) {
          var q = _queue(function (items, cb) {
              worker(items[0], cb);
          }, concurrency, 1);
  
          return q;
      };
  
      async.priorityQueue = function (worker, concurrency) {
  
          function _compareTasks(a, b){
              return a.priority - b.priority;
          }
  
          function _binarySearch(sequence, item, compare) {
              var beg = -1,
                  end = sequence.length - 1;
              while (beg < end) {
                  var mid = beg + ((end - beg + 1) >>> 1);
                  if (compare(item, sequence[mid]) >= 0) {
                      beg = mid;
                  } else {
                      end = mid - 1;
                  }
              }
              return beg;
          }
  
          function _insert(q, data, priority, callback) {
              if (callback != null && typeof callback !== "function") {
                  throw new Error("task callback must be a function");
              }
              q.started = true;
              if (!_isArray(data)) {
                  data = [data];
              }
              if(data.length === 0) {
                  // call drain immediately if there are no tasks
                  return async.setImmediate(function() {
                      q.drain();
                  });
              }
              _arrayEach(data, function(task) {
                  var item = {
                      data: task,
                      priority: priority,
                      callback: typeof callback === 'function' ? callback : noop
                  };
  
                  q.tasks.splice(_binarySearch(q.tasks, item, _compareTasks) + 1, 0, item);
  
                  if (q.tasks.length === q.concurrency) {
                      q.saturated();
                  }
                  async.setImmediate(q.process);
              });
          }
  
          // Start with a normal queue
          var q = async.queue(worker, concurrency);
  
          // Override push to accept second parameter representing priority
          q.push = function (data, priority, callback) {
              _insert(q, data, priority, callback);
          };
  
          // Remove unshift function
          delete q.unshift;
  
          return q;
      };
  
      async.cargo = function (worker, payload) {
          return _queue(worker, 1, payload);
      };
  
      function _console_fn(name) {
          return _restParam(function (fn, args) {
              fn.apply(null, args.concat([_restParam(function (err, args) {
                  if (typeof console === 'object') {
                      if (err) {
                          if (console.error) {
                              console.error(err);
                          }
                      }
                      else if (console[name]) {
                          _arrayEach(args, function (x) {
                              console[name](x);
                          });
                      }
                  }
              })]));
          });
      }
      async.log = _console_fn('log');
      async.dir = _console_fn('dir');
      /*async.info = _console_fn('info');
      async.warn = _console_fn('warn');
      async.error = _console_fn('error');*/
  
      async.memoize = function (fn, hasher) {
          var memo = {};
          var queues = {};
          var has = Object.prototype.hasOwnProperty;
          hasher = hasher || identity;
          var memoized = _restParam(function memoized(args) {
              var callback = args.pop();
              var key = hasher.apply(null, args);
              if (has.call(memo, key)) {   
                  async.setImmediate(function () {
                      callback.apply(null, memo[key]);
                  });
              }
              else if (has.call(queues, key)) {
                  queues[key].push(callback);
              }
              else {
                  queues[key] = [callback];
                  fn.apply(null, args.concat([_restParam(function (args) {
                      memo[key] = args;
                      var q = queues[key];
                      delete queues[key];
                      for (var i = 0, l = q.length; i < l; i++) {
                          q[i].apply(null, args);
                      }
                  })]));
              }
          });
          memoized.memo = memo;
          memoized.unmemoized = fn;
          return memoized;
      };
  
      async.unmemoize = function (fn) {
          return function () {
              return (fn.unmemoized || fn).apply(null, arguments);
          };
      };
  
      function _times(mapper) {
          return function (count, iterator, callback) {
              mapper(_range(count), iterator, callback);
          };
      }
  
      async.times = _times(async.map);
      async.timesSeries = _times(async.mapSeries);
      async.timesLimit = function (count, limit, iterator, callback) {
          return async.mapLimit(_range(count), limit, iterator, callback);
      };
  
      async.seq = function (/* functions... */) {
          var fns = arguments;
          return _restParam(function (args) {
              var that = this;
  
              var callback = args[args.length - 1];
              if (typeof callback == 'function') {
                  args.pop();
              } else {
                  callback = noop;
              }
  
              async.reduce(fns, args, function (newargs, fn, cb) {
                  fn.apply(that, newargs.concat([_restParam(function (err, nextargs) {
                      cb(err, nextargs);
                  })]));
              },
              function (err, results) {
                  callback.apply(that, [err].concat(results));
              });
          });
      };
  
      async.compose = function (/* functions... */) {
          return async.seq.apply(null, Array.prototype.reverse.call(arguments));
      };
  
  
      function _applyEach(eachfn) {
          return _restParam(function(fns, args) {
              var go = _restParam(function(args) {
                  var that = this;
                  var callback = args.pop();
                  return eachfn(fns, function (fn, _, cb) {
                      fn.apply(that, args.concat([cb]));
                  },
                  callback);
              });
              if (args.length) {
                  return go.apply(this, args);
              }
              else {
                  return go;
              }
          });
      }
  
      async.applyEach = _applyEach(async.eachOf);
      async.applyEachSeries = _applyEach(async.eachOfSeries);
  
  
      async.forever = function (fn, callback) {
          var done = only_once(callback || noop);
          var task = ensureAsync(fn);
          function next(err) {
              if (err) {
                  return done(err);
              }
              task(next);
          }
          next();
      };
  
      function ensureAsync(fn) {
          return _restParam(function (args) {
              var callback = args.pop();
              args.push(function () {
                  var innerArgs = arguments;
                  if (sync) {
                      async.setImmediate(function () {
                          callback.apply(null, innerArgs);
                      });
                  } else {
                      callback.apply(null, innerArgs);
                  }
              });
              var sync = true;
              fn.apply(this, args);
              sync = false;
          });
      }
  
      async.ensureAsync = ensureAsync;
  
      async.constant = _restParam(function(values) {
          var args = [null].concat(values);
          return function (callback) {
              return callback.apply(this, args);
          };
      });
  
      async.wrapSync =
      async.asyncify = function asyncify(func) {
          return _restParam(function (args) {
              var callback = args.pop();
              var result;
              try {
                  result = func.apply(this, args);
              } catch (e) {
                  return callback(e);
              }
              // if result is Promise object
              if (_isObject(result) && typeof result.then === "function") {
                  result.then(function(value) {
                      callback(null, value);
                  })["catch"](function(err) {
                      callback(err.message ? err : new Error(err));
                  });
              } else {
                  callback(null, result);
              }
          });
      };
  
      // Node.js
      if (typeof module === 'object' && module.exports) {
          module.exports = async;
      }
      // AMD / RequireJS
      else if (typeof define === 'function' && define.amd) {
          define([], function () {
              return async;
          });
      }
      // included directly via <script> tag
      else {
          root.async = async;
      }
  
  }());
  
  }).call(this,require('_process'),typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
  },{"_process":4}],4:[function(require,module,exports){
  // shim for using process in browser
  
  var process = module.exports = {};
  var queue = [];
  var draining = false;
  
  function drainQueue() {
      if (draining) {
          return;
      }
      draining = true;
      var currentQueue;
      var len = queue.length;
      while(len) {
          currentQueue = queue;
          queue = [];
          var i = -1;
          while (++i < len) {
              currentQueue[i]();
          }
          len = queue.length;
      }
      draining = false;
  }
  process.nextTick = function (fun) {
      queue.push(fun);
      if (!draining) {
          setTimeout(drainQueue, 0);
      }
  };
  
  process.title = 'browser';
  process.browser = true;
  process.env = {};
  process.argv = [];
  process.version = ''; // empty string to avoid regexp issues
  process.versions = {};
  
  function noop() {}
  
  process.on = noop;
  process.addListener = noop;
  process.once = noop;
  process.off = noop;
  process.removeListener = noop;
  process.removeAllListeners = noop;
  process.emit = noop;
  
  process.binding = function (name) {
      throw new Error('process.binding is not supported');
  };
  
  // TODO(shtylman)
  process.cwd = function () { return '/' };
  process.chdir = function (dir) {
      throw new Error('process.chdir is not supported');
  };
  process.umask = function() { return 0; };
  
  },{}],5:[function(require,module,exports){
  // Copyright Joyent, Inc. and other Node contributors.
  //
  // Permission is hereby granted, free of charge, to any person obtaining a
  // copy of this software and associated documentation files (the
  // "Software"), to deal in the Software without restriction, including
  // without limitation the rights to use, copy, modify, merge, publish,
  // distribute, sublicense, and/or sell copies of the Software, and to permit
  // persons to whom the Software is furnished to do so, subject to the
  // following conditions:
  //
  // The above copyright notice and this permission notice shall be included
  // in all copies or substantial portions of the Software.
  //
  // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
  // NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
  // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
  // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
  // USE OR OTHER DEALINGS IN THE SOFTWARE.
  
  'use strict';
  
  // If obj.hasOwnProperty has been overridden, then calling
  // obj.hasOwnProperty(prop) will break.
  // See: https://github.com/joyent/node/issues/1707
  function hasOwnProperty(obj, prop) {
    return Object.prototype.hasOwnProperty.call(obj, prop);
  }
  
  module.exports = function(qs, sep, eq, options) {
    sep = sep || '&';
    eq = eq || '=';
    var obj = {};
  
    if (typeof qs !== 'string' || qs.length === 0) {
      return obj;
    }
  
    var regexp = /\+/g;
    qs = qs.split(sep);
  
    var maxKeys = 1000;
    if (options && typeof options.maxKeys === 'number') {
      maxKeys = options.maxKeys;
    }
  
    var len = qs.length;
    // maxKeys <= 0 means that we should not limit keys count
    if (maxKeys > 0 && len > maxKeys) {
      len = maxKeys;
    }
  
    for (var i = 0; i < len; ++i) {
      var x = qs[i].replace(regexp, '%20'),
          idx = x.indexOf(eq),
          kstr, vstr, k, v;
  
      if (idx >= 0) {
        kstr = x.substr(0, idx);
        vstr = x.substr(idx + 1);
      } else {
        kstr = x;
        vstr = '';
      }
  
      k = decodeURIComponent(kstr);
      v = decodeURIComponent(vstr);
  
      if (!hasOwnProperty(obj, k)) {
        obj[k] = v;
      } else if (isArray(obj[k])) {
        obj[k].push(v);
      } else {
        obj[k] = [obj[k], v];
      }
    }
  
    return obj;
  };
  
  var isArray = Array.isArray || function (xs) {
    return Object.prototype.toString.call(xs) === '[object Array]';
  };
  
  },{}],6:[function(require,module,exports){
  // Copyright Joyent, Inc. and other Node contributors.
  //
  // Permission is hereby granted, free of charge, to any person obtaining a
  // copy of this software and associated documentation files (the
  // "Software"), to deal in the Software without restriction, including
  // without limitation the rights to use, copy, modify, merge, publish,
  // distribute, sublicense, and/or sell copies of the Software, and to permit
  // persons to whom the Software is furnished to do so, subject to the
  // following conditions:
  //
  // The above copyright notice and this permission notice shall be included
  // in all copies or substantial portions of the Software.
  //
  // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
  // NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
  // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
  // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
  // USE OR OTHER DEALINGS IN THE SOFTWARE.
  
  'use strict';
  
  var stringifyPrimitive = function(v) {
    switch (typeof v) {
      case 'string':
        return v;
  
      case 'boolean':
        return v ? 'true' : 'false';
  
      case 'number':
        return isFinite(v) ? v : '';
  
      default:
        return '';
    }
  };
  
  module.exports = function(obj, sep, eq, name) {
    sep = sep || '&';
    eq = eq || '=';
    if (obj === null) {
      obj = undefined;
    }
  
    if (typeof obj === 'object') {
      return map(objectKeys(obj), function(k) {
        var ks = encodeURIComponent(stringifyPrimitive(k)) + eq;
        if (isArray(obj[k])) {
          return map(obj[k], function(v) {
            return ks + encodeURIComponent(stringifyPrimitive(v));
          }).join(sep);
        } else {
          return ks + encodeURIComponent(stringifyPrimitive(obj[k]));
        }
      }).join(sep);
  
    }
  
    if (!name) return '';
    return encodeURIComponent(stringifyPrimitive(name)) + eq +
           encodeURIComponent(stringifyPrimitive(obj));
  };
  
  var isArray = Array.isArray || function (xs) {
    return Object.prototype.toString.call(xs) === '[object Array]';
  };
  
  function map (xs, f) {
    if (xs.map) return xs.map(f);
    var res = [];
    for (var i = 0; i < xs.length; i++) {
      res.push(f(xs[i], i));
    }
    return res;
  }
  
  var objectKeys = Object.keys || function (obj) {
    var res = [];
    for (var key in obj) {
      if (Object.prototype.hasOwnProperty.call(obj, key)) res.push(key);
    }
    return res;
  };
  
  },{}],7:[function(require,module,exports){
  'use strict';
  
  exports.decode = exports.parse = require('./decode');
  exports.encode = exports.stringify = require('./encode');
  
  },{"./decode":5,"./encode":6}],8:[function(require,module,exports){
  var async = require("async");
  var fetch_1 = require("../../../../SupClient/src/fetch");
  var Player = (function () {
      function Player(canvas, dataURL, options) {
          var _this = this;
          this.entriesById = {};
          this.entriesByPath = {};
          this.resources = {};
          this.assetsById = {};
          this.outerAssetsById = {};
          this.tick = function (timestamp) {
              if (timestamp === void 0) { timestamp = 0; }
              _this.tickAnimationFrameId = requestAnimationFrame(_this.tick);
              _this.accumulatedTime += timestamp - _this.lastTimestamp;
              _this.lastTimestamp = timestamp;
              var _a = _this.gameInstance.tick(_this.accumulatedTime), updates = _a.updates, timeLeft = _a.timeLeft;
              _this.accumulatedTime = timeLeft;
              if (_this.gameInstance.input.exited) {
                  cancelAnimationFrame(_this.tickAnimationFrameId);
                  return;
              }
              if (updates > 0)
                  _this.gameInstance.draw();
          };
          this.canvas = canvas;
          this.dataURL = dataURL;
          options.enableOnExit = true;
          this.gameInstance = new SupEngine.GameInstance(this.canvas, options);
      }
      Player.prototype.load = function (progressCallback, callback) {
          var _this = this;
          var progress = 0;
          var innerProgressCallback = function () {
              progress++;
              var total = _this.resourcesToLoad.length + _this.assetsToLoad.length;
              progressCallback(progress, total);
          };
          async.series([
              function (cb) { _this._loadManifest(cb); },
              function (cb) { _this._loadResources(innerProgressCallback, cb); },
              function (cb) { _this._loadAssets(innerProgressCallback, cb); },
              function (cb) { _this._initPlugins(cb); },
              function (cb) { _this._startPlugins(cb); },
              function (cb) { _this._lateStartPlugins(cb); }
          ], callback);
      };
      Player.prototype._loadManifest = function (callback) {
          var _this = this;
          this.getAssetData("project.json", "json", function (err, project) {
              if (err != null) {
                  callback(new Error("Failed to load game manifest"));
                  return;
              }
              _this.gameName = project.name;
              document.title = project.name;
              _this.resourcesToLoad = Object.keys(SupRuntime.resourcePlugins);
              _this.assetsToLoad = [];
              var walk = function (asset, parent, storagePath) {
                  if (parent === void 0) { parent = ""; }
                  if (storagePath === void 0) { storagePath = ""; }
                  var children;
                  if (asset.children != null) {
                      children = [];
                      for (var _i = 0, _a = asset.children; _i < _a.length; _i++) {
                          var child = _a[_i];
                          children.push(child.name);
                      }
                  }
                  var path = "" + parent + asset.name;
                  storagePath += asset.name + " (" + asset.id + ")";
                  _this.assetsToLoad.push({ id: asset.id, name: asset.name, path: path, storagePath: storagePath, type: asset.type, children: children });
                  parent += asset.name + "/";
                  storagePath += "/";
                  if (asset.children == null)
                      return;
                  for (var _b = 0, _c = asset.children; _b < _c.length; _b++) {
                      var child = _c[_b];
                      walk(child, parent, storagePath);
                  }
              };
              for (var _i = 0, _a = project.assets; _i < _a.length; _i++) {
                  var asset = _a[_i];
                  walk(asset);
              }
              callback();
          });
      };
      Player.prototype._loadResources = function (progressCallback, callback) {
          var _this = this;
          if (this.resourcesToLoad.length === 0) {
              callback();
              return;
          }
          var resourcesLoaded = 0;
          var onResourceLoaded = function (err, resourceName, resource) {
              if (err != null) {
                  callback(new Error("Failed to load resource " + resourceName + ": " + err.message));
                  return;
              }
              _this.resources[resourceName] = resource;
              progressCallback();
              resourcesLoaded++;
              if (resourcesLoaded === _this.resourcesToLoad.length)
                  callback();
          };
          // NOTE: Have to use .forEach because of TS4091 (closure references block-scoped variable)
          this.resourcesToLoad.forEach(function (resourceName) {
              var plugin = SupRuntime.resourcePlugins[resourceName];
              if (plugin == null) {
                  // This resource isn't meant to be loaded at runtime, skip
                  onResourceLoaded(null, resourceName, null);
                  return;
              }
              plugin.loadResource(_this, resourceName, function (err, data) { onResourceLoaded(err, resourceName, data); });
          });
      };
      Player.prototype._loadAssets = function (progressCallback, callback) {
          var _this = this;
          if (this.gameInstance.threeRenderer == null) {
              callback(new Error("Failed to initialize renderer. Your device might not support WebGL."));
              return;
          }
          if (this.assetsToLoad.length === 0) {
              callback();
              return;
          }
          var assetsLoaded = 0;
          var onAssetLoaded = function (err, entry, asset) {
              if (err != null) {
                  callback(new Error("Failed to load asset " + entry.path + ": " + err.message));
                  return;
              }
              _this.entriesById[entry.id] = entry;
              _this.entriesByPath[entry.path] = entry;
              _this.assetsById[entry.id] = asset;
              progressCallback();
              assetsLoaded++;
              if (assetsLoaded === _this.assetsToLoad.length)
                  callback();
          };
          // NOTE: Have to use .forEach because of TS4091 (closure references block-scoped variable)
          this.assetsToLoad.forEach(function (entry) {
              if (entry.children != null) {
                  onAssetLoaded(null, entry, {});
                  return;
              }
              var plugin = SupRuntime.plugins[entry.type];
              if (plugin == null || plugin.loadAsset == null) {
                  console.warn("Don't know how to load assets of type \"" + entry.type + "\"");
                  onAssetLoaded(null, entry, {});
                  return;
              }
              plugin.loadAsset(_this, entry, function (err, data) { onAssetLoaded(err, entry, data); });
          });
      };
      Player.prototype._initPlugins = function (callback) {
          var _this = this;
          async.each(Object.keys(SupRuntime.plugins), function (name, cb) {
              var plugin = SupRuntime.plugins[name];
              if (plugin.init != null)
                  plugin.init(_this, cb);
              else
                  cb();
          }, callback);
      };
      Player.prototype._startPlugins = function (callback) {
          var _this = this;
          async.each(Object.keys(SupRuntime.plugins), function (name, cb) {
              var plugin = SupRuntime.plugins[name];
              if (plugin.start != null)
                  plugin.start(_this, cb);
              else
                  cb();
          }, callback);
      };
      Player.prototype._lateStartPlugins = function (callback) {
          var _this = this;
          async.each(Object.keys(SupRuntime.plugins), function (name, cb) {
              var plugin = SupRuntime.plugins[name];
              if (plugin.lateStart != null)
                  plugin.lateStart(_this, cb);
              else
                  cb();
          }, callback);
      };
      Player.prototype.run = function () {
          this.lastTimestamp = 0;
          this.accumulatedTime = 0;
          this.canvas.focus();
          this.tick();
      };
      Player.prototype.getAssetData = function (path, responseType, callback) {
          fetch_1.default("" + this.dataURL + path, responseType, callback);
      };
      Player.prototype.getOuterAsset = function (assetId) {
          var outerAsset = this.outerAssetsById[assetId];
          var asset = this.assetsById[assetId];
          var entry = this.entriesById[assetId];
          if (outerAsset == null && asset != null) {
              if (entry.type == null) {
                  outerAsset = { name: entry.name, path: entry.path, type: "folder", children: entry.children };
              }
              else {
                  var plugin = SupRuntime.plugins[this.entriesById[assetId].type];
                  outerAsset = this.outerAssetsById[assetId] =
                      // Temporary check until every asset is correctly handled
                      (plugin.createOuterAsset != null) ? plugin.createOuterAsset(this, asset) : asset;
                  outerAsset.name = entry.name;
                  outerAsset.path = entry.path;
                  outerAsset.type = entry.type;
              }
          }
          return outerAsset;
      };
      Player.prototype.createActor = function () { throw new Error("Player.createActor should be defined by a scripting plugin"); };
      Player.prototype.createComponent = function () { throw new Error("Player.createComponent should be defined by a scripting plugin"); };
      return Player;
  })();
  Object.defineProperty(exports, "__esModule", { value: true });
  exports.default = Player;
  
  },{"../../../../SupClient/src/fetch":2,"async":3}]},{},[1])(1)
  });