text: "use strict";
  
  exports.__esModule = true;
  exports.AnyTypeAnnotation = AnyTypeAnnotation;
  exports.ArrayTypeAnnotation = ArrayTypeAnnotation;
  exports.BooleanTypeAnnotation = BooleanTypeAnnotation;
  exports.BooleanLiteralTypeAnnotation = BooleanLiteralTypeAnnotation;
  exports.NullLiteralTypeAnnotation = NullLiteralTypeAnnotation;
  exports.DeclareClass = DeclareClass;
  exports.DeclareFunction = DeclareFunction;
  exports.DeclareInterface = DeclareInterface;
  exports.DeclareModule = DeclareModule;
  exports.DeclareModuleExports = DeclareModuleExports;
  exports.DeclareTypeAlias = DeclareTypeAlias;
  exports.DeclareVariable = DeclareVariable;
  exports.ExistentialTypeParam = ExistentialTypeParam;
  exports.FunctionTypeAnnotation = FunctionTypeAnnotation;
  exports.FunctionTypeParam = FunctionTypeParam;
  exports.InterfaceExtends = InterfaceExtends;
  exports._interfaceish = _interfaceish;
  exports.InterfaceDeclaration = InterfaceDeclaration;
  exports.IntersectionTypeAnnotation = IntersectionTypeAnnotation;
  exports.MixedTypeAnnotation = MixedTypeAnnotation;
  exports.NullableTypeAnnotation = NullableTypeAnnotation;
  
  var _types = require("./types");
  
  Object.defineProperty(exports, "NumericLiteralTypeAnnotation", {
    enumerable: true,
    get: function get() {
      return _types.NumericLiteral;
    }
  });
  Object.defineProperty(exports, "StringLiteralTypeAnnotation", {
    enumerable: true,
    get: function get() {
      return _types.StringLiteral;
    }
  });
  exports.NumberTypeAnnotation = NumberTypeAnnotation;
  exports.StringTypeAnnotation = StringTypeAnnotation;
  exports.ThisTypeAnnotation = ThisTypeAnnotation;
  exports.TupleTypeAnnotation = TupleTypeAnnotation;
  exports.TypeofTypeAnnotation = TypeofTypeAnnotation;
  exports.TypeAlias = TypeAlias;
  exports.TypeAnnotation = TypeAnnotation;
  exports.TypeParameter = TypeParameter;
  exports.TypeParameterInstantiation = TypeParameterInstantiation;
  exports.ObjectTypeAnnotation = ObjectTypeAnnotation;
  exports.ObjectTypeCallProperty = ObjectTypeCallProperty;
  exports.ObjectTypeIndexer = ObjectTypeIndexer;
  exports.ObjectTypeProperty = ObjectTypeProperty;
  exports.QualifiedTypeIdentifier = QualifiedTypeIdentifier;
  exports.UnionTypeAnnotation = UnionTypeAnnotation;
  exports.TypeCastExpression = TypeCastExpression;
  exports.VoidTypeAnnotation = VoidTypeAnnotation;
  function AnyTypeAnnotation() {
    this.word("any");
  }
  
  function ArrayTypeAnnotation(node) {
    this.print(node.elementType, node);
    this.token("[");
    this.token("]");
  }
  
  function BooleanTypeAnnotation() {
    this.word("bool");
  }
  
  function BooleanLiteralTypeAnnotation(node) {
    this.word(node.value ? "true" : "false");
  }
  
  function NullLiteralTypeAnnotation() {
    this.word("null");
  }
  
  function DeclareClass(node) {
    this.word("declare");
    this.space();
    this.word("class");
    this.space();
    this._interfaceish(node);
  }
  
  function DeclareFunction(node) {
    this.word("declare");
    this.space();
    this.word("function");
    this.space();
    this.print(node.id, node);
    this.print(node.id.typeAnnotation.typeAnnotation, node);
    this.semicolon();
  }
  
  function DeclareInterface(node) {
    this.word("declare");
    this.space();
    this.InterfaceDeclaration(node);
  }
  
  function DeclareModule(node) {
    this.word("declare");
    this.space();
    this.word("module");
    this.space();
    this.print(node.id, node);
    this.space();
    this.print(node.body, node);
  }
  
  function DeclareModuleExports(node) {
    this.word("declare");
    this.space();
    this.word("module");
    this.token(".");
    this.word("exports");
    this.print(node.typeAnnotation, node);
  }
  
  function DeclareTypeAlias(node) {
    this.word("declare");
    this.space();
    this.TypeAlias(node);
  }
  
  function DeclareVariable(node) {
    this.word("declare");
    this.space();
    this.word("var");
    this.space();
    this.print(node.id, node);
    this.print(node.id.typeAnnotation, node);
    this.semicolon();
  }
  
  function ExistentialTypeParam() {
    this.token("*");
  }
  
  function FunctionTypeAnnotation(node, parent) {
    this.print(node.typeParameters, node);
    this.token("(");
    this.printList(node.params, node);
  
    if (node.rest) {
      if (node.params.length) {
        this.token(",");
        this.space();
      }
      this.token("...");
      this.print(node.rest, node);
    }
  
    this.token(")");
  
    if (parent.type === "ObjectTypeCallProperty" || parent.type === "DeclareFunction") {
      this.token(":");
    } else {
      this.space();
      this.token("=>");
    }
  
    this.space();
    this.print(node.returnType, node);
  }
  
  function FunctionTypeParam(node) {
    this.print(node.name, node);
    if (node.optional) this.token("?");
    this.token(":");
    this.space();
    this.print(node.typeAnnotation, node);
  }
  
  function InterfaceExtends(node) {
    this.print(node.id, node);
    this.print(node.typeParameters, node);
  }
  
  exports.ClassImplements = InterfaceExtends;
  exports.GenericTypeAnnotation = InterfaceExtends;
  function _interfaceish(node) {
    this.print(node.id, node);
    this.print(node.typeParameters, node);
    if (node.extends.length) {
      this.space();
      this.word("extends");
      this.space();
      this.printList(node.extends, node);
    }
    if (node.mixins && node.mixins.length) {
      this.space();
      this.word("mixins");
      this.space();
      this.printList(node.mixins, node);
    }
    this.space();
    this.print(node.body, node);
  }
  
  function InterfaceDeclaration(node) {
    this.word("interface");
    this.space();
    this._interfaceish(node);
  }
  
  function andSeparator() {
    this.space();
    this.token("&");
    this.space();
  }
  
  function IntersectionTypeAnnotation(node) {
    this.printJoin(node.types, node, { separator: andSeparator });
  }
  
  function MixedTypeAnnotation() {
    this.word("mixed");
  }
  
  function NullableTypeAnnotation(node) {
    this.token("?");
    this.print(node.typeAnnotation, node);
  }
  
  function NumberTypeAnnotation() {
    this.word("number");
  }
  
  function StringTypeAnnotation() {
    this.word("string");
  }
  
  function ThisTypeAnnotation() {
    this.word("this");
  }
  
  function TupleTypeAnnotation(node) {
    this.token("[");
    this.printList(node.types, node);
    this.token("]");
  }
  
  function TypeofTypeAnnotation(node) {
    this.word("typeof");
    this.space();
    this.print(node.argument, node);
  }
  
  function TypeAlias(node) {
    this.word("type");
    this.space();
    this.print(node.id, node);
    this.print(node.typeParameters, node);
    this.space();
    this.token("=");
    this.space();
    this.print(node.right, node);
    this.semicolon();
  }
  
  function TypeAnnotation(node) {
    this.token(":");
    this.space();
    if (node.optional) this.token("?");
    this.print(node.typeAnnotation, node);
  }
  
  function TypeParameter(node) {
    if (node.variance === "plus") {
      this.token("+");
    } else if (node.variance === "minus") {
      this.token("-");
    }
  
    this.word(node.name);
  
    if (node.bound) {
      this.print(node.bound, node);
    }
  
    if (node.default) {
      this.space();
      this.token("=");
      this.space();
      this.print(node.default, node);
    }
  }
  
  function TypeParameterInstantiation(node) {
    this.token("<");
    this.printList(node.params, node, {});
    this.token(">");
  }
  
  exports.TypeParameterDeclaration = TypeParameterInstantiation;
  function ObjectTypeAnnotation(node) {
    var _this = this;
  
    this.token("{");
    var props = node.properties.concat(node.callProperties, node.indexers);
  
    if (props.length) {
      this.space();
  
      this.printJoin(props, node, {
        indent: true,
        statement: true,
        iterator: function iterator() {
          if (props.length !== 1) {
            _this.semicolon();
            _this.space();
          }
        }
      });
  
      this.space();
    }
  
    this.token("}");
  }
  
  function ObjectTypeCallProperty(node) {
    if (node.static) {
      this.word("static");
      this.space();
    }
    this.print(node.value, node);
  }
  
  function ObjectTypeIndexer(node) {
    if (node.static) {
      this.word("static");
      this.space();
    }
    this.token("[");
    this.print(node.id, node);
    this.token(":");
    this.space();
    this.print(node.key, node);
    this.token("]");
    this.token(":");
    this.space();
    this.print(node.value, node);
  }
  
  function ObjectTypeProperty(node) {
    if (node.static) {
      this.word("static");
      this.space();
    }
    this.print(node.key, node);
    if (node.optional) this.token("?");
    this.token(":");
    this.space();
    this.print(node.value, node);
  }
  
  function QualifiedTypeIdentifier(node) {
    this.print(node.qualification, node);
    this.token(".");
    this.print(node.id, node);
  }
  
  function orSeparator() {
    this.space();
    this.token("|");
    this.space();
  }
  
  function UnionTypeAnnotation(node) {
    this.printJoin(node.types, node, { separator: orSeparator });
  }
  
  function TypeCastExpression(node) {
    this.token("(");
    this.print(node.expression, node);
    this.print(node.typeAnnotation, node);
    this.token(")");
  }
  
  function VoidTypeAnnotation() {
    this.word("void");
  }