System.register(['lang', './utils.js', 'src/client/reactive/active-expression/active-expression.js', 'systemjs-babel-build', 'babel-plugin-syntax-jsx', 'babel-plugin-syntax-do-expressions', 'babel-plugin-syntax-function-bind', 'babel-plugin-syntax-async-generators', 'src/client/bound-eval.js', 'active-expression-rewriting'], function (_export, _context) {
  "use strict";

  var extend, AExprRegistry, babelDefault, jsx, doExpressions, functionBind, asyncGenerators, boundEval, aexpr;
  return {
    setters: [function (_lang) {}, function (_utilsJs) {
      extend = _utilsJs.extend;
    }, function (_srcClientReactiveActiveExpressionActiveExpressionJs) {
      AExprRegistry = _srcClientReactiveActiveExpressionActiveExpressionJs.AExprRegistry;
    }, function (_systemjsBabelBuild) {
      babelDefault = _systemjsBabelBuild.default;
    }, function (_babelPluginSyntaxJsx) {
      jsx = _babelPluginSyntaxJsx.default;
    }, function (_babelPluginSyntaxDoExpressions) {
      doExpressions = _babelPluginSyntaxDoExpressions.default;
    }, function (_babelPluginSyntaxFunctionBind) {
      functionBind = _babelPluginSyntaxFunctionBind.default;
    }, function (_babelPluginSyntaxAsyncGenerators) {
      asyncGenerators = _babelPluginSyntaxAsyncGenerators.default;
    }, function (_srcClientBoundEvalJs) {
      boundEval = _srcClientBoundEvalJs.default;
    }, function (_activeExpressionRewriting) {
      aexpr = _activeExpressionRewriting.default;
    }],
    execute: function () {
      _recorder_._src_client_lang_lang_ext_js = _recorder_._src_client_lang_lang_ext_js || {};
      _recorder_._src_client_lang_lang_ext_js.extend = extend;
      _recorder_._src_client_lang_lang_ext_js.AExprRegistry = AExprRegistry;
      _recorder_._src_client_lang_lang_ext_js.babelDefault = babelDefault;

      const babel = _recorder_._src_client_lang_lang_ext_js.babelDefault.babel;

      _recorder_._src_client_lang_lang_ext_js.babel = babel;
      _recorder_._src_client_lang_lang_ext_js.jsx = jsx;
      _recorder_._src_client_lang_lang_ext_js.doExpressions = doExpressions;
      _recorder_._src_client_lang_lang_ext_js.functionBind = functionBind;
      _recorder_._src_client_lang_lang_ext_js.asyncGenerators = asyncGenerators;

      const SYNTAX_PLUGINS = [_recorder_._src_client_lang_lang_ext_js.jsx, _recorder_._src_client_lang_lang_ext_js.doExpressions, _recorder_._src_client_lang_lang_ext_js.functionBind, _recorder_._src_client_lang_lang_ext_js.asyncGenerators];

      _recorder_._src_client_lang_lang_ext_js.SYNTAX_PLUGINS = SYNTAX_PLUGINS;
      const filename = "tempfile.js";
      _recorder_._src_client_lang_lang_ext_js.filename = filename;
      const BABEL_CONFIG_DEFAULT = {
        babelrc: false,
        plugins: _recorder_._src_client_lang_lang_ext_js.SYNTAX_PLUGINS,
        presets: [],
        filename: _recorder_._src_client_lang_lang_ext_js.filename,
        sourceFileName: _recorder_._src_client_lang_lang_ext_js.filename,
        moduleIds: false,
        sourceMaps: true,
        // inputSourceMap: load.metadata.sourceMap,
        compact: false,
        comments: true,
        code: true,
        ast: true,
        resolveModuleSource: undefined
      };

      _recorder_._src_client_lang_lang_ext_js.BABEL_CONFIG_DEFAULT = BABEL_CONFIG_DEFAULT;
      _recorder_._src_client_lang_lang_ext_js.extend(Object.prototype, {

        dependentAExprs() {
          return _recorder_._src_client_lang_lang_ext_js.AExprRegistry.allAsArray().filter(ae => {
            if (!ae.supportsDependencies()) {
              return false;
            }

            const dependencies = ae.dependencies().all();
            return dependencies.find(dep => {
              const desc = dep.getAsDependencyDescription();
              return desc.object === this || desc.value === this || desc.scope === this;
            });
          });
        },

        transformAsAST(fullPluginOrVisitor) {
          const iteratorPlugin = fullPluginOrVisitor instanceof Function ? fullPluginOrVisitor :
          // only got the visitor: need to bridge to a plugin function as expected by babel
          () => ({ visitor: fullPluginOrVisitor });

          const babelConfig = Object.assign({}, _recorder_._src_client_lang_lang_ext_js.BABEL_CONFIG_DEFAULT, {
            plugins: [..._recorder_._src_client_lang_lang_ext_js.SYNTAX_PLUGINS, iteratorPlugin]
          });

          return _recorder_._src_client_lang_lang_ext_js.babel.transformFromAst(this, undefined, babelConfig);
        },

        // using `babel.traverse` also allows for wild cards to match AST nodes
        traverseAsAST(visitor) {
          return _recorder_._src_client_lang_lang_ext_js.babel.traverse(this, visitor);
        }

      });

      /*MD
      ## STRING
      MD*/

      _recorder_._src_client_lang_lang_ext_js.boundEval = boundEval;


      _recorder_._src_client_lang_lang_ext_js.extend(String.prototype, {

        toAST() {
          return _recorder_._src_client_lang_lang_ext_js.babel.transform(this, _recorder_._src_client_lang_lang_ext_js.BABEL_CONFIG_DEFAULT).ast;
        },

        /**
         * @example providing a visitor object
         * var ids = [];
         * `let x = 0, y = x +2;`.transformAsAST({
         *   Identifier(path) {
         *     ids.push(path.node.name);
         *   }
         * });
         * ids;
         * 
         * @example providing a full-fledged plugin function
         * var ids = [];
         * `let x = 0, y = x +2;`.transformAsAST(({ types: t, template, traverse }) => ({
         *   visitor: {
         *     Identifier(path) {
         *       ids.push(path.node.name);
         *     }
         *   }
         * }));
         * ids;
         */
        transformAsAST(fullPluginOrVisitor) {
          return this.toAST().transformAsAST(fullPluginOrVisitor);
        },

        /*
         * @example printing all node types found in source code
         * `var a = 42, b = 423; lively::foo`.traverseAsAST({
         *    enter(path) {
         *      lively.notify(path.node.type)
         *    }
         *  });
         */
        traverseAsAST(visitor) {
          return this.toAST().traverseAsAST(visitor);
        },

        async boundEval(thisReference, targetModule) {
          const result = await _recorder_._src_client_lang_lang_ext_js.boundEval(this, thisReference, targetModule);
          if (result.isError) {
            throw result.value;
          } else {
            return result.value;
          }
        }

      });

      /*MD
      ## FUNCTION
      MD*/
      _recorder_._src_client_lang_lang_ext_js.aexpr = aexpr;


      const aexprByFunction = new WeakMap();

      _recorder_._src_client_lang_lang_ext_js.aexprByFunction = aexprByFunction;
      _recorder_._src_client_lang_lang_ext_js.extend(Function.prototype, {

        asAExpr() {
          return _recorder_._src_client_lang_lang_ext_js.aexprByFunction.getOrCreate(this, () => _recorder_._src_client_lang_lang_ext_js.aexpr(this));
        },

        onChange(callback) {
          return this.asAExpr().onChange(callback);
        },

        onBecomeTrue(callback) {
          return this.asAExpr().onBecomeTrue(callback);
        },

        onBecomeFalse(callback) {
          return this.asAExpr().onBecomeFalse(callback);
        }

      });
    }
  };
});