text: "use strict";
  
  exports.__esModule = true;
  
  var _getIterator2 = require("babel-runtime/core-js/get-iterator");
  
  var _getIterator3 = _interopRequireDefault(_getIterator2);
  
  exports.call = call;
  exports._call = _call;
  exports.isBlacklisted = isBlacklisted;
  exports.visit = visit;
  exports.skip = skip;
  exports.skipKey = skipKey;
  exports.stop = stop;
  exports.setScope = setScope;
  exports.setContext = setContext;
  exports.resync = resync;
  exports._resyncParent = _resyncParent;
  exports._resyncKey = _resyncKey;
  exports._resyncList = _resyncList;
  exports._resyncRemoved = _resyncRemoved;
  exports.popContext = popContext;
  exports.pushContext = pushContext;
  exports.setup = setup;
  exports.setKey = setKey;
  exports.requeue = requeue;
  exports._getQueueContexts = _getQueueContexts;
  
  var _index = require("../index");
  
  var _index2 = _interopRequireDefault(_index);
  
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
  
  function call(key) {
    var opts = this.opts;
  
    this.debug(function () {
      return key;
    });
  
    if (this.node) {
      if (this._call(opts[key])) return true;
    }
  
    if (this.node) {
      return this._call(opts[this.node.type] && opts[this.node.type][key]);
    }
  
    return false;
  }
  
  function _call(fns) {
    if (!fns) return false;
  
    for (var _iterator = fns, _isArray = Array.isArray(_iterator), _i = 0, _iterator = _isArray ? _iterator : (0, _getIterator3.default)(_iterator);;) {
      var _ref;
  
      if (_isArray) {
        if (_i >= _iterator.length) break;
        _ref = _iterator[_i++];
      } else {
        _i = _iterator.next();
        if (_i.done) break;
        _ref = _i.value;
      }
  
      var fn = _ref;
  
      if (!fn) continue;
  
      var node = this.node;
      if (!node) return true;
  
      var ret = fn.call(this.state, this, this.state);
      if (ret) throw new Error("Unexpected return value from visitor method " + fn);
  
      if (this.node !== node) return true;
  
      if (this.shouldStop || this.shouldSkip || this.removed) return true;
    }
  
    return false;
  }
  
  function isBlacklisted() {
    var blacklist = this.opts.blacklist;
    return blacklist && blacklist.indexOf(this.node.type) > -1;
  }
  
  function visit() {
    if (!this.node) {
      return false;
    }
  
    if (this.isBlacklisted()) {
      return false;
    }
  
    if (this.opts.shouldSkip && this.opts.shouldSkip(this)) {
      return false;
    }
  
    if (this.call("enter") || this.shouldSkip) {
      this.debug(function () {
        return "Skip...";
      });
      return this.shouldStop;
    }
  
    this.debug(function () {
      return "Recursing into...";
    });
    _index2.default.node(this.node, this.opts, this.scope, this.state, this, this.skipKeys);
  
    this.call("exit");
  
    return this.shouldStop;
  }
  
  function skip() {
    this.shouldSkip = true;
  }
  
  function skipKey(key) {
    this.skipKeys[key] = true;
  }
  
  function stop() {
    this.shouldStop = true;
    this.shouldSkip = true;
  }
  
  function setScope() {
    if (this.opts && this.opts.noScope) return;
  
    var target = this.context && this.context.scope;
  
    if (!target) {
      var path = this.parentPath;
      while (path && !target) {
        if (path.opts && path.opts.noScope) return;
  
        target = path.scope;
        path = path.parentPath;
      }
    }
  
    this.scope = this.getScope(target);
    if (this.scope) this.scope.init();
  }
  
  function setContext(context) {
    this.shouldSkip = false;
    this.shouldStop = false;
    this.removed = false;
    this.skipKeys = {};
  
    if (context) {
      this.context = context;
      this.state = context.state;
      this.opts = context.opts;
    }
  
    this.setScope();
  
    return this;
  }
  
  function resync() {
    if (this.removed) return;
  
    this._resyncParent();
    this._resyncList();
    this._resyncKey();
  }
  
  function _resyncParent() {
    if (this.parentPath) {
      this.parent = this.parentPath.node;
    }
  }
  
  function _resyncKey() {
    if (!this.container) return;
  
    if (this.node === this.container[this.key]) return;
  
    if (Array.isArray(this.container)) {
      for (var i = 0; i < this.container.length; i++) {
        if (this.container[i] === this.node) {
          return this.setKey(i);
        }
      }
    } else {
      for (var key in this.container) {
        if (this.container[key] === this.node) {
          return this.setKey(key);
        }
      }
    }
  
    this.key = null;
  }
  
  function _resyncList() {
    if (!this.parent || !this.inList) return;
  
    var newContainer = this.parent[this.listKey];
    if (this.container === newContainer) return;
  
    this.container = newContainer || null;
  }
  
  function _resyncRemoved() {
    if (this.key == null || !this.container || this.container[this.key] !== this.node) {
      this._markRemoved();
    }
  }
  
  function popContext() {
    this.contexts.pop();
    this.setContext(this.contexts[this.contexts.length - 1]);
  }
  
  function pushContext(context) {
    this.contexts.push(context);
    this.setContext(context);
  }
  
  function setup(parentPath, container, listKey, key) {
    this.inList = !!listKey;
    this.listKey = listKey;
    this.parentKey = listKey || key;
    this.container = container;
  
    this.parentPath = parentPath || this.parentPath;
    this.setKey(key);
  }
  
  function setKey(key) {
    this.key = key;
    this.node = this.container[this.key];
    this.type = this.node && this.node.type;
  }
  
  function requeue() {
    var pathToQueue = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this;
  
    if (pathToQueue.removed) return;
  
    var contexts = this.contexts;
  
    for (var _iterator2 = contexts, _isArray2 = Array.isArray(_iterator2), _i2 = 0, _iterator2 = _isArray2 ? _iterator2 : (0, _getIterator3.default)(_iterator2);;) {
      var _ref2;
  
      if (_isArray2) {
        if (_i2 >= _iterator2.length) break;
        _ref2 = _iterator2[_i2++];
      } else {
        _i2 = _iterator2.next();
        if (_i2.done) break;
        _ref2 = _i2.value;
      }
  
      var context = _ref2;
  
      context.maybeQueue(pathToQueue);
    }
  }
  
  function _getQueueContexts() {
    var path = this;
    var contexts = this.contexts;
    while (!contexts.length) {
      path = path.parentPath;
      contexts = path.contexts;
    }
    return contexts;
  }
  