System.register(['src/components/widgets/lively-morph.js', 'src/client/bound-eval.js', 'src/external/lodash/lodash.js', 'utils'], function (_export, _context) {
  "use strict";

  var Morph, boundEval, _, generateUuid, waitForDeepProperty, currentScriptPromises, moduleMap;

  return {
    setters: [function (_srcComponentsWidgetsLivelyMorphJs) {
      Morph = _srcComponentsWidgetsLivelyMorphJs.default;
    }, function (_srcClientBoundEvalJs) {
      boundEval = _srcClientBoundEvalJs.default;
    }, function (_srcExternalLodashLodashJs) {
      _ = _srcExternalLodashLodashJs.default;
    }, function (_utils) {
      generateUuid = _utils.uuid;
      waitForDeepProperty = _utils.waitForDeepProperty;
    }],
    execute: function () {
      _recorder_._src_components_widgets_lively_script_js = _recorder_._src_components_widgets_lively_script_js || {};
      _recorder_._src_components_widgets_lively_script_js.Morph = Morph;
      _recorder_._src_components_widgets_lively_script_js.boundEval = boundEval;
      _recorder_._src_components_widgets_lively_script_js._ = _;
      _recorder_._src_components_widgets_lively_script_js.waitForDeepProperty = waitForDeepProperty;
      _recorder_._src_components_widgets_lively_script_js.generateUuid = generateUuid;

      _export('currentScriptPromises', currentScriptPromises = []);

      _export('currentScriptPromises', currentScriptPromises);

      _recorder_._src_components_widgets_lively_script_js.currentScriptPromises = currentScriptPromises;

      _export('moduleMap', moduleMap = new Map());

      _export('moduleMap', moduleMap);

      _recorder_._src_components_widgets_lively_script_js.moduleMap = moduleMap;
      class LivelyScript extends _recorder_._src_components_widgets_lively_script_js.Morph {

        async initialize() {
          var src = this.textContent;
          // console.log("LivelyScript>>initialize " + src)

          this.get("#result").innerHTML = `[pending exec script${this.id ? " " + this.id : ""}]`;
          var result = await this.boundEval(src);
          if (result.isError) {
            lively.showError(result.value);
            this.get("#result").innerHTML = "<lively-error><pre>" + result.value + "</pre></lively-error>";
            return;
          }

          if (result.value && result.value.then) {
            result.value = await result.value;
          }

          if (result.value instanceof HTMLElement && result.value !== this) {
            this.get("#result").innerHTML = "";
            this.get("#result").appendChild(result.value);
          } else if (result.value !== undefined) {
            this.get("#result").innerHTML = "" + result.value;
          } else {
            this.get("#result").innerHTML = "";
          }
        }

        async moduleFor(obj) {
          var moduleName = _recorder_._src_components_widgets_lively_script_js.moduleMap.get(obj);
          if (!moduleName) {
            var container = lively.query(this, "lively-container");
            if (container) {

              await _recorder_._src_components_widgets_lively_script_js.waitForDeepProperty(container, "getURL");
              container.livelyScriptContainerId = container.livelyScriptContainerId || _recorder_._src_components_widgets_lively_script_js.generateUuid();

              // all scripts in one container share the same module... but a second container will get a different module
              moduleName = (container.getURL() || lively4url).toString() + "_" + container.livelyScriptContainerId;
            } else {
              // no container, so we assume lively4 as root
              moduleName = lively4url + "/livelyscript_" + _recorder_._src_components_widgets_lively_script_js.generateUuid(); // so that some relative urls work...
            }
            _recorder_._src_components_widgets_lively_script_js.moduleMap.set(obj, moduleName);
          }
          return moduleName;
        }

        async boundEval(str) {
          // console.log("" + this.id + ">>boundEval " + str )
          var targetModule = await this.moduleFor(lively.findWorldContext(this) // all scripts in one container should share scope? 

          );var resolveMe;
          if (_recorder_._src_components_widgets_lively_script_js.currentScriptPromises.length > 0) {
            // console.log("script wait on " + currentScriptPromise)
            var last = _recorder_._src_components_widgets_lively_script_js._.last(_recorder_._src_components_widgets_lively_script_js.currentScriptPromises); // wait on each other... scripts can only be executed sequencitally?
          }
          var myPromise = new Promise(resolve => {
            resolveMe = resolve;
          });
          _recorder_._src_components_widgets_lively_script_js.currentScriptPromises.push(myPromise);
          if (last) {
            // console.log("wait on last: " + last)
            await last;
          }
          // console.log("" + this.id + ">>boundEval exec " + str, targetModule )
          var myPromisedResult = _recorder_._src_components_widgets_lively_script_js.boundEval(str, this, targetModule);
          myPromisedResult.then(() => {
            var first = _recorder_._src_components_widgets_lively_script_js.currentScriptPromises.shift();
            if (first !== myPromise) {
              _recorder_._src_components_widgets_lively_script_js.currentScriptPromises = [];
              throw new Error("LivelyScript execution order broken, resetting it...");
            }
            resolveMe();
          });
          return myPromisedResult;
        }

        toString() {
          return "[LivelyScript]";
        }

        livelyExample() {
          this.textContent = "3 + 4";
          this.initialize();
        }

      }

      _export('default', LivelyScript);

      _recorder_._src_components_widgets_lively_script_js.LivelyScript = LivelyScript;
    }
  };
});